How To Use Harmonic Mean Filter On Images – C# Guide

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#.


Andraz Krzisnik
How To Use Harmonic Mean Filter On Images...

Harmonic mean filter is one of the mean filters we use to process image data in spatial domain. Therefore, like with most of spatial filters, we will need to use a kernel and convolution.

With mean filters in general, we essentially blur the image to deal with noise corruption. Therefore, we should use them for images that have only this kind of degradation. In other words, having any other alterations in the image might complicate the process of restoring it to its original form.

We mentioned, we will need kernel and convolution. In case you’re not familiar with any of it, I’ll try and keep it short and concise, but I recommend you learn more in detail if anything remains unclear.

Kernel is a small matrix, we put on top of our image pixel values. It’s like a window, with which we take those values inside it to compute a new output pixel value. Calculating values together on each kernel position only produces one output pixel value.

Furthermore, to produce the entire output image, we need to use convolution. It’s essentially the process of moving the kernel one pixel at a time and calculating new output pixel values.

However, there is a downside to this process, because the output image will have a little smaller dimensions. But we can’t use zero padding with this filter because it would require to divide by 0, and it’s just not worth ending the world like this.

Harmonic mean filter

We can use harmonic mean filter to remove salt noise. Similar to salt and pepper noise also known as impulse noise, without probability of impulses of lower intensities. However, it fails for the pepper noise.

Let’s take a look at the following formula that computes new pixel values.

Harmonic mean filter formula
Harmonic mean filter formula

The g(s, t) represents each pixel value inside the kernel, s and t being relative coordinates of the kernel itself.

C# code

public static Bitmap HarmonicMean(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[] mean = new double[3];

                 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;
                         for (int c = 0; c < 3; c++)
                         {
                             mean[c] += 1d / buffer[kernel_pixel + c];
                         }
                     }
                 }

                 for (int c = 0; c < 3; c++)
                 {
                     result[res_pixel_loc + c] = (byte)(Math.Pow(2 * r + 1, 2) / mean[c]);
                 }
             }
         }

         Marshal.Copy(result, 0, result_data.Scan0, res_bytes);
         result_image.UnlockBits(result_data);
         return result_image;
     }

Conclusion

Harmonic mean filter is useful for removing impulses on a higher end of intensity range. I hope this guide was helpful and I hope you’ll read some of my other posts as well.

You can download the project and try it out on your own images.

Related Articles

Frequency Domain Filtering

How To Use Bandpass Filters – C# Guide

Bandpass filters are the counterpart of bandreject filters. Therefore, they attenuate every frequency outside the ring. In case you’re just tuning in, let me clarify what I...

Posted on by Andraz Krzisnik
C# Image Processing

How To Use Fourier Transform On Images – C# Guide

Fourier transform is an equation that turns normal pixel values into complex numbers. But to know what these complex numbers mean, we should give a little more context to them by...

Posted on by Andraz Krzisnik