1
Making your own linear filters! {#tutorial_filter_2d}
2
===============================
7
In this tutorial you will learn how to:
9
- Use the OpenCV function @ref cv::filter2D to create your own linear filters.
14
@note The explanation below belongs to the book **Learning OpenCV** by Bradski and Kaehler.
18
In a very general sense, convolution is an operation between every part of an image and an operator
23
A kernel is essentially a fixed size array of numerical coefficeints along with an *anchor point* in
24
that array, which is tipically located at the center.
26
![](images/filter_2d_tutorial_kernel_theory.png)
28
### How does convolution with a kernel work?
30
Assume you want to know the resulting value of a particular location in the image. The value of the
31
convolution is calculated in the following way:
33
-# Place the kernel anchor on top of a determined pixel, with the rest of the kernel overlaying the
34
corresponding local pixels in the image.
35
-# Multiply the kernel coefficients by the corresponding image pixel values and sum the result.
36
-# Place the result to the location of the *anchor* in the input image.
37
-# Repeat the process for all pixels by scanning the kernel over the entire image.
39
Expressing the procedure above in the form of an equation we would have:
41
\f[H(x,y) = \sum_{i=0}^{M_{i} - 1} \sum_{j=0}^{M_{j}-1} I(x+i - a_{i}, y + j - a_{j})K(i,j)\f]
43
Fortunately, OpenCV provides you with the function @ref cv::filter2D so you do not have to code all
49
-# **What does this program do?**
51
- Performs a *normalized box filter*. For instance, for a kernel of size \f$size = 3\f$, the
54
\f[K = \dfrac{1}{3 \cdot 3} \begin{bmatrix}
60
The program will perform the filter operation with kernels of sizes 3, 5, 7, 9 and 11.
62
- The filter output (with each kernel) will be shown during 500 milliseconds
64
-# The tutorial code's is shown lines below. You can also download it from
65
[here](https://github.com/Itseez/opencv/tree/master/samples/cpp/tutorial_code/ImgTrans/filter2D_demo.cpp)
67
#include "opencv2/imgproc.hpp"
68
#include "opencv2/highgui.hpp"
75
int main ( int argc, char** argv )
85
char* window_name = "filter2D Demo";
90
src = imread( argv[1] );
96
namedWindow( window_name, WINDOW_AUTOSIZE );
98
/// Initialize arguments for the filter
99
anchor = Point( -1, -1 );
103
/// Loop - Will filter the image with different kernel sizes each 0.5 seconds
108
/// Press 'ESC' to exit the program
112
/// Update kernel size for a normalized box filter
113
kernel_size = 3 + 2*( ind%5 );
114
kernel = Mat::ones( kernel_size, kernel_size, CV_32F )/ (float)(kernel_size*kernel_size);
117
filter2D(src, dst, ddepth , kernel, anchor, delta, BORDER_DEFAULT );
118
imshow( window_name, dst );
130
src = imread( argv[1] );
135
-# Create a window to display the result
137
namedWindow( window_name, WINDOW_AUTOSIZE );
139
-# Initialize the arguments for the linear filter
141
anchor = Point( -1, -1 );
145
-# Perform an infinite loop updating the kernel size and applying our linear filter to the input
146
image. Let's analyze that more in detail:
147
-# First we define the kernel our filter is going to use. Here it is:
149
kernel_size = 3 + 2*( ind%5 );
150
kernel = Mat::ones( kernel_size, kernel_size, CV_32F )/ (float)(kernel_size*kernel_size);
152
The first line is to update the *kernel_size* to odd values in the range: \f$[3,11]\f$. The second
153
line actually builds the kernel by setting its value to a matrix filled with \f$1's\f$ and
154
normalizing it by dividing it between the number of elements.
156
-# After setting the kernel, we can generate the filter by using the function @ref cv::filter2D :
158
filter2D(src, dst, ddepth , kernel, anchor, delta, BORDER_DEFAULT );
160
The arguments denote:
162
-# *src*: Source image
163
-# *dst*: Destination image
164
-# *ddepth*: The depth of *dst*. A negative value (such as \f$-1\f$) indicates that the depth is
165
the same as the source.
166
-# *kernel*: The kernel to be scanned through the image
167
-# *anchor*: The position of the anchor relative to its kernel. The location *Point(-1, -1)*
168
indicates the center by default.
169
-# *delta*: A value to be added to each pixel during the convolution. By default it is \f$0\f$
170
-# *BORDER_DEFAULT*: We let this value by default (more details in the following tutorial)
172
-# Our program will effectuate a *while* loop, each 500 ms the kernel size of our filter will be
173
updated in the range indicated.
178
-# After compiling the code above, you can execute it giving as argument the path of an image. The
179
result should be a window that shows an image blurred by a normalized filter. Each 0.5 seconds
180
the kernel size should change, as can be seen in the series of snapshots below:
182
![](images/filter_2d_tutorial_result.jpg)