When smoothing or blurring images (the most popular goal of smoothing is to reduce noise), we can use diverse linear filters, because linear filters are easy to achieve, and are kind of fast, the most used ones are Homogeneous filter, Gaussian filter, Median filter, et al.
When performing a linear filter, we do nothing but output pixel’s value g(i,j) which is determined as a weighted sum of input pixel values f(i+k, j+l):
g(i, j)=SUM[f(i+k, j+l) h(k, l)];
in which, h(k, l)) is called the kernel, which is nothing more than the coefficients of the filter.
Homogeneous filter is the most simple filter, each output pixel is the mean of its kernel neighbors ( all of them contribute with equal weights), and its kernel K looks like:
Gaussian filter is nothing but using different-weight-kernel, in both x and y direction, pixels located in the middle would have bigger weight, and the weights decrease with distance from the neighborhood center, so pixels located on sides have smaller weight, its kernel K is something like (when kernel is 5*5):
Median filter is something that replace each pixel’s value with the median of its neighboring pixels. This method is great when dealing with “salt and pepper noise“.
By using all the three above filters to smooth image, we not only dissolve noise, but also smooth edges, which make edges less sharper, even disappear. To solve this problem, we can use a filter called bilateral filter, which is an advanced version of Gaussian filter, it introduces another weight that represents how two pixels can be close (or similar) to one another in value, and by considering both weights in image, Bilateral filter can keep edges sharp while blurring image.
Let me show you the process by using this image which have sharp edge.
Say we are smoothing this image (we can see noise in the image), and now we are dealing with the pixel at middle of the blue rect.
Left-above picture is a Gaussian kernel, and right-above picture is Bilateral filter kernel, which considered both weight.
We can also see the difference between Gaussian filter and Bilateral filter by these pictures:
Say we have an original image with noise like this
By using Gaussian filter, the image is smoother than before, but we can see the edge is no longer sharp, a slope appeared between white and black pixels.
However, by using Bilateral filter, the image is smoother, the edge is sharp, as well.
It is super easy to make these kind of filters in OpenCV:
//Homogeneous blur: blur(image, dstHomo, Size(kernel_length, kernel_length), Point(-1,-1)); //Gaussian blur: GaussianBlur(image, dstGaus, Size(kernel_length, kernel_length), 0, 0); //Median blur: medianBlur(image, dstMed, kernel_length); //Bilateral blur: bilateralFilter(image, dstBila, kernel_length, kernel_length*2, kernel_length/2);
and for each function, you can find more details in OpenCV Documentation
Glad to use my favorite Van Gogh image :
From left to right: Homogeneous blur, Gaussian blur, Median blur, Bilateral blur.
(click iamge to view full size version :p )
kernel length = 3:
kernel length = 9:
kernel length = 23: