Added reST tutorial documentation for Pyramids and added a few links to conf.py
authorAna Huaman <no@email>
Tue, 21 Jun 2011 22:22:31 +0000 (22:22 +0000)
committerAna Huaman <no@email>
Tue, 21 Jun 2011 22:22:31 +0000 (22:22 +0000)
doc/conf.py
doc/tutorials/ImgProc/Pyramids/Pyramids.rst [new file with mode: 0644]
doc/tutorials/ImgProc/Pyramids/images/Pyramids_Tutorial_Cover.png [new file with mode: 0644]
doc/tutorials/ImgProc/Pyramids/images/Pyramids_Tutorial_Original_Image.png [new file with mode: 0644]
doc/tutorials/ImgProc/Pyramids/images/Pyramids_Tutorial_PyrDown_Result.png [new file with mode: 0644]
doc/tutorials/ImgProc/Pyramids/images/Pyramids_Tutorial_PyrUp_Result.png [new file with mode: 0644]
doc/tutorials/ImgProc/Pyramids/images/Pyramids_Tutorial_Pyramid_Theory.png [new file with mode: 0644]
doc/tutorials/tutorials.rst

index 023991f..a9ede8c 100644 (file)
@@ -299,7 +299,10 @@ extlinks = {'cvt_color': ('http://opencv.willowgarage.com/documentation/cpp/imgp
             'dilate': ('http://opencv.jp/opencv-2.2_org/cpp/imgproc_image_filtering.html#cv-dilate%s', None),
             'get_structuring_element': ('http://opencv.jp/opencv-2.2_org/cpp/imgproc_image_filtering.html#cv-getstructuringelement%s', None),
             'flood_fill': ( 'http://opencv.jp/opencv-2.2_org/cpp/imgproc_miscellaneous_image_transformations.html?#floodFill%s', None),
-           'morphology_ex': ('http://opencv.jp/opencv-2.2_org/cpp/imgproc_image_filtering.html?highlight=morphology#morphologyEx%s', None)
+           'morphology_ex': ('http://opencv.jp/opencv-2.2_org/cpp/imgproc_image_filtering.html?highlight=morphology#morphologyEx%s', None),
+            'pyr_down': ('http://opencv.willowgarage.com/documentation/cpp/imgproc_image_filtering.html#cv-pyrdown%s', None),
+            'pyr_up': ('http://opencv.willowgarage.com/documentation/cpp/imgproc_image_filtering.html#cv-pyrup%s', None),
+            'resize': ('http://opencv.willowgarage.com/documentation/cpp/imgproc_geometric_image_transformations.html#cv-resize%s', None)
            }
 
 
diff --git a/doc/tutorials/ImgProc/Pyramids/Pyramids.rst b/doc/tutorials/ImgProc/Pyramids/Pyramids.rst
new file mode 100644 (file)
index 0000000..8070c73
--- /dev/null
@@ -0,0 +1,256 @@
+.. _Pyramids:
+
+Image Pyramids
+***************
+
+Goal
+=====
+
+In this tutorial you will learn how to:
+
+* Use the OpenCV functions :pyr_up:`pyrUp <>` and :pyr_down:`pyrDown <>` to downsample  or upsample a given image.
+  
+Cool Theory
+============
+
+.. note::
+   The explanation below belongs to the book **Learning OpenCV** by Bradski and Kaehler.
+
+* Usually we need to convert an image to a size different than its original. For this, there are two possible options:
+  
+  * *Upsize* the image (zoom in) or 
+  * *Downsize* it (zoom out). 
+
+* Although there is a *geometric transformation* function in OpenCV that -literally- resize an image (:resize:`resize <>`, which we will show in a future tutorial), in this section we analyze first the use of **Image Pyramids**, which are widely applied in a huge range of vision applications.
+
+Image Pyramid
+--------------
+
+* An image pyramid is a collection of images - all arising from a single original image - that are successively downsampled until some desired stopping point is reached.
+
+* There are two common kinds of image pyramids:
+
+  * **Gaussian pyramid:** Used to downsample images
+
+  * **Laplacian pyramid:** Used to  reconstruct an upsampled image from an image lower in the pyramid (with less resolution) 
+
+* In this tutorial we'll use the *Gaussian pyramid*.
+
+Gaussian Pyramid
+^^^^^^^^^^^^^^^^^
+
+* Imagine the pyramid as a set of layers in which the higher the layer, the smaller the size. 
+
+  .. image:: images/Pyramids_Tutorial_Pyramid_Theory.png
+     :alt: Pyramid figure
+     :align: center 
+
+* Every layer is numbered from bottom to top, so layer :math:`(i+1)` (denoted as :math:`G_{i+1}` is smaller than layer :math:`i` (:math:`G_{i}`). 
+
+* To produce layer :math:`(i+1)` in the Gaussian pyramid, we do the following:
+
+  * Convolve :math:`G_{i}` with a Gaussian kernel:
+
+    .. math::
+
+       \frac{1}{16} \begin{bmatrix} 1 & 4 & 6 & 4 & 1  \\ 4 & 16 & 24 & 16 & 4  \\ 6 & 24 & 36 & 24 & 6  \\ 4 & 16 & 24 & 16 & 4  \\ 1 & 4 & 6 & 4 & 1 \end{bmatrix} 
+
+  * Remove every even-numbered row and column. 
+
+* You can easily notice that the resulting image will be exactly one-quarter the area of its predecessor. Iterating this process on the input image :math:`G_{0}` (original image) produces the entire pyramid.
+
+* The procedure above was useful to downsample an image. What if we want to make it bigger?:
+
+  * First, upsize the image to twice the original in each dimension, wit the new even rows and columns filled with zeros (:math:`0`)
+
+  * Perform a convolution with the same kernel shown above (multiplied by 4) to approximate the values of the "missing pixels"
+
+* These two procedures (downsampling and upsampling as explained above) are implemented by the OpenCV functions :pyr_up:`pyrUp <>` and :pyr_down:`pyrDown <>`, as we will see in an example with the code below: 
+
+.. note::
+   When we reduce the size of an image, we are actually *losing* information of the image.
+
+Code
+======
+
+This 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/Image_Processing/Pyramids.cpp>`_
+
+.. code-block:: cpp 
+
+   #include "opencv2/imgproc/imgproc.hpp"
+   #include "opencv2/highgui/highgui.hpp"
+   #include <math.h>
+   #include <stdlib.h>
+   #include <stdio.h>
+
+   using namespace cv;
+
+   /// Global variables
+   Mat src, dst, tmp;
+   char* window_name = "Pyramids Demo";
+
+
+   /**
+    * @function main
+    */
+   int main( int argc, char** argv )
+   {
+     /// General instructions
+     printf( "\n Zoom In-Out demo  \n " );
+     printf( "------------------ \n" );
+     printf( " * [u] -> Zoom in  \n" );
+     printf( " * [d] -> Zoom out \n" );
+     printf( " * [ESC] -> Close program \n \n" );
+
+     /// Test image - Make sure it s divisible by 2^{n}
+     src = imread( "../images/chicky_512.png" );
+     if( !src.data )
+       { printf(" No data! -- Exiting the program \n");
+         return -1; }
+
+     tmp = src;  
+     dst = tmp;
+
+     /// Create window
+     namedWindow( window_name, CV_WINDOW_AUTOSIZE );
+     imshow( window_name, dst );
+
+     /// Loop
+     while( true )
+     { 
+       int c;
+       c = waitKey(10);
+
+       if( (char)c == 27 )
+                { break; }
+       if( (char)c == 'u' )
+         { pyrUp( tmp, dst, Size( tmp.cols*2, tmp.rows*2 ) );
+           printf( "** Zoom In: Image x 2 \n" ); 
+         }
+       else if( (char)c == 'd' )
+        { pyrDown( tmp, dst, Size( tmp.cols/2, tmp.rows/2 ) );
+          printf( "** Zoom Out: Image / 2 \n" );
+        }
+
+       imshow( window_name, dst );
+       tmp = dst;
+     }      
+     return 0;
+   }
+
+Explanation
+=============
+
+#. Let's check the general structure of the program:
+
+   * Load an image (in this case it is defined in the program, the user does not have to enter it as an argument)
+
+     .. code-block:: cpp
+
+        /// Test image - Make sure it s divisible by 2^{n}
+        src = imread( "../images/chicky_512.png" );
+        if( !src.data )
+          { printf(" No data! -- Exiting the program \n");
+            return -1; }
+
+   * Create a Mat object to store the result of the operations (*dst*) and one to save temporal results (*tmp*). 
+
+     .. code-block:: cpp
+  
+        Mat src, dst, tmp;
+        /* ... */
+        tmp = src;  
+        dst = tmp;
+
+
+
+   * Create a window to display the result
+
+     .. code-block:: cpp
+
+        namedWindow( window_name, CV_WINDOW_AUTOSIZE );
+        imshow( window_name, dst );
+
+   * Perform an infinite loop waiting for user input.
+
+     .. code-block:: cpp
+
+        while( true )
+        { 
+          int c;
+          c = waitKey(10);
+
+          if( (char)c == 27 )
+                   { break; }
+          if( (char)c == 'u' )
+            { pyrUp( tmp, dst, Size( tmp.cols*2, tmp.rows*2 ) );
+              printf( "** Zoom In: Image x 2 \n" ); 
+            }
+          else if( (char)c == 'd' )
+           { pyrDown( tmp, dst, Size( tmp.cols/2, tmp.rows/2 ) );
+             printf( "** Zoom Out: Image / 2 \n" );
+           }
+
+          imshow( window_name, dst );
+          tmp = dst;
+        }      
+   
+
+     Our program exits if the user presses *ESC*. Besides, it has two options:
+     * **Perform upsampling (after pressing 'u')**    
+
+       .. code-block:: cpp
+
+          pyrUp( tmp, dst, Size( tmp.cols*2, tmp.rows*2 )
+
+       We use the function :pyr_up:`pyrUp <>` with 03 arguments:
+
+       * *tmp*: The current image, it is initialized with the *src* original image.
+       * *dst*: The destination image (to be shown on screen, supposedly the double of the input image)
+       * *Size( tmp.cols*2, tmp.rows*2 )* : The destination size. Since we are upsampling, :pyr_up:`pyrUp <>` expects a size double than the input image (in this case *tmp*).
+
+     * **Perform downsampling (after pressing 'd')**    
+
+       .. code-block:: cpp
+
+          pyrDown( tmp, dst, Size( tmp.cols/2, tmp.rows/2 )
+
+       Similarly as with :pyr_up:`pyrUp <>`, we use the function :pyr_down:`pyrDown <>` with 03 arguments:
+
+       * *tmp*: The current image, it is initialized with the *src* original image.
+       * *dst*: The destination image (to be shown on screen, supposedly half the input image)
+       * *Size( tmp.cols/2, tmp.rows/2 )* : The destination size. Since we are upsampling, :pyr_down:`pyrDown <>` expects half the size the input image (in this case *tmp*).
+
+     * Notice that it is important that the input image can be divided by a factor of two (in both dimensions). Otherwise, an error will be shown.
+
+     * Finally, we update the input image **tmp** with the current image displayed, so the subsequent operations are performed on it.
+       .. code-block:: cpp
+
+          tmp = dst;
+
+
+
+Results
+========
+
+* After compiling the code above we can test it. The program calls an image **chicky_512.png** that comes in the *tutorial_code/image* folder. Notice that this image is :math:`512 \times 512`, hence a downsample won't generate any error (:math:`512 = 2^{9}`). The original image is shown below:
+
+  .. image:: images/Pyramids_Tutorial_Original_Image.png
+     :alt: Pyramids: Original image    
+     :align: center 
+
+* First we apply two successive :pyr_down:`pyrDown <>` operations by pressing 'd'. Our output is:
+  .. image:: images/Pyramids_Tutorial_PyrDown_Result.png
+     :alt: Pyramids: PyrDown Result
+     :align: center 
+
+* Note that we should have lost some resolution due to the fact that we are diminishing the size of the image. This is evident after we apply :pyr_up:`pyrUp <>` twice (by pressing 'u'). Our output is now:
+  .. image:: images/Pyramids_Tutorial_PyrUp_Result.png
+     :alt: Pyramids: PyrUp Result
+     :align: center 
+
+
diff --git a/doc/tutorials/ImgProc/Pyramids/images/Pyramids_Tutorial_Cover.png b/doc/tutorials/ImgProc/Pyramids/images/Pyramids_Tutorial_Cover.png
new file mode 100644 (file)
index 0000000..af2b9a9
Binary files /dev/null and b/doc/tutorials/ImgProc/Pyramids/images/Pyramids_Tutorial_Cover.png differ
diff --git a/doc/tutorials/ImgProc/Pyramids/images/Pyramids_Tutorial_Original_Image.png b/doc/tutorials/ImgProc/Pyramids/images/Pyramids_Tutorial_Original_Image.png
new file mode 100644 (file)
index 0000000..7236637
Binary files /dev/null and b/doc/tutorials/ImgProc/Pyramids/images/Pyramids_Tutorial_Original_Image.png differ
diff --git a/doc/tutorials/ImgProc/Pyramids/images/Pyramids_Tutorial_PyrDown_Result.png b/doc/tutorials/ImgProc/Pyramids/images/Pyramids_Tutorial_PyrDown_Result.png
new file mode 100644 (file)
index 0000000..8d39287
Binary files /dev/null and b/doc/tutorials/ImgProc/Pyramids/images/Pyramids_Tutorial_PyrDown_Result.png differ
diff --git a/doc/tutorials/ImgProc/Pyramids/images/Pyramids_Tutorial_PyrUp_Result.png b/doc/tutorials/ImgProc/Pyramids/images/Pyramids_Tutorial_PyrUp_Result.png
new file mode 100644 (file)
index 0000000..9cedda0
Binary files /dev/null and b/doc/tutorials/ImgProc/Pyramids/images/Pyramids_Tutorial_PyrUp_Result.png differ
diff --git a/doc/tutorials/ImgProc/Pyramids/images/Pyramids_Tutorial_Pyramid_Theory.png b/doc/tutorials/ImgProc/Pyramids/images/Pyramids_Tutorial_Pyramid_Theory.png
new file mode 100644 (file)
index 0000000..70844d3
Binary files /dev/null and b/doc/tutorials/ImgProc/Pyramids/images/Pyramids_Tutorial_Pyramid_Theory.png differ
index 6aef65f..d7e6932 100644 (file)
@@ -204,7 +204,7 @@ As always, we would be happy to hear your comments and receive your contribution
      ===================== ======================================================
     
      .. |Morphology_1| image:: ImgProc/Morphology_1/images/Morphology_1_Tutorial_Cover.png
-                       :height: 200px
+                       :height: 200pt
 
 
   * :ref:`Morphology_2`
@@ -219,4 +219,18 @@ As always, we would be happy to hear your comments and receive your contribution
      ===================== ======================================================
     
      .. |Morphology_2| image:: ImgProc/Morphology_2/images/Morphology_2_Tutorial_Cover.png
-                       :height: 200px
+                       :height: 200pt
+
+  * :ref:`Pyramids`
+
+     ===================== ======================================================
+      |Pyramids|           *Title:* **Image Pyramids**
+
+                          *Compatibility:* > OpenCV 2.0
+
+                          What if I need a bigger/smaller image?
+    
+     ===================== ======================================================
+    
+     .. |Pyramids| image:: ImgProc/Pyramids/images/Pyramids_Tutorial_Cover.png
+                   :height: 200pt