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

Region Splitting And Merging

How To Make Region Splitting And Merging Algorithm – C#

Region splitting and merging is a texture segmentation operation, where we use descriptors such as local mean intensity and standard deviation

Posted on by Andraz Krzisnik
Order-Statistic Filters

How To Make Alpha Trimmed Mean Filter For Images

Alpha trimmed mean filter is a combination of mean filters and order-statistic filters. This guide shows how to use them with C#.

Posted on by Andraz Krzisnik