Home | History | Annotate | Download | only in pyramids
      1 Image Pyramids {#tutorial_pyramids}
      2 ==============
      3 
      4 Goal
      5 ----
      6 
      7 In this tutorial you will learn how to:
      8 
      9 -   Use the OpenCV functions @ref cv::pyrUp and @ref cv::pyrDown to downsample or upsample a given
     10     image.
     11 
     12 Theory
     13 ------
     14 
     15 @note The explanation below belongs to the book **Learning OpenCV** by Bradski and Kaehler.
     16 
     17 -   Usually we need to convert an image to a size different than its original. For this, there are
     18     two possible options:
     19     -#  *Upsize* the image (zoom in) or
     20     -#  *Downsize* it (zoom out).
     21 -   Although there is a *geometric transformation* function in OpenCV that -literally- resize an
     22     image (@ref cv::resize , which we will show in a future tutorial), in this section we analyze
     23     first the use of **Image Pyramids**, which are widely applied in a huge range of vision
     24     applications.
     25 
     26 ### Image Pyramid
     27 
     28 -   An image pyramid is a collection of images - all arising from a single original image - that are
     29     successively downsampled until some desired stopping point is reached.
     30 -   There are two common kinds of image pyramids:
     31     -   **Gaussian pyramid:** Used to downsample images
     32     -   **Laplacian pyramid:** Used to reconstruct an upsampled image from an image lower in the
     33         pyramid (with less resolution)
     34 -   In this tutorial we'll use the *Gaussian pyramid*.
     35 
     36 #### Gaussian Pyramid
     37 
     38 -   Imagine the pyramid as a set of layers in which the higher the layer, the smaller the size.
     39 
     40     ![](images/Pyramids_Tutorial_Pyramid_Theory.png)
     41 
     42 -   Every layer is numbered from bottom to top, so layer \f$(i+1)\f$ (denoted as \f$G_{i+1}\f$ is smaller
     43     than layer \f$i\f$ (\f$G_{i}\f$).
     44 -   To produce layer \f$(i+1)\f$ in the Gaussian pyramid, we do the following:
     45     -   Convolve \f$G_{i}\f$ with a Gaussian kernel:
     46 
     47         \f[\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}\f]
     48 
     49     -   Remove every even-numbered row and column.
     50 
     51 -   You can easily notice that the resulting image will be exactly one-quarter the area of its
     52     predecessor. Iterating this process on the input image \f$G_{0}\f$ (original image) produces the
     53     entire pyramid.
     54 -   The procedure above was useful to downsample an image. What if we want to make it bigger?:
     55     columns filled with zeros (\f$0\f$)
     56     -   First, upsize the image to twice the original in each dimension, wit the new even rows and
     57     -   Perform a convolution with the same kernel shown above (multiplied by 4) to approximate the
     58         values of the "missing pixels"
     59 -   These two procedures (downsampling and upsampling as explained above) are implemented by the
     60     OpenCV functions @ref cv::pyrUp and @ref cv::pyrDown , as we will see in an example with the
     61     code below:
     62 
     63 @note When we reduce the size of an image, we are actually *losing* information of the image.
     64 
     65 Code
     66 ----
     67 
     68 This tutorial code's is shown lines below. You can also download it from
     69 [here](https://github.com/Itseez/opencv/tree/master/samples/cpp/tutorial_code/ImgProc/Pyramids.cpp)
     70 
     71 @include samples/cpp/tutorial_code/ImgProc/Pyramids.cpp
     72 
     73 Explanation
     74 -----------
     75 
     76 Let's check the general structure of the program:
     77 
     78 -   Load an image (in this case it is defined in the program, the user does not have to enter it
     79     as an argument)
     80     @code{.cpp}
     81     /// Test image - Make sure it s divisible by 2^{n}
     82     src = imread( "../images/chicky_512.jpg" );
     83     if( !src.data )
     84       { printf(" No data! -- Exiting the program \n");
     85         return -1; }
     86     @endcode
     87 
     88 -   Create a Mat object to store the result of the operations (*dst*) and one to save temporal
     89     results (*tmp*).
     90     @code{.cpp}
     91     Mat src, dst, tmp;
     92     /* ... */
     93     tmp = src;
     94     dst = tmp;
     95     @endcode
     96 
     97 -   Create a window to display the result
     98     @code{.cpp}
     99     namedWindow( window_name, WINDOW_AUTOSIZE );
    100     imshow( window_name, dst );
    101     @endcode
    102 
    103 -   Perform an infinite loop waiting for user input.
    104     @code{.cpp}
    105     while( true )
    106     {
    107       int c;
    108       c = waitKey(10);
    109 
    110       if( (char)c == 27 )
    111         { break; }
    112       if( (char)c == 'u' )
    113         { pyrUp( tmp, dst, Size( tmp.cols*2, tmp.rows*2 ) );
    114           printf( "** Zoom In: Image x 2 \n" );
    115         }
    116       else if( (char)c == 'd' )
    117        { pyrDown( tmp, dst, Size( tmp.cols/2, tmp.rows/2 ) );
    118          printf( "** Zoom Out: Image / 2 \n" );
    119        }
    120 
    121       imshow( window_name, dst );
    122       tmp = dst;
    123     }
    124     @endcode
    125     Our program exits if the user presses *ESC*. Besides, it has two options:
    126 
    127     -   **Perform upsampling (after pressing 'u')**
    128         @code{.cpp}
    129         pyrUp( tmp, dst, Size( tmp.cols*2, tmp.rows*2 )
    130         @endcode
    131         We use the function @ref cv::pyrUp with 03 arguments:
    132 
    133         -   *tmp*: The current image, it is initialized with the *src* original image.
    134         -   *dst*: The destination image (to be shown on screen, supposedly the double of the
    135             input image)
    136         -   *Size( tmp.cols*2, tmp.rows\*2 )\* : The destination size. Since we are upsampling,
    137             @ref cv::pyrUp expects a size double than the input image (in this case *tmp*).
    138     -   **Perform downsampling (after pressing 'd')**
    139         @code{.cpp}
    140         pyrDown( tmp, dst, Size( tmp.cols/2, tmp.rows/2 )
    141         @endcode
    142         Similarly as with @ref cv::pyrUp , we use the function @ref cv::pyrDown with 03
    143         arguments:
    144 
    145         -   *tmp*: The current image, it is initialized with the *src* original image.
    146         -   *dst*: The destination image (to be shown on screen, supposedly half the input
    147             image)
    148         -   *Size( tmp.cols/2, tmp.rows/2 )* : The destination size. Since we are upsampling,
    149             @ref cv::pyrDown expects half the size the input image (in this case *tmp*).
    150     -   Notice that it is important that the input image can be divided by a factor of two (in
    151         both dimensions). Otherwise, an error will be shown.
    152     -   Finally, we update the input image **tmp** with the current image displayed, so the
    153         subsequent operations are performed on it.
    154         @code{.cpp}
    155         tmp = dst;
    156         @endcode
    157 
    158 Results
    159 -------
    160 
    161 -   After compiling the code above we can test it. The program calls an image **chicky_512.jpg**
    162     that comes in the *tutorial_code/image* folder. Notice that this image is \f$512 \times 512\f$,
    163     hence a downsample won't generate any error (\f$512 = 2^{9}\f$). The original image is shown below:
    164 
    165     ![](images/Pyramids_Tutorial_Original_Image.jpg)
    166 
    167 -   First we apply two successive @ref cv::pyrDown operations by pressing 'd'. Our output is:
    168 
    169     ![](images/Pyramids_Tutorial_PyrDown_Result.jpg)
    170 
    171 -   Note that we should have lost some resolution due to the fact that we are diminishing the size
    172     of the image. This is evident after we apply @ref cv::pyrUp twice (by pressing 'u'). Our output
    173     is now:
    174 
    175     ![](images/Pyramids_Tutorial_PyrUp_Result.jpg)
    176