From: Ana Huaman Date: Tue, 21 Jun 2011 22:22:31 +0000 (+0000) Subject: Added reST tutorial documentation for Pyramids and added a few links to conf.py X-Git-Tag: accepted/tizen/6.0/unified/20201030.111113~6889 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9ce4e87507e73b4626bb2fe2797986e6f8521fbc;p=platform%2Fupstream%2Fopencv.git Added reST tutorial documentation for Pyramids and added a few links to conf.py --- diff --git a/doc/conf.py b/doc/conf.py index 023991f..a9ede8c 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -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 index 0000000..8070c73 --- /dev/null +++ b/doc/tutorials/ImgProc/Pyramids/Pyramids.rst @@ -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 `_ + +.. code-block:: cpp + + #include "opencv2/imgproc/imgproc.hpp" + #include "opencv2/highgui/highgui.hpp" + #include + #include + #include + + 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 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 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 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 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 index 0000000..70844d3 Binary files /dev/null and b/doc/tutorials/ImgProc/Pyramids/images/Pyramids_Tutorial_Pyramid_Theory.png differ diff --git a/doc/tutorials/tutorials.rst b/doc/tutorials/tutorials.rst index 6aef65f..d7e6932 100644 --- a/doc/tutorials/tutorials.rst +++ b/doc/tutorials/tutorials.rst @@ -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