You're reading from OpenCV Computer Vision Application Programming Cookbook Second Edition
Filtering is one of the fundamental tasks in signal and image processing. It is a process aimed at selectively extracting certain aspects of an image that are considered to convey important information in the context of a given application. Filtering removes noise in images, extracts interesting visual features, allows image resampling, and so on. It finds its roots in the general Signals and Systems theory. We will not cover this theory in detail here. However, this chapter will present some of the important concepts related to filtering and will show you how filters can be used in image-processing applications. But first, let's begin with a brief explanation of the concept of frequency domain analysis.
When we look at an image, we observe how the different gray-levels (or colors) are distributed over the image. Images differ from each other because they have a different gray-level distribution. However, there exists another point of view under which an image can be analyzed...
In this first recipe, we will present some very basic low-pass filters. In the introductory section of this chapter, we learned that the objective of such filters is to reduce the amplitude of the image variations. One simple way to achieve this goal is to replace each pixel by the average value of the pixels around it. By doing this, the rapid intensity variations will be smoothed out and thus replaced by a more gradual transition.
The objective of the cv::blur
function is to smooth an image by replacing each pixel with the average pixel value computed over a rectangular neighborhood. This low-pass filter is applied as follows:
cv::blur(image,result, cv::Size(5,5)); // size of the filter
This kind of filter is also called a box filter. Here, we applied it by using a 5x5
filter in order to make the filter's effect more visible. Take a look at the following screenshot:
The first recipe of this chapter introduced the concept of linear filters. Non-linear filters also exist and can be advantageously used in image processing. One such filter is the median filter that we present in this recipe.
Since median filters are particularly useful in order to combat salt-and-pepper noise (or salt-only, in our case), we will use the image we created in the first recipe of Chapter 2, Manipulating Pixels, and that is reproduced here:
The call to the median filtering function is done in a way that is similar to the other filters:
cv::medianBlur(image,result,5); // size of the filter
The resulting image is as follows:
The first recipe of this chapter introduced the idea of linear filtering using kernel matrices. The filters that were used had the effect of blurring an image by removing or attenuating its high-frequency components. In this recipe, we will perform the opposite transformation, that is, amplifying the high-frequency content of an image. As a result, the high-pass filters introduced here will perform edge detection.
The filter that we will use here is called the Sobel filter. It is said to be a directional filter, because it only affects the vertical or the horizontal image frequencies depending on which kernel of the filter is used. OpenCV has a function that applies the Sobel operator on an image. The horizontal filter is called as follows:
cv::Sobel(image, // input sobelX, // output CV_8U, // image type 1, 0, // kernel specification 3, // size of the square kernel...
The Laplacian is another high-pass linear filter that is based on the computation of the image derivatives. As it will be explained, it computes second-order derivatives to measure the curvature of the image function.
The OpenCV function, cv::Laplacian
, computes the Laplacian of an image. It is very similar to the cv::Sobel
function. In fact, it uses the same basic function, cv::getDerivKernels
, in order to obtain its kernel matrix. The only difference is that there are no derivative order parameters since these ones are, by definition, second order derivatives.
For this operator, we will create a simple class that will encapsulate some useful operations related to the Laplacian. The basic methods are as follows:
class LaplacianZC { private: // laplacian cv::Mat laplace; // Aperture size of the laplacian kernel int aperture; public: LaplacianZC() : aperture(3) {} // Set the aperture size of the kernel ...