mirror of
https://github.com/opencv/opencv.git
synced 2025-01-18 06:03:15 +08:00
Added rst Tutorial for Filter 2D
This commit is contained in:
parent
3a0d3ebdde
commit
ae649e8c30
200
doc/tutorials/imgproc/imgtrans/filter_2d/filter_2d.rst
Normal file
200
doc/tutorials/imgproc/imgtrans/filter_2d/filter_2d.rst
Normal file
@ -0,0 +1,200 @@
|
||||
.. _filter_2d:
|
||||
|
||||
Making your own linear filters!
|
||||
********************************
|
||||
|
||||
Goal
|
||||
=====
|
||||
|
||||
In this tutorial you will learn how to:
|
||||
|
||||
* Use the OpenCV function :filter2d:`filter2D <>` to create your own linear filters.
|
||||
|
||||
Theory
|
||||
============
|
||||
|
||||
.. note::
|
||||
The explanation below belongs to the book **Learning OpenCV** by Bradski and Kaehler.
|
||||
|
||||
|
||||
Convolution
|
||||
------------
|
||||
In a very general sense, convolution 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 coefficeints along with an *anchor point* in that array, which is tipically located at the center.
|
||||
|
||||
.. image:: images/filter_2d_tutorial_kernel_theory.png
|
||||
:alt: kernel example
|
||||
:align: center
|
||||
|
||||
How does convolution with a kernel work?
|
||||
-----------------------------------------
|
||||
|
||||
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:
|
||||
|
||||
#. Place the kernel anchor on top of a determined pixel, with the rest of the kernel overlaying the corresponding local pixels in the image.
|
||||
|
||||
#. Multiply the kernel coefficients by the corresponding image pixel values and sum the result.
|
||||
|
||||
#. Place the result to the location of the *anchor* in the input image.
|
||||
|
||||
#. 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:
|
||||
|
||||
.. math::
|
||||
|
||||
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:`filter2D <>` so you do not have to code all these operations.
|
||||
|
||||
Code
|
||||
======
|
||||
|
||||
#. **What does this program do?**
|
||||
|
||||
* Loads an image
|
||||
* Performs a *normalized box filter*. For instance, for a kernel of size :math:`size = 3`, the kernel would be:
|
||||
|
||||
.. math::
|
||||
|
||||
K = \dfrac{1}{3 \cdot 3} \begin{bmatrix}
|
||||
1 & 1 & 1 \\
|
||||
1 & 1 & 1 \\
|
||||
1 & 1 & 1
|
||||
\end{bmatrix}
|
||||
|
||||
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 <https://code.ros.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ImgTrans/filter2D_demo.cpp>`_
|
||||
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#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;
|
||||
}
|
||||
Explanation
|
||||
=============
|
||||
|
||||
#. We begin with the usual steps:
|
||||
|
||||
* Load an image
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
src = imread( argv[1] );
|
||||
|
||||
if( !src.data )
|
||||
{ return -1; }
|
||||
|
||||
* Create a window to display the result
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
namedWindow( window_name, CV_WINDOW_AUTOSIZE );
|
||||
|
||||
#. Initialize the arguments for the linear filter
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
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:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
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: :math:`[3,11]`. The second line actually builds the kernel by setting its value to a matrix filled with :math:`1's` 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 <>`:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
filter2D(src, dst, ddepth , kernel, anchor, delta, BORDER_DEFAULT );
|
||||
|
||||
The arguments denote:
|
||||
|
||||
a. *src*: Source image
|
||||
#. *dst*: Destination image
|
||||
#. *ddepth*: The depth of *dst*. A negative value (such as :math:`-1`) indicates that the depth is the same as the source.
|
||||
#. *kernel*: The kernel to be scanned through the image
|
||||
#. *anchor*: The position of the anchor relative to its kernel. The location *Point(-1, -1)* indicates the center by default.
|
||||
#. *delta*: A value to be added to each pixel during the convolution. By default it is :math:`0`
|
||||
#. *BORDER_DEFAULT*: We let this value by default (more details in the following tutorial)
|
||||
|
||||
#. Our program will effectuate a *while* loop, each 500 ms the kernel size of our filter will be updated in the range indicated.
|
||||
|
||||
Results
|
||||
========
|
||||
|
||||
#. 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:
|
||||
|
||||
.. image:: images/filter_2d_tutorial_result.png
|
||||
:alt: kernel example
|
||||
:align: center
|
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
Binary file not shown.
After Width: | Height: | Size: 125 KiB |
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
@ -103,3 +103,26 @@ In this section you will learn about the image processing (manipulation) functio
|
||||
.. |Threshold| image:: images/Threshold_Tutorial_Cover.png
|
||||
:height: 100pt
|
||||
:width: 100pt
|
||||
|
||||
.. ************************
|
||||
.. ImgTrans
|
||||
.. ************************
|
||||
|
||||
* :ref:`filter_2d`
|
||||
|
||||
===================== ==============================================
|
||||
|Filter_2D| *Title:* **Making your own linear filters**
|
||||
|
||||
*Compatibility:* > OpenCV 2.0
|
||||
|
||||
*Author:* |Author_AnaH|
|
||||
|
||||
Where we learn to design our own filters by using OpenCV functions
|
||||
|
||||
===================== ==============================================
|
||||
|
||||
.. |Filter_2D| image:: images/imgtrans/Filter_2D_Tutorial_Cover.jpg
|
||||
:height: 100pt
|
||||
:width: 100pt
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user