Introduction
In the previous tutorial we saw how to render text over an image. Now we will see how to blur images using four ready OpenCV functions. Blurring is the process of applying a filter to the image. By blurring an image we can remove any noise like small points and so on, which is applied to the image while taking it. Thus the image will look smoother. It is quite an useful operation.
We will apply Homogenous blur, Gaussian blur, Median blur and Bilateral Filter. The good thing is that we have the functions available for use in OpenCV so there is no need to write all the logic by ourselves. And believe me, that logic is not quite simple.
I will provide the code first and then I will go through each type of blurring and give more details about it. I will skip all the theory behind the blurring and will provide links for more information. There are a lot of good books and articles on this topic. One such book I found very useful is Computer Vision: Algorithms and Applications.
The source code
Following is the source code which calls all the four different blurring OpenCV functions and output their result in four different windows. Again, we have reading an image from a file so I will not repeat myself with explanations on how this is done.
using namespace cv; void blurImage() { // Path to the input image std::string l_pathToInputImage{ "../Resources/city.jpg" }; // Create an object to hold the image data of the first image Mat l_image; // Read the image date from a file with no change to color scheme l_image = imread(l_pathToInputImage, IMREAD_UNCHANGED); // Check if we have read the first image data correctly if (!l_image.data) { std::cout << "No image data \n"; return; } // Create a destination image matrix Mat l_homogeneousBlurImage = l_image.clone(); // Set the kernel size Size l_bluringKernelSize{ 13,13 }; // Apply homogeneous blur blur(l_image, l_homogeneousBlurImage, l_bluringKernelSize, Point(-1,-1), BORDER_DEFAULT); Mat l_gaussianBlurImage = l_image.clone(); l_bluringKernelSize.width = 25; l_bluringKernelSize.height = 25; // Apply Gaussian blur GaussianBlur( l_image, l_gaussianBlurImage, l_bluringKernelSize, 0, 0, BORDER_DEFAULT ); Mat l_medianBlurImage = l_image.clone(); int l_medianKernelSize = 13; // Apply median blur medianBlur(l_image, l_medianBlurImage, l_medianKernelSize ); Mat l_bilateralFilterBlurImage = l_image.clone(); int l_bilateralFilterKernelSize = 15; // Apply Bilateral Filter blur bilateralFilter(l_image, l_bilateralFilterBlurImage, l_bilateralFilterKernelSize, l_bilateralFilterKernelSize*2, l_bilateralFilterKernelSize/2, BORDER_DEFAULT); // Display the input image namedWindow("Input", WINDOW_NORMAL); cv::imshow("Input", l_image); // Display the Homogeneous Blur image namedWindow("Homogeneous Blur", WINDOW_NORMAL); cv::imshow("Homogeneous Blur", l_homogeneousBlurImage); // Display the Gaussion Blur image namedWindow("Gaussian Blur", WINDOW_NORMAL); cv::imshow("Gaussian Blur", l_gaussianBlurImage); // Display the Median Blur image namedWindow("Median Blur", WINDOW_NORMAL); cv::imshow("Median Blur", l_medianBlurImage); // Display the Bilateral Filter Blur image namedWindow("Bilateral Filter Blur", WINDOW_NORMAL); cv::imshow("Bilateral Filter Blur", l_bilateralFilterBlurImage); }
Homogeneous blur
This type of blur uses normalized box filter. Here is more information about it. This is the part in the source code which does it:
// Create a destination image matrix Mat l_homogeneousBlurImage = l_image.clone(); // Set the kernel size Size l_bluringKernelSize{ 13,13 }; // Apply homogeneous blur blur(l_image, l_homogeneousBlurImage, l_bluringKernelSize, Point(-1,-1), BORDER_DEFAULT);
Firstly we create a new Mat object by cloning the one which we used to read the image data to. Then we set the size of the kernel – columns and rows – which we will use to apply. In our case it will be one matrix of 13 rows and 13 columns. The number should be odd and greater than 1. This will be applied to each pixel in our image.
Next we call the blur() function. It is similar to another OpenCV function – boxFilter(). Firstly we provide the source image matrix – the one we read the image data to. Then we provide the destination matrix – where we will keep the result of the calculations. The third argument is the blurring kernel size, which is of Size type. The next Point object is the anchor of the kernel. It has a default value. Point(-1, -1) means that it will be at the center of the kernel. You can play and set it to another value. It should be inside the matrix though. Lastly we have the border type, which is the mode used to extrapolate pixels outside of the image. It has also a default value. More information about the possible values here.
And that’s it, by one function call we have the whole image blurred. You can go ahead and play with the kernel size and the anchor point to see the change results. Here is my result.

Gaussian blur
Next, we have the Gaussian blur filter. Again, here is more information about the concept. And here is the source code part.
Mat l_gaussianBlurImage = l_image.clone(); l_bluringKernelSize.width = 25; l_bluringKernelSize.height = 25; // Apply Gaussian blur GaussianBlur( l_image, l_gaussianBlurImage, l_bluringKernelSize, 0, 0, BORDER_DEFAULT );
Again, we create another Mat object and clone the image matrix to it. Then we set the size of the kernel. Here I made it 25×25 so it will have more blur. Keep the size an odd number.
Now I call the GaussianBlur() function. The first argument is the input image matrix followed by the output image matrix. Next is the kernel size. The fourth and fifth arguments are the sigmaX and sigmaY standard deviations. I have left them as zeros. You can go ahead, play with them and see the results. Lastly, we have the border type as in the previous example.
Again, I strongly recommend you to play with the kernel sizes and sigma deviations and see how the result changes. Currently the result on my side looks like this.

Median blur
This blurs an image using a median filter. Here is more information about it. There is already an implemented function for it in OpenCV so we will be using it directly. Here is the piece of code to demonstrate how to use it.
Mat l_medianBlurImage = l_image.clone(); int l_medianKernelSize = 13; // Apply median blur medianBlur(l_image, l_medianBlurImage, l_medianKernelSize );
As usual we make a copy of the source image matrix into a new matrix. Then we set the kernel size. Notice that here it is only one integer value. We don’t have a width or a height. You must set it to an odd number and greater than 1. Try with different values to see the result.
The function to apply the median filter is named medianBlur(). Firstly we provide the source image matrix, that we have read from the image file. Then we provide the image matrix object we cloned from the source. Lastly we provide the kernel size.
Following is the result on my size. Try with different values of the kernel size and see the results.

Bilateral Filter Blur
Lastly we will see the bilateral filter. The filters we saw so far smooth the image but they also smooth any edges. This filter has the ability to preserve the edges. Here is more information about it. Following is the demo code piece.
Mat l_bilateralFilterBlurImage = l_image.clone(); int l_bilateralFilterKernelSize = 15; // Apply Bilateral Filter blur bilateralFilter(l_image, l_bilateralFilterBlurImage, l_bilateralFilterKernelSize, l_bilateralFilterKernelSize*2, l_bilateralFilterKernelSize/2, BORDER_DEFAULT);
Again we clone the source image matrix into a new matrix object. Then we set the filter kernel size. It should be an odd number.
The function to apply a bilateral filter is named bilateralFilter(). The first argument is the input image matrix and the second argument is the destination image matrix, which we just cloned. Next is the filter kernel size. The next two arguments are the sigmaColor and sigmaSpace. I keep the first one bigger and the second one smaller. Lastly we set the border type, which also has a default value.
Here it is worth playing with the kernel size and the sigma values. Then you can check the results and find what suites you more. Following is my result.

Conclusion
In this tutorial we saw how we can smooth images using the blurring functionality of OpenCV. By blurring an image we can remove noises, which have appeared during the taking of the image. We saw four filters which can do the job. OpenCV provides ready functions to apply these filters. This is really helpful because writing the logic of these filters is not a simple job.
The source code is attached here as an archive and also available in GitHub.
Next we will see another morphological operaion on images – dilation.
OpenCV Blurring
Passionate developer, loving husband and caring father. As an introvert programming is my life. I work as a senior software engineer in a big international company. My hobbies include playing computer games (mostly World of Warcraft), watching TV series and hiking.