OpenCV  4.1.0
Open Source Computer Vision
Making your own linear filters!

Prev Tutorial: Thresholding Operations using inRange

Next Tutorial: Adding borders to your images

Goal

In this tutorial you will learn how to:

Theory

Note
The explanation below belongs to the book Learning OpenCV by Bradski and Kaehler.

Correlation

In a very general sense, correlation is an operation between every part of an image and an operator (kernel).

What is a kernel?

A kernel is essentially a fixed size array of numerical coefficients along with an anchor point in that array, which is typically located at the center.

filter_2d_tutorial_kernel_theory.png

How does correlation with a kernel work?

Assume you want to know the resulting value of a particular location in the image. The value of the correlation is calculated in the following way:

  1. Place the kernel anchor on top of a determined pixel, with the rest of the kernel overlaying the corresponding local pixels in the image.
  2. Multiply the kernel coefficients by the corresponding image pixel values and sum the result.
  3. Place the result to the location of the anchor in the input image.
  4. Repeat the process for all pixels by scanning the kernel over the entire image.

Expressing the procedure above in the form of an equation we would have:

\[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)\]

Fortunately, OpenCV provides you with the function filter2D() so you do not have to code all these operations.

What does this program do?

The program will perform the filter operation with kernels of sizes 3, 5, 7, 9 and 11.

Code

The tutorial code's is shown in the lines below.

Explanation

Load an image

Initialize the arguments

Loop

Perform an infinite loop updating the kernel size and applying our linear filter to the input image. Let's analyze that more in detail:

The first line is to update the kernel_size to odd values in the range: \([3,11]\). The second line actually builds the kernel by setting its value to a matrix filled with \(1's\) and normalizing it by dividing it between the number of elements.

Results

  1. 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:
filter_2d_tutorial_result.jpg