mirror of
https://github.com/opencv/opencv.git
synced 2024-11-24 19:20:28 +08:00
Added reST tutorial documentation for Pyramids and added a few links to conf.py
This commit is contained in:
parent
5df9da1576
commit
9ce4e87507
@ -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)
|
||||
}
|
||||
|
||||
|
||||
|
256
doc/tutorials/ImgProc/Pyramids/Pyramids.rst
Normal file
256
doc/tutorials/ImgProc/Pyramids/Pyramids.rst
Normal file
@ -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
|
||||
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 290 KiB |
Binary file not shown.
After Width: | Height: | Size: 574 KiB |
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
Binary file not shown.
After Width: | Height: | Size: 237 KiB |
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user