# Image Smoothing with OpenCV

Smoothing using Mode, Mean and Medain Filters

Image smoothing which is known as low pass filtering is a key technology in image enhancement. Noises are presented due to limitations in imaging system, poor sampling and digitization or transmission. So, through smoothing it actually removes high frequency content (e.g: noise, edges) from the image resulting in edges being blurred when this is filter is applied.

The low-pass filters usually employ moving window operator called kernel which affects one pixel of the image at a time, changing its value by some function of a local region (window) of pixels. The operator moves over the image to affect all the pixels in the image. There are various filters used for smoothing an image. Also, the kernel size can be changed by 3,5,7.. So, lets see what would happen to image when using different filters and different kernel sizes.

**Mode Filter**

In this filter, the center pixel value is replaced by the most common value inside the local window around the pixel.

Code

int* arr1 = new int[size];

int index1 = 0;

int getMode = 0;

Mat output = gr.clone();for (int i = adj; i < gr.rows - adj; i++) {

for (int j = adj; j < gr.cols - adj; j++) {

index1 = 0;

for (int g = i - adj; g <= i + adj; g++) {

for (int h = j - adj; h <= j + adj; h++) {

arr1[index1] = (int)gr.at<uchar>(g, h);

index1++;

}

}

getMode = mode(arr1, size);//use to get most common value from a given array

output.at<uchar>(i, j) = (uchar)getMode;

}

}

Output

**Mean Filter**

The idea of mean filtering is simply to replace each pixel value in an image with the mean (‘average’) value of its neighbours, including itself. This has effect of eliminating pixel values which are unrepresentative of their surroundings.

Code

int sum = 0;

int avg = 0;

Mat output = gr.clone();for (int i = adj; i < gr.rows - adj; i++) {

for (int j = adj; j < gr.cols - adj; j++) {

sum = 0;

for (int g = i - adj; g <= i + adj; g++) {

for (int h = j - adj; h <= j + adj; h++) {

sum= sum+(int)gr.at<uchar>(g, h);

}

}

avg = sum / (a * a);

output.at<uchar>(i, j) = (uchar)avg;

}

}

Output

**Median Filter**

In median filter, the center pixel value is replaced by the median value of its neighbours, including itself.

Code

int size = a * a;

int* arr = new int[size];

int index = 0;

int middle = 0;

Mat output = gr.clone();for (int i = adj; i < gr.rows - adj; i++) {

for (int j = adj; j < gr.cols - adj; j++) {

index = 0;

for (int g = i - adj; g <= i + adj; g++) {

for (int h = j - adj; h <= j + adj; h++) {

arr[index] = (int)gr.at<uchar>(g, h);

index++;

}

}

insertionSort(arr, size); //use for sorting the array

middle = size / 2;

output.at<uchar>(i, j) = (uchar)arr[middle];

}

}

Output

Lets discuss the observations of these filters.

- When increasing the kernel size, the blurness effect will be increased.
- Among three filters, median filter preserves the sharpness and location edges.