How To Use Median Filter On Images – C# Guide
Median filter is one of the order-statistic filters for processing image data in spatial domain. This guide shows how to apply it with C#.
Filter by Category
Median filter is one of the order-statistic filters for processing image data in spatial domain. This guide shows how to apply it with C#.
We can use contraharmonic mean filter to process image data in spatial domain. It's most effective against salt and pepper noise.
Harmonic mean filter is of mean filters we can use to process image data in spatial domain. This guide shows how to apply it with C#.
Geometric mean filter is one of mean filters we can use processing images in spatial domain. We use C# programming language to apply it here.
Arithmetic mean filter is one of the simplest mean filters we could use to reduce noise from an image. Learn more about spatial filtering.
Salt and pepper noise or impulse noise is one of the noise models we can use to simulate image data corruption in real life.
Uniform noise is one of the noise models we can use to simulate real life data corruption. This guide shows how to make in on images.
Exponential noise is one of the noise models we can use to simulate corruption of data. This guide show how to use it on images.
Gamma noise is one of the noise models we use to simulate practical data corruption. This guide shows how to apply it on images.
Rayleigh noise is one of the noise models with which we can simulate data corruption. Guide to making noise from PDF and image histogram.
Median filter is one of order specific filters we can use to process image data in spatial domain. Therefore, we will need to use a kernel, which will encompass image pixels to process them further.
Order specific filters output values by ordering them in a specific way and picking one that satisfies the condition of the filter. We also mentioned we will need a kernel or filter, which will allow us to sort and pick output pixel intensity values locally.
We will get our output image by moving our filter across the entire input image, we wish to process, one pixel at a time. It is also worth mentioning that each filter location will produce only one output value. Therefore, we will end up with an image that has slightly smaller dimensions.
To compensate for this loss, we could use zero padding to add pixels with 0 intensity around the image before we filter it.
As its name implies, median filter outputs pixel with median intensity value from local set of pixels. In case you’re not entirely familiar with what median actually is, don’t worry I’ll explain it now. Median is the middle value in a set of sorted values.
Median is not mean. The difference between the two is that we calculate mean from a set of values. While with median we pick out a value that already exists in that set.
This filter is particularly useful for removing salt and pepper noise. We demonstrated harmonic and contraharmonic mean filters to remove this kind of noise before. However, we never got as good result with them as we got it with median filter.
Following formula does what we described above.
The g(s, t) represents pixel intensity value that’s located with s and t coordinates inside the kernel.
public static Bitmap MedianFilter(this Bitmap image)
{
int w = image.Width;
int h = image.Height;
BitmapData image_data = image.LockBits(
new Rectangle(0, 0, w, h),
ImageLockMode.ReadOnly,
PixelFormat.Format24bppRgb);
int bytes = image_data.Stride * image_data.Height;
byte[] buffer = new byte[bytes];
Marshal.Copy(image_data.Scan0, buffer, 0, bytes);
image.UnlockBits(image_data);
int r = 1;
int wres = w - 2 * r;
int hres = h - 2 * r;
Bitmap result_image = new Bitmap(wres, hres);
BitmapData result_data = result_image.LockBits(
new Rectangle(0, 0, wres, hres),
ImageLockMode.WriteOnly,
PixelFormat.Format24bppRgb);
int res_bytes = result_data.Stride * result_data.Height;
byte[] result = new byte[res_bytes];
for (int x = r; x < w - r; x++)
{
for (int y = r; y < h - r; y++)
{
int pixel_location = x * 3 + y * image_data.Stride;
int res_pixel_loc = (x - r) * 3 + (y - r) * result_data.Stride;
double[] median = new double[3];
byte[][] neighborhood = new byte[3][];
for (int c = 0; c < 3; c++)
{
neighborhood[c] = new byte[(int)Math.Pow(2 * r + 1, 2)];
int added = 0;
for (int kx = -r; kx <= r; kx++)
{
for (int ky = -r; ky <= r; ky++)
{
int kernel_pixel = pixel_location + kx * 3 + ky * image_data.Stride;
neighborhood[c][added] = buffer[kernel_pixel + c];
added++;
}
}
}
for (int c = 0; c < 3; c++)
{
result[res_pixel_loc + c] = (byte)(neighborhood[c].median());
}
}
}
Marshal.Copy(result, 0, result_data.Scan0, res_bytes);
result_image.UnlockBits(result_data);
return result_image;
}
Median filter is just one of order statistic filters, but it really works for images that have random distributed noise like impulse noise.
I hope this guide was helpful. You can also download the entire project and try it out on your own images.