## Wednesday, January 30, 2013

### Low pass filters (blurring) in Image Processing using C++

Theory

Low pass filtering also called "blurring" & "smoothing" is very basic filtering operations in image processing. The simplest low-pass filter just calculates the average of a pixel and all of its eight immediate neighbours. The result replaces the original value of the pixel. The process is repeated for every pixel in the image.The example of Kernel used for simple low pass filters is
In this kernel pixel values from the neighbourhood are summed without being weighted, and the sum is divided by the number of pixels in the neighbourhood. Here is the C++ code for low pass filtering operation using above Kernel (Averaging operation) . Here I implement the convolution operation.

Source Code : C++

#include<iostream>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

int main()
{

Mat src, dst;
float sum;

if( !src.data )
{ return -1; }

// define the kernel
float Kernel[3][3] = {
{1/9.0, 1/9.0, 1/9.0},
{1/9.0, 1/9.0, 1/9.0},
{1/9.0, 1/9.0, 1/9.0}
};
dst = src.clone();
for(int y = 0; y < src.rows; y++)
for(int x = 0; x < src.cols; x++)
dst.at<uchar>(y,x) = 0.0;
//convolution operation
for(int y = 1; y < src.rows - 1; y++){
for(int x = 1; x < src.cols - 1; x++){
sum = 0.0;
for(int k = -1; k <= 1;k++){
for(int j = -1; j <=1; j++){
sum = sum + Kernel[j+1][k+1]*src.at<uchar>(y - j, x - k);
}
}
dst.at<uchar>(y,x) = sum;
}
}

namedWindow("final");
imshow("final", dst);

namedWindow("initial");
imshow("initial", src);

waitKey();

return 0;
}


Output

1. Hi, probably our entry may be off topic but anyways, I have been surfing around your blog and it looks very professional.
Image Processing India

2. Hello your code compiles but the image result is blurred but augmented (ONLY PART of the image appears)
any ideas what can cause this?

1. Check twice your x and y. You may be looping rows and columns in a wrong way

3. actually I had forgotten the clone() function.
However, now only the right 1/3 of the image is blurred.

What can cause this?
Thanks

Thanks!

A quick question: how can I apply more blur in your code...? is it possible?

1. To apply more blur, increase the size of kernel. In the above example it is 3x3. Make it 4x4 with each element 1/16 and see what happens.

2. All of my data is stored in (pic = new char [R*(3*C)];)
and my loop of rows and colm is working on this array (pic[(r*((3*C)))+ (3*c)]+=;
pic[(r*((3*C)))+ (3*c) + 1]+=;
pic[(r*((3*C)))+ (3*c) + 2]+=;
)
can you tell me how to blur it?
Thanks.

5. Hi I am trying to write this code but can you please let me know what will be the location of pixel at src.at(y - j, x - k)

6. This comment has been removed by the author.

7. i m running this code in visual studio 2015 using opencv 3.1 its compiling but i not getting images as output . Can you please help me with it. thanks

8. How is this taking care of the border?

9. Hello,
Thank you for this code.

I'am trying to apply it on Bitmap image, and when I come to the line:
sum = sum + Kernel[j+1][k+1]*src.at(y - j, x - k);
I modify it to:
Color pixelValue = sourceBitmap->GetPixel(y - j, x - k);
sum = sum + kernel[j + 1,k + 1] * pixelValue;
but there is an error in multiply double by color,
how can I fix it?