In this tutorial you will learn how to:
Note
The explanation below belongs to the book Learning OpenCV by Bradski and Kaehler.
In a very general sense, convolution is an operation between every part of an image and an operator (kernel).
A kernel is essentially a fixed size array of numerical coefficeints along with an anchor point in that array, which is tipically located at the center.
Assume you want to know the resulting value of a particular location in the image. The value of the convolution is calculated in the following way:
Expressing the procedure above in the form of an equation we would have:
Fortunately, OpenCV provides you with the function filter2D so you do not have to code all these operations.
What does this program do?
Loads an image
Performs a normalized box filter. For instance, for a kernel of size , the kernel would be:
The program will perform the filter operation with kernels of sizes 3, 5, 7, 9 and 11.
The filter output (with each kernel) will be shown during 500 milliseconds
The tutorial code’s is shown lines below. You can also download it from here
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>
using namespace cv;
/** @function main */
int main ( int argc, char** argv )
{
/// Declare variables
Mat src, dst;
Mat kernel;
Point anchor;
double delta;
int ddepth;
int kernel_size;
char* window_name = "filter2D Demo";
int c;
/// Load an image
src = imread( argv[1] );
if( !src.data )
{ return -1; }
/// Create window
namedWindow( window_name, CV_WINDOW_AUTOSIZE );
/// Initialize arguments for the filter
anchor = Point( -1, -1 );
delta = 0;
ddepth = -1;
/// Loop - Will filter the image with different kernel sizes each 0.5 seconds
int ind = 0;
while( true )
{
c = waitKey(500);
/// Press 'ESC' to exit the program
if( (char)c == 27 )
{ break; }
/// Update kernel size for a normalized box filter
kernel_size = 3 + 2*( ind%5 );
kernel = Mat::ones( kernel_size, kernel_size, CV_32F )/ (float)(kernel_size*kernel_size);
/// Apply filter
filter2D(src, dst, ddepth , kernel, anchor, delta, BORDER_DEFAULT );
imshow( window_name, dst );
ind++;
}
return 0;
}
Load an image
src = imread( argv[1] );
if( !src.data )
{ return -1; }
Create a window to display the result
namedWindow( window_name, CV_WINDOW_AUTOSIZE );
Initialize the arguments for the linear filter
anchor = Point( -1, -1 );
delta = 0;
ddepth = -1;
Perform an infinite loop updating the kernel size and applying our linear filter to the input image. Let’s analyze that more in detail:
First we define the kernel our filter is going to use. Here it is:
kernel_size = 3 + 2*( ind%5 );
kernel = Mat::ones( kernel_size, kernel_size, CV_32F )/ (float)(kernel_size*kernel_size);
The first line is to update the kernel_size to odd values in the range: . The second line actually builds the kernel by setting its value to a matrix filled with and normalizing it by dividing it between the number of elements.
After setting the kernel, we can generate the filter by using the function filter2D:
filter2D(src, dst, ddepth , kernel, anchor, delta, BORDER_DEFAULT );
The arguments denote:
Our program will effectuate a while loop, each 500 ms the kernel size of our filter will be updated in the range indicated.
After compiling the code above, you can execute it giving as argument the path of an image. The result should be a window that shows an image blurred by a normalized filter. Each 0.5 seconds the kernel size should change, as can be seen in the series of snapshots below: