# Kuwahara Filter in C#

The Kuwahara filter is probably one of those things that you haven't heard of much, if ever. It's a noise reduction filter/blurring technique for images that preserves edges in a similar fashion to the median filter that I showed a while back. It acts in a similar fashion to the box blur, except we take that box around the center pixel and divide that into 4 smaller boxes (with some overlap since the number of items in the box is usually odd in the x and y axis). These smaller boxes are calculated in the same fashion as the box blur for the average value. While we're doing that, we're also doing another step: Finding the variance for the box. We want to know which box has the least amount of variance. I've seen the variance calculated a number of ways but the easiest is simply finding the minimum and maximum values (for r,g, and b) for a box and subtracting the min from the max. It's easy and fast and I'm lazy so it's good enough for me. Anyway, as always I have a bit of code for you showing you how to do this filter:

` public static Bitmap KuwaharaBlur(Bitmap Image, int Size)`

{

System.Drawing.Bitmap TempBitmap = Image;

System.Drawing.Bitmap NewBitmap = new System.Drawing.Bitmap(TempBitmap.Width, TempBitmap.Height);

System.Drawing.Graphics NewGraphics = System.Drawing.Graphics.FromImage(NewBitmap);

NewGraphics.DrawImage(TempBitmap, new System.Drawing.Rectangle(0, 0, TempBitmap.Width, TempBitmap.Height), new System.Drawing.Rectangle(0, 0, TempBitmap.Width, TempBitmap.Height), System.Drawing.GraphicsUnit.Pixel);

NewGraphics.Dispose();

Random TempRandom = new Random();

int\[\] ApetureMinX = { -(Size / 2), 0, -(Size / 2), 0 };

int\[\] ApetureMaxX = { 0, (Size / 2), 0, (Size / 2) };

int\[\] ApetureMinY = { -(Size / 2), -(Size / 2), 0, 0 };

int\[\] ApetureMaxY = { 0, 0, (Size / 2), (Size / 2) };

for (int x = 0; x < NewBitmap.Width; ++x)

{

for (int y = 0; y < NewBitmap.Height; ++y)

{

int\[\] RValues = { 0, 0, 0, 0 };

int\[\] GValues = { 0, 0, 0, 0 };

int\[\] BValues = { 0, 0, 0, 0 };

int\[\] NumPixels = { 0, 0, 0, 0 };

int\[\] MaxRValue = { 0, 0, 0, 0 };

int\[\] MaxGValue = { 0, 0, 0, 0 };

int\[\] MaxBValue = { 0, 0, 0, 0 };

int\[\] MinRValue = { 255, 255, 255, 255 };

int\[\] MinGValue = { 255, 255, 255, 255 };

int\[\] MinBValue = { 255, 255, 255, 255 };

for (int i = 0; i < 4; ++i)

{

for (int x2 = ApetureMinX\[i\]; x2 < ApetureMaxX\[i\]; ++x2)

{

int TempX = x + x2;

if (TempX >= 0 && TempX < NewBitmap.Width)

{

for (int y2 = ApetureMinY\[i\]; y2 < ApetureMaxY\[i\]; ++y2)

{

int TempY = y + y2;

if (TempY >= 0 && TempY < NewBitmap.Height)

{

Color TempColor = TempBitmap.GetPixel(TempX, TempY);

RValues\[i\] += TempColor.R;

GValues\[i\] += TempColor.G;

BValues\[i\] += TempColor.B;

if (TempColor.R > MaxRValue\[i\])

{

MaxRValue\[i\] = TempColor.R;

}

else if (TempColor.R < MinRValue\[i\])

{

MinRValue\[i\] = TempColor.R;

}

if (TempColor.G > MaxGValue\[i\])

{

MaxGValue\[i\] = TempColor.G;

}

else if (TempColor.G < MinGValue\[i\])

{

MinGValue\[i\] = TempColor.G;

}

if (TempColor.B > MaxBValue\[i\])

{

MaxBValue\[i\] = TempColor.B;

}

else if (TempColor.B < MinBValue\[i\])

{

MinBValue\[i\] = TempColor.B;

}

++NumPixels\[i\];

}

}

}

}

}

int j = 0;

int MinDifference = 10000;

for (int i = 0; i < 4; ++i)

{

int CurrentDifference = (MaxRValue\[i\] - MinRValue\[i\]) + (MaxGValue\[i\] - MinGValue\[i\]) + (MaxBValue\[i\] - MinBValue\[i\]);

if (CurrentDifference < MinDifference && NumPixels\[i\] > 0)

{

j = i;

MinDifference = CurrentDifference;

}

}

Color MeanPixel = Color.FromArgb(RValues\[j\] / NumPixels\[j\],

GValues\[j\] / NumPixels\[j\],

BValues\[j\] / NumPixels\[j\]);

NewBitmap.SetPixel(x, y, MeanPixel);

}

}

return NewBitmap;

}

The code above takes in an image as well as the size that you want the aperture to be. In turn it gives you a smoothed image. Now if you run this, note that it will look very different from any of the other filters I've shown on here. It should look almost like a painting (depending on the original image, it even looks like there are brush strokes). As such, it's going to look a lot more stylized than say a box blur. So keep that in mind when running it. Anyway, hopefully this helps you out in some way. So try it out, leave feedback, and happy coding.

## Sign up for More Posts

I have no idea why you'd put yourself through that but if you'd like more posts from me then how about using my RSS feed? Take a look.