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;
}