How To Make Max And Min Filter In Image Processing

Max and min filter is one of the order-statistic filter we can use to process image data in spatial domain. This tutorial shows it with C#.


Andraz Krzisnik
How To Make Max And Min Filter In Image...

We can use max and min filter to process image data in spatial domain. Furthermore, they belong among order-statistic filters along with median filter. As for spatial domain filtering, our filter is basically a small window we place on top of our image.

When we place our filter somewhere on the image, it’s going to encompass pixel intesity values, which we’ll use to store them into a set. After that we’ll pick out the value according to which filter we’ll use.

To form the entire output image, we’ll need to move the filter one pixel at the time. This way, we’ll be able to form the whole image pixel by pixel. However, filtering in spatial domain will produce images with slightly smaller dimensions.

We can compensate for the lost pixels with zero padding and expand our image for the same amount as we’re going to lose.

Max and min filter

I’ve made a post about median filter already, but I’d like to mention it here again. When we use median filter we pick the middle intensity in the set. However when we’re using max and min filter, we pick the highest or the lowest intensity value in the set.

If we use max filter, we’ll bring out the brightest points in the image. And if we’re using min filter, we’ll find the darkest points in the image.

Following formulas do what we described above.

max filter formula
Max filter formula
Min filter formula

The g(s, t) in the formulas represents pixel intensity values encompassed by filter, where s and t are coordinates of each pixel inside.

C# code

public static Bitmap Filter(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++)
                {
                    //if you want to change it to max filter, change .Min() to .Max()
                    result[res_pixel_loc + c] = (byte)(neighborhood[c].Min());
                }
            }
        }

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

        return result_image;
    }

Conclusion

Max and min filters are basically just usable options among order-statistic filters. But that doesn’t mean it makes them really useful in practice.

I hope this tutorial was helpful. You can also download the project with which you can see the demonstration of these filters.

Related Articles

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
Thresholding

How To Make Adaptive Thresholding Algorithm With C#

Adaptive thresholding operation computes thresholds for each pixel locally and therefore segments images more accurately.

Posted on by Andraz Krzisnik