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 neighbors. 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 neighborhood are summed without being weighted, and the sum is divided by the number of pixels in the neighborhood. 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; /// Load an image src = imread("salt.jpg", CV_LOAD_IMAGE_GRAYSCALE); 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
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
Hello your code compiles but the image result is blurred but augmented (ONLY PART of the image appears)
any ideas what can cause this?
Check twice your x and y. You may be looping rows and columns in a wrong way
actually I had forgotten the clone() function.
However, now only the right 1/3 of the image is blurred.
What can cause this?
Thanks
I made it….
I had also forgotten in the imread statment to add CV_LOAD_IMAGE_GRAYSCALE
Thanks!
A quick question: how can I apply more blur in your code…? is it possible?
To apply more blur, increase the size of kernel. In the above example it is 3×3. Make it 4×4 with each element 1/16 and see what happens.
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)
This comment has been removed by the author.
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
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.
How is this taking care of the border?
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?
hy! im tried to run your code in visual studio 2013 but it is not compiling giving me a error