3X3 Median Filtering in c# but not working?

末鹿安然 提交于 2021-01-29 04:56:52

问题


Really I'm trying to apply 3X3 Median Filtering by C# and depending on my understanding the concepts of Median Filtering I wrote the following code but when I'm running it the Form hangs. I think have some problem in the last nested for loop but i don't know where is the error or the wrong in applying the Median concepts!

public static Bitmap MedianFiltering(Bitmap bm)
    {
        List<int> termsList = new List<int>();
        Bitmap res, temp;
        Color c;
        int counter = 0;

        //Convert to Grayscale 
        for (int i = 0; i < bm.Width; i++)
        {
            for (int j = 0; j < bm.Height; j++)
            {
                c = bm.GetPixel(i, j);
                byte gray = (byte)(.333 * c.R + .333 * c.G + .333 * c.B);
                bm.SetPixel(i, j, Color.FromArgb(gray, gray, gray));
            }
        }

        temp = bm;

       //applying Median Filtering 
        for (int i = 0; i <= temp.Width - 3; i++)
            for (int j = 0; j <= temp.Height - 3; j++)
            {
                for (int x = i; x <= i + 2; x++)
                    for (int y = j; y <= j + 2; y++)
                    {

                        c = temp.GetPixel(x, y);
                        termsList.Add(c.R);
                        counter++;
                    }
                int[] terms = termsList.ToArray();
                Array.Sort<int>(terms);
                Array.Reverse(terms);
                int color = terms[4];
                temp.SetPixel(i + 1, j + 1, Color.FromArgb(color, color, color));
                counter = 0;
            }
        res = temp;

        return res;
    }

Thanks.


回答1:


You are not clearing the termsList after each pixel processing. This is causing the list to keep growing. Sorting and reversing the list will keep taking longer and longer times. This will also cause incorrect results since you only want to get the median of the 9 pixels related to the current pixel.

Simply clear the list like this:

...
int[] terms = termsList.ToArray();
termsList.Clear();
...

UPDATE:

I did more optimization for the code:

public static void MedianFiltering(Bitmap bm)
{
    List<byte> termsList = new List<byte>();

    byte[,] image = new byte[bm.Width,bm.Height];

    //Convert to Grayscale 
    for (int i = 0; i < bm.Width; i++)
    {
        for (int j = 0; j < bm.Height; j++)
        {
            var c = bm.GetPixel(i, j);
            byte gray = (byte)(.333 * c.R + .333 * c.G + .333 * c.B);
            image[i, j] = gray;
        }
    }

    //applying Median Filtering 
    for (int i = 0; i <= bm.Width - 3; i++)
        for (int j = 0; j <= bm.Height - 3; j++)
        {
            for (int x = i; x <= i + 2; x++)
                for (int y = j; y <= j + 2; y++)
                {
                    termsList.Add(image[x, y]);
                }
            byte[] terms = termsList.ToArray();
            termsList.Clear();
            Array.Sort<byte>(terms);
            Array.Reverse(terms);
            byte color = terms[4];
            bm.SetPixel(i + 1, j + 1, Color.FromArgb(color, color, color));
        }
}

Please note that in your original method, you returned a Bitmap. I removed this.

Please note that temp = bm; does not create a copy of the Bitmap. It is just pointing the temp variable to the same object (that is pointed by bm). So in your original method, you returned the exact object that is passed in the method parameter. To use the new method pass the Bitmap and then the bitmap it self will be modified (this is also true for your method).

This enhanced performance 4 times on my machine.

What I did is mainly read the bitmap data into a byte array instead of using the Bitmap it self to read/write data multiple times.

If you need to further enhance the performance, take a look at this question.



来源:https://stackoverflow.com/questions/33703387/3x3-median-filtering-in-c-sharp-but-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!