LitDev.Engines.FIP.ImageKuwaharaFilterGS C# (CSharp) Method

ImageKuwaharaFilterGS() public method

Image to greyscale convertion and kuwahara filtration
public ImageKuwaharaFilterGS ( Bitmap OriginalImage, int FilterSize ) : Bitmap
OriginalImage System.Drawing.Bitmap Original ARGB image
FilterSize int Kuwahara filter size
return System.Drawing.Bitmap
        public Bitmap ImageKuwaharaFilterGS(Bitmap OriginalImage, int FilterSize)
        {
            Bitmap image = OriginalImage;
            Bitmap image2 = new Bitmap(image.Width, image.Height);

            if (FilterSize % 2 == 0)
            {
                throw new Exception("Filter size must be odd.");
            }

            if (FilterSize < 3)
            {
                throw new Exception("Filter size must be positive greater than 2.");
            }

            int size = 2 * FilterSize - 1;

            int range = (int)Math.Floor(Convert.ToDouble(size / 2));

            for (int m = range; m < image.Width - range; m++)
            {
                for (int n = range; n < image.Height - range; n++)
                {

                    int[,] roi = new int[size, size];

                    int tmpj = 0;
                    int tmpi = 0;

                    int newValue = 0;

                    Color CPixel = image.GetPixel(m, n);

                    for (int i = m - range; i < m + range + 1; i++)
                    {
                        for (int j = n - range; j < n + range + 1; j++)
                        {
                            Color pixel = image.GetPixel(i, j);
                            Double p = Convert.ToDouble((pixel.R * 0.3) + (pixel.G * 0.59) + (pixel.B * 0.11));

                            roi[tmpi, tmpj] = (int)p;

                            tmpj++;
                        }

                        tmpi++;
                        tmpj = 0;
                    }

                    int[] roivector1 = new int[FilterSize * FilterSize];
                    int[] roivector2 = new int[FilterSize * FilterSize];
                    int[] roivector3 = new int[FilterSize * FilterSize];
                    int[] roivector4 = new int[FilterSize * FilterSize];

                    int tmp1 = 0;
                    for (int i = 0; i < FilterSize; i++)
                    {
                        for (int j = 0; j < FilterSize; j++)
                        {

                            roivector1[tmp1] = roi[i, j];
                            tmp1++;

                        }
                    }

                    int tmp2 = 0;
                    for (int i = 0; i < FilterSize; i++)
                    {
                        for (int j = (FilterSize - 1); j < roi.GetLength(1); j++)
                        {

                            roivector2[tmp2] = roi[i, j];
                            tmp2++;

                        }
                    }

                    int tmp3 = 0;
                    for (int i = (FilterSize - 1); i < roi.GetLength(0); i++)
                    {
                        for (int j = 0; j < FilterSize; j++)
                        {

                            roivector3[tmp3] = roi[i, j];
                            tmp3++;

                        }
                    }

                    int tmp4 = 0;
                    for (int i = (FilterSize - 1); i < roi.GetLength(0); i++)
                    {
                        for (int j = (FilterSize - 1); j < roi.GetLength(1); j++)
                        {

                            roivector4[tmp4] = roi[i, j];
                            tmp4++;

                        }
                    }

                    Double[] avg = new Double[4] { 0, 0, 0, 0 };

                    Double[] var = new Double[4] { 0, 0, 0, 0 };

                    Double[] std = new Double[4] { 0, 0, 0, 0 };

                    for (int i = 0; i < FilterSize * FilterSize; i++)
                    {

                        avg[0] += Convert.ToDouble(roivector1[i]) / (FilterSize * FilterSize);
                        avg[1] += Convert.ToDouble(roivector2[i]) / (FilterSize * FilterSize);
                        avg[2] += Convert.ToDouble(roivector3[i]) / (FilterSize * FilterSize);
                        avg[3] += Convert.ToDouble(roivector4[i]) / (FilterSize * FilterSize);

                    }

                    for (int i = 0; i < FilterSize * FilterSize; i++)
                    {

                        var[0] += Math.Pow((Convert.ToDouble(roivector1[i]) - avg[0]), 2) / (FilterSize * FilterSize);
                        var[1] += Math.Pow((Convert.ToDouble(roivector2[i]) - avg[1]), 2) / (FilterSize * FilterSize);
                        var[2] += Math.Pow((Convert.ToDouble(roivector3[i]) - avg[2]), 2) / (FilterSize * FilterSize);
                        var[3] += Math.Pow((Convert.ToDouble(roivector4[i]) - avg[3]), 2) / (FilterSize * FilterSize);

                    }

                    int minIndex = System.Array.IndexOf(var, var.Min());

                    newValue = (int)avg[minIndex];

                    if (newValue > 255) newValue = 255;
                    if (newValue < 0) newValue = 0;

                    image2.SetPixel(m, n, Color.FromArgb(255, newValue, newValue, newValue));
                }
            }

            return image2;
        }