Added rst Tutorial for Filter 2D
authorAna Huaman <no@email>
Mon, 27 Jun 2011 04:01:01 +0000 (04:01 +0000)
committerAna Huaman <no@email>
Mon, 27 Jun 2011 04:01:01 +0000 (04:01 +0000)
doc/tutorials/imgproc/imgtrans/filter_2d/filter_2d.rst [new file with mode: 0644]
doc/tutorials/imgproc/imgtrans/filter_2d/images/filter_2d_tutorial_kernel_theory.png [new file with mode: 0644]
doc/tutorials/imgproc/imgtrans/filter_2d/images/filter_2d_tutorial_result.png [new file with mode: 0644]
doc/tutorials/imgproc/table_of_content_imgproc/images/imgtrans/Filter_2D_Tutorial_Cover.jpg [new file with mode: 0644]
doc/tutorials/imgproc/table_of_content_imgproc/table_of_content_imgproc.rst

diff --git a/doc/tutorials/imgproc/imgtrans/filter_2d/filter_2d.rst b/doc/tutorials/imgproc/imgtrans/filter_2d/filter_2d.rst
new file mode 100644 (file)
index 0000000..aa5a69a
--- /dev/null
@@ -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
diff --git a/doc/tutorials/imgproc/imgtrans/filter_2d/images/filter_2d_tutorial_kernel_theory.png b/doc/tutorials/imgproc/imgtrans/filter_2d/images/filter_2d_tutorial_kernel_theory.png
new file mode 100644 (file)
index 0000000..70d4e2d
Binary files /dev/null and b/doc/tutorials/imgproc/imgtrans/filter_2d/images/filter_2d_tutorial_kernel_theory.png differ
diff --git a/doc/tutorials/imgproc/imgtrans/filter_2d/images/filter_2d_tutorial_result.png b/doc/tutorials/imgproc/imgtrans/filter_2d/images/filter_2d_tutorial_result.png
new file mode 100644 (file)
index 0000000..416d84d
Binary files /dev/null and b/doc/tutorials/imgproc/imgtrans/filter_2d/images/filter_2d_tutorial_result.png differ
diff --git a/doc/tutorials/imgproc/table_of_content_imgproc/images/imgtrans/Filter_2D_Tutorial_Cover.jpg b/doc/tutorials/imgproc/table_of_content_imgproc/images/imgtrans/Filter_2D_Tutorial_Cover.jpg
new file mode 100644 (file)
index 0000000..eb02934
Binary files /dev/null and b/doc/tutorials/imgproc/table_of_content_imgproc/images/imgtrans/Filter_2D_Tutorial_Cover.jpg differ
index 2f19080..5c9621c 100644 (file)
@@ -103,3 +103,26 @@ In this section you will learn about the image processing (manipulation) functio
   .. |Threshold| image:: images/Threshold_Tutorial_Cover.png\r
                       :height: 100pt\r
                       :width:  100pt\r
+\r
+.. ************************\r
+.. ImgTrans\r
+.. ************************\r
+\r
+* :ref:`filter_2d`\r
+\r
+  ===================== ==============================================\r
+   |Filter_2D|          *Title:* **Making your own linear filters**\r
+\r
+                        *Compatibility:* > OpenCV 2.0\r
+                        \r
+                        *Author:* |Author_AnaH|\r
+\r
+                        Where we learn to design our own filters by using OpenCV functions\r
+\r
+  ===================== ==============================================\r
+  \r
+  .. |Filter_2D| image:: images/imgtrans/Filter_2D_Tutorial_Cover.jpg\r
+                      :height: 100pt\r
+                      :width:  100pt\r
+\r
+\r