SoFunction
Updated on 2024-11-20

Code implementation of openCV median and mean filtering

Before we start our blog today, we need to understand what filtering is:

First we look at the concept of image filtering. Image filtering, i.e., suppressing the noise of the target image under the condition of retaining the detailed features of the image as much as possible, is an indispensable operation in image preprocessing, and the effect of its processing will directly affect the effectiveness and reliability of the subsequent image processing and analysis.

Below is the original image on the left and the noise map on the right:

The elimination of the noise component of an image is called the smoothing or filtering operation of the image. It is common for most of the energy of a signal or image to be concentrated in the low and mid-frequency bands of the amplitude spectrum, while in the higher frequency bands the information of interest is often drowned out by noise. Therefore a filter that reduces the amplitude of the high frequency components is able to attenuate the effect of noise.
The purpose of image filtering is twofold: one is to extract the characteristics of the object as a feature pattern of image recognition; the other is to adapt to the requirements of image processing, to eliminate the image digitized when mixed with the noise.
And there are two requirements for the filtering process: one can not damage the image contours and edges and other important information; the second is to make the image clear visual effect.

Smoothing filtering is a spatial domain filtering technique for low frequency enhancement. It has two types of purposes: one is blurring; the other is noise removal.

Smoothing filtering in the spatial domain is generally carried out using the simple average method, which is to find the average brightness value of the neighboring image element points. The size of the neighborhood is directly related to the effect of smoothing, the larger the neighborhood the better the effect of smoothing, but the neighborhood is too large, the smoothing will make the loss of edge information the larger, so that the output image becomes fuzzy, so you need to reasonably select the size of the neighborhood.

A graphic analogy for filters is that we can think of a filter as a window containing weighting coefficients, and when smoothing an image with this filter, we place this window on top of the image and look through it to see the image we get.

Let's take an example of how filtering is used in our lives: the skin resurfacing feature of Face Beauty. If you compare the puddles on our face to noise, then the filtering algorithm is there to take out that noise and make our skin look smooth for selfies.

This blog post will introduce two algorithms: median filtering and mean filtering.

I. Mean value filtering

In a square area (usually 3*3) in the picture, the pixels in the center point are the average of the pixel values of all the points. Mean value filtering is to perform the above operation for the whole picture.

We can understand this by looking at the matrix below

Defects: Mean value filtering itself has inherent defects, that is, it does not protect the image details well and destroys the detailed part of the image while image denoising, thus making the image blurred and not removing the noise points well. In particular, pepper noise

Implementation Code:

#include "opencv2/"
#include "opencv2/"
#include<ctime>
using namespace cv;
using namespace std;

//Mean Filter
void AverFiltering(const Mat &src,Mat &dst) {
	if (!) return;
	//at accesses pixel points
	for (int i = 1; i<; ++i)
		for (int j = 1; j < ; ++j) {
			if ((i - 1 >= 0) && (j - 1) >= 0 && (i + 1)< && (j + 1)<) {//Edges are not processed
				<Vec3b>(i, j)[0] = (<Vec3b>(i, j)[0] + <Vec3b>(i - 1, j - 1)[0] + <Vec3b>(i - 1, j)[0] + <Vec3b>(i, j - 1)[0] +
					<Vec3b>(i - 1, j + 1)[0] + <Vec3b>(i + 1, j - 1)[0] + <Vec3b>(i + 1, j + 1)[0] + <Vec3b>(i, j + 1)[0] +
					<Vec3b>(i + 1, j)[0]) / 9;
				<Vec3b>(i, j)[1] = (<Vec3b>(i, j)[1] + <Vec3b>(i - 1, j - 1)[1] + <Vec3b>(i - 1, j)[1] + <Vec3b>(i, j - 1)[1] +
					<Vec3b>(i - 1, j + 1)[1] + <Vec3b>(i + 1, j - 1)[1] + <Vec3b>(i + 1, j + 1)[1] + <Vec3b>(i, j + 1)[1] +
					<Vec3b>(i + 1, j)[1]) / 9;
				<Vec3b>(i, j)[2] = (<Vec3b>(i, j)[2] + <Vec3b>(i - 1, j - 1)[2] + <Vec3b>(i - 1, j)[2] + <Vec3b>(i, j - 1)[2] +
					<Vec3b>(i - 1, j + 1)[2] + <Vec3b>(i + 1, j - 1)[2] + <Vec3b>(i + 1, j + 1)[2] + <Vec3b>(i, j + 1)[2] +
					<Vec3b>(i + 1, j)[2]) / 9;
			}
			else {//Edge assignment
				<Vec3b>(i, j)[0] = <Vec3b>(i, j)[0];
				<Vec3b>(i, j)[1] = <Vec3b>(i, j)[1];
				<Vec3b>(i, j)[2] = <Vec3b>(i, j)[2];
			}
		}
}
//w/images of peppers salted
void salt(Mat &image, int num) {
	if (!) return;//Preventing incoming empty charts
	int i, j;
	srand(time(NULL));
	for (int x = 0; x < num; ++x) {
		i = rand() % ;
		j = rand() % ;
		<Vec3b>(i, j)[0] = 255;
		<Vec3b>(i, j)[1] = 255;
		<Vec3b>(i, j)[2] = 255;
	}
}
void main() {
	Mat image = imread("Luffy.jpg.");

	Mat Salt_Image;
	(Salt_Image);
	salt(Salt_Image, 3000);

	Mat image1((), ());
	Mat image2;
	AverFiltering(Salt_Image, image1);
	blur(Salt_Image, image2, Size(3, 3));The mean filter function that comes with the //openCV library.
	imshow("Original image.", image);
	imshow("Customized mean filtering", image1);
	imshow("openCV comes with mean filtering.", image2);
	waitKey();
}

Rendering:

You can see that the image is blurred and the noise is not removed very effectively, the algorithm just blurs the image.

II. Median Filtering

First, let's review the median. The number 6 is the median of a series of numbers }1,4,6,8,9}. This can be applied to image processing. We still have a 3*3 matrix with 9 pixels in the image, we sort the 9 pixels and assign the center of the matrix to the median of the 9 pixels.

Code:

// Find the median of nine numbers
uchar Median(uchar n1, uchar n2, uchar n3, uchar n4, uchar n5,
	uchar n6, uchar n7, uchar n8, uchar n9) {
	uchar arr[9];
	arr[0] = n1;
	arr[1] = n2;
	arr[2] = n3;
	arr[3] = n4;
	arr[4] = n5;
	arr[5] = n6;
	arr[6] = n7;
	arr[7] = n8;
	arr[8] = n9;
	for (int gap = 9 / 2; gap > 0; gap /= 2)//Hill Sort
		for (int i = gap; i < 9; ++i)
			for (int j = i - gap; j >= 0 && arr[j] > arr[j + gap]; j -= gap)
				swap(arr[j], arr[j + gap]);
	return arr[4];//Return the median value
}

//w/images of peppers salted
void salt(Mat &image, int num) {
	if (!) return;//Preventing incoming empty charts
	int i, j;
	srand(time(NULL));
	for (int x = 0; x < num; ++x) {
		i = rand() % ;
		j = rand() % ;
		<Vec3b>(i, j)[0] = 255;
		<Vec3b>(i, j)[1] = 255;
		<Vec3b>(i, j)[2] = 255;
	}
}

//Median Filter Function
void MedianFlitering(const Mat &src, Mat &dst) {
	if (!)return;
	Mat _dst((), ());
	for(int i=0;i<;++i)
		for (int j=0; j < ; ++j) {
			if ((i - 1) > 0 && (i + 1) <  && (j - 1) > 0 && (j + 1) < ) {
				_dst.at<Vec3b>(i, j)[0] = Median(<Vec3b>(i, j)[0], <Vec3b>(i + 1, j + 1)[0],
					<Vec3b>(i + 1, j)[0], <Vec3b>(i, j + 1)[0], <Vec3b>(i + 1, j - 1)[0],
					<Vec3b>(i - 1, j + 1)[0], <Vec3b>(i - 1, j)[0], <Vec3b>(i, j - 1)[0],
					<Vec3b>(i - 1, j - 1)[0]);
				_dst.at<Vec3b>(i, j)[1] = Median(<Vec3b>(i, j)[1], <Vec3b>(i + 1, j + 1)[1],
					<Vec3b>(i + 1, j)[1], <Vec3b>(i, j + 1)[1], <Vec3b>(i + 1, j - 1)[1],
					<Vec3b>(i - 1, j + 1)[1], <Vec3b>(i - 1, j)[1], <Vec3b>(i, j - 1)[1],
					<Vec3b>(i - 1, j - 1)[1]);
				_dst.at<Vec3b>(i, j)[2] = Median(<Vec3b>(i, j)[2], <Vec3b>(i + 1, j + 1)[2],
					<Vec3b>(i + 1, j)[2], <Vec3b>(i, j + 1)[2], <Vec3b>(i + 1, j - 1)[2],
					<Vec3b>(i - 1, j + 1)[2], <Vec3b>(i - 1, j)[2], <Vec3b>(i, j - 1)[2],
					<Vec3b>(i - 1, j - 1)[2]);
			}
			else
				_dst.at<Vec3b>(i, j) = <Vec3b>(i, j);
		}
	_dst.copyTo(dst);//copy
}


void main() {
	Mat image = imread("Luffy.jpg.");

	Mat Salt_Image;
	(Salt_Image);
	salt(Salt_Image, 3000);

	Mat image3, image4;
	MedianFlitering(Salt_Image, image3);
	medianBlur(Salt_Image, image4, 3);
	imshow("Customized median filtering after processing", image3);
	imshow("openCV comes with median filtering.", image4);
	waitKey();
}

Rendering:

As you can see, the pretzel noise is nicely smoothed out and not blurred too much like the mean.

to this article on openCV median filtering and mean filtering code implementation of the article is introduced to this, more related openCV median filtering and mean filtering content, please search for my previous articles or continue to browse the following related articles I hope that you will support me more in the future!