# Kuwahara Filter in C#

The filter you've probably never heard of before.
Feb 11 2009

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.