Implement a Mean Filter with OpenCV

Published by: 0

In the last blog post I have stated how to implement a median filter with openCV and a bit to the discrete convolution theory. The approach I have used there was a bit straightforward than the convolution. Here in the mean filter the implementation will follow the convolution theory with applying a 3×3 kernel to the source image.

The basic idea of the mean filter is replacing a pixel value in the image with the average value of its neighbouring pixels. Starting from the 1 to N-1 on each direction, a 3×3 area will be selected and then the pixel value average will be applied to the middle pixel.

The kernel for a 3×3 mean filter will look like this.

4

When each corresponding source pixel is multiplied and summed together(Convolution theory), the average value will be returned. Then it’ll be written back to the considering (i,j) pixel of the source image (or to a new image Mat)

The C++ implementation goes like this.

[cpp]#include <opencv\cv.h>
#include <iostream>
#include "opencv\highgui.h"

using namespace cv;
using namespace std;

int main() {
Mat noisyimg = imread("noisy_Farm.jpg",CV_LOAD_IMAGE_GRAYSCALE);
float kernal[3][3];

for (int a = 0; a < 3; a++) {
for (int b = 0; b < 3; b++) {
kernal[a][b] = (float)1 / 9;
}
}
cout << kernal[1][2];
namedWindow("orig",WINDOW_AUTOSIZE);
imshow("orig", noisyimg);
Mat filtered(noisyimg.rows, noisyimg.cols,CV_8UC1);
for (int i = 1; i < noisyimg.rows – 1; i++) {
for (int j = 1; j< noisyimg.cols – 1; j++) {

int tot = 0;
for (int a = – 1; a <= 1; a++) {
for (int b = – 1; b <= 1; b++) {
/**Getting the sum of multiplied values*/
tot += kernal[a + 1][b + 1] * noisyimg.at<uchar>(i + a, j + b);
}
}
/**Writing the average value back to the source image*/
filtered.at<uchar>(i, j) = cvRound((float)tot);
}
}

imshow("mod", filtered);
waitKey (0);

}[/cpp]

 

Results

5 6

Note that, more the larger the kernel size, more the blurring effect will take place.