From: Ana Huaman Date: Thu, 30 Jun 2011 09:08:04 +0000 (+0000) Subject: Added Remap tutorial in reST X-Git-Tag: accepted/2.0/20130307.220821~2607 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=64c8d8f2a0c38e5be57bebd01a1e2a73cf4f79c7;p=profile%2Fivi%2Fopencv.git Added Remap tutorial in reST --- diff --git a/doc/conf.py b/doc/conf.py index a71dc2c..561d9ae 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -316,7 +316,10 @@ extlinks = {'cvt_color': ('http://opencv.willowgarage.com/documentation/cpp/imgp 'opencv_group' : ('http://tech.groups.yahoo.com/group/OpenCV/%s', None), 'hough_lines' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_feature_detection.html?#cv-houghlines%s', None), 'hough_lines_p' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_feature_detection.html?#cv-houghlinesp%s', None), - 'hough_circles' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_feature_detection.html?#cv-houghcircles%s', None) + 'hough_circles' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_feature_detection.html?#cv-houghcircles%s', None), + 'remap' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_geometric_image_transformations.html?#remap%s', None), + 'warp_affine' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_geometric_image_transformations.html?#cv-warpaffine%s' , None), + 'get_rotation_matrix_2d' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_geometric_image_transformations.html?#cv-getrotationmatrix2d%s', None) } diff --git a/doc/tutorials/imgproc/imgtrans/remap/images/Remap_Tutorial_Original_Image.jpg b/doc/tutorials/imgproc/imgtrans/remap/images/Remap_Tutorial_Original_Image.jpg new file mode 100644 index 0000000..46cce16 Binary files /dev/null and b/doc/tutorials/imgproc/imgtrans/remap/images/Remap_Tutorial_Original_Image.jpg differ diff --git a/doc/tutorials/imgproc/imgtrans/remap/images/Remap_Tutorial_Result_0.jpg b/doc/tutorials/imgproc/imgtrans/remap/images/Remap_Tutorial_Result_0.jpg new file mode 100644 index 0000000..a38f383 Binary files /dev/null and b/doc/tutorials/imgproc/imgtrans/remap/images/Remap_Tutorial_Result_0.jpg differ diff --git a/doc/tutorials/imgproc/imgtrans/remap/images/Remap_Tutorial_Result_1.jpg b/doc/tutorials/imgproc/imgtrans/remap/images/Remap_Tutorial_Result_1.jpg new file mode 100644 index 0000000..9d2a4e3 Binary files /dev/null and b/doc/tutorials/imgproc/imgtrans/remap/images/Remap_Tutorial_Result_1.jpg differ diff --git a/doc/tutorials/imgproc/imgtrans/remap/images/Remap_Tutorial_Result_2.jpg b/doc/tutorials/imgproc/imgtrans/remap/images/Remap_Tutorial_Result_2.jpg new file mode 100644 index 0000000..934d78c Binary files /dev/null and b/doc/tutorials/imgproc/imgtrans/remap/images/Remap_Tutorial_Result_2.jpg differ diff --git a/doc/tutorials/imgproc/imgtrans/remap/images/Remap_Tutorial_Result_3.jpg b/doc/tutorials/imgproc/imgtrans/remap/images/Remap_Tutorial_Result_3.jpg new file mode 100644 index 0000000..74d5982 Binary files /dev/null and b/doc/tutorials/imgproc/imgtrans/remap/images/Remap_Tutorial_Result_3.jpg differ diff --git a/doc/tutorials/imgproc/imgtrans/remap/images/Remap_Tutorial_Theory_0.jpg b/doc/tutorials/imgproc/imgtrans/remap/images/Remap_Tutorial_Theory_0.jpg new file mode 100644 index 0000000..cf5a74a Binary files /dev/null and b/doc/tutorials/imgproc/imgtrans/remap/images/Remap_Tutorial_Theory_0.jpg differ diff --git a/doc/tutorials/imgproc/imgtrans/remap/images/Remap_Tutorial_Theory_1.jpg b/doc/tutorials/imgproc/imgtrans/remap/images/Remap_Tutorial_Theory_1.jpg new file mode 100644 index 0000000..8d1aa12 Binary files /dev/null and b/doc/tutorials/imgproc/imgtrans/remap/images/Remap_Tutorial_Theory_1.jpg differ diff --git a/doc/tutorials/imgproc/imgtrans/remap/remap.rst b/doc/tutorials/imgproc/imgtrans/remap/remap.rst new file mode 100644 index 0000000..61e7048 --- /dev/null +++ b/doc/tutorials/imgproc/imgtrans/remap/remap.rst @@ -0,0 +1,314 @@ +.. _remap: + +Remapping +********* + +Goal +==== + +In this tutorial you will learn how to: + +a. Use the OpenCV function :remap:`remap <>` to implement simple remapping routines. + +Theory +====== + +What is remapping? +------------------ + +* It is the process of taking pixels from one place in the image and locating them in another position in a new image. + +* To accomplish the mapping process, it might be necessary to do some interpolation for non-integer pixel locations, since there will not always be a one-to-one-pixel correspondence between source and destination images. + +* We can express the remap for every pixel location :math:`(x,y)` as: + + .. math:: + + g(x,y) = f ( h(x,y) ) + + where :math:`g()` is the remapped image, :math:`f()` the source image and :math:`h(x,y)` is the mapping function that operates on :math:`(x,y)`. + +* Let's think in a quick example. Imagine that we have an image :math:`I` and, say, we want to do a remap such that: + + .. math:: + + h(x,y) = (I.cols - x, y ) + + What would happen? It is easily seen that the image would flip in the :math:`x` direction. For instance, consider the input image: + + .. image:: images/Remap_Tutorial_Theory_0.jpg + :alt: Original test image + :width: 120pt + :align: center + + observe how the red circle changes positions with respect to x (considering :math:`x` the horizontal direction): + + .. image:: images/Remap_Tutorial_Theory_1.jpg + :alt: Original test image + :width: 120pt + :align: center + +* In OpenCV, the function :remap:`remap <>` offers a simple remapping implementation. + +Code +==== + +#. **What does this program do?** + + * Loads an image + * Each second, apply 1 of 4 different remapping processes to the image and display them indefinitely in a window. + * Wait for the user to exit the program + +#. The tutorial code's is shown lines below. You can also download it from `here `_ + +.. code-block:: cpp + + #include "opencv2/highgui/highgui.hpp" + #include "opencv2/imgproc/imgproc.hpp" + #include + #include + + using namespace cv; + + /// Global variables + Mat src, dst; + Mat map_x, map_y; + char* remap_window = "Remap demo"; + int ind = 0; + + /// Function Headers + void update_map( void ); + + /** + * @function main + */ + int main( int argc, char** argv ) + { + /// Load the image + src = imread( argv[1], 1 ); + + /// Create dst, map_x and map_y with the same size as src: + dst.create( src.size(), src.type() ); + map_x.create( src.size(), CV_32FC1 ); + map_y.create( src.size(), CV_32FC1 ); + + /// Create window + namedWindow( remap_window, CV_WINDOW_AUTOSIZE ); + + /// Loop + while( true ) + { + /// Each 1 sec. Press ESC to exit the program + int c = waitKey( 1000 ); + + if( (char)c == 27 ) + { break; } + + /// Update map_x & map_y. Then apply remap + update_map(); + remap( src, dst, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0,0, 0) ); + + /// Display results + imshow( remap_window, dst ); + } + return 0; + } + + /** + * @function update_map + * @brief Fill the map_x and map_y matrices with 4 types of mappings + */ + void update_map( void ) + { + ind = ind%4; + + for( int j = 0; j < src.rows; j++ ) + { for( int i = 0; i < src.cols; i++ ) + { + switch( ind ) + { + case 0: + if( i > src.cols*0.25 && i < src.cols*0.75 && j > src.rows*0.25 && j < src.rows*0.75 ) + { + map_x.at(j,i) = 2*( i - src.cols*0.25 ) + 0.5 ; + map_y.at(j,i) = 2*( j - src.rows*0.25 ) + 0.5 ; + } + else + { map_x.at(j,i) = 0 ; + map_y.at(j,i) = 0 ; + } + break; + case 1: + map_x.at(j,i) = i ; + map_y.at(j,i) = src.rows - j ; + break; + case 2: + map_x.at(j,i) = src.cols - i ; + map_y.at(j,i) = j ; + break; + case 3: + map_x.at(j,i) = src.cols - i ; + map_y.at(j,i) = src.rows - j ; + break; + } // end of switch + } + } + ind++; + } + +Explanation +=========== + +#. Create some variables we will use: + + .. code-block:: cpp + + Mat src, dst; + Mat map_x, map_y; + char* remap_window = "Remap demo"; + int ind = 0; + +#. Load an image: + + .. code-block:: cpp + + src = imread( argv[1], 1 ); + +#. Create the destination image and the two mapping matrices (for x and y ) + + .. code-block:: cpp + + dst.create( src.size(), src.type() ); + map_x.create( src.size(), CV_32FC1 ); + map_y.create( src.size(), CV_32FC1 ); + +#. Create a window to display results + + .. code-block:: cpp + + namedWindow( remap_window, CV_WINDOW_AUTOSIZE ); + +#. Establish a loop. Each 1000 ms we update our mapping matrices (*mat_x* and *mat_y*) and apply them to our source image: + + .. code-block:: cpp + + while( true ) + { + /// Each 1 sec. Press ESC to exit the program + int c = waitKey( 1000 ); + + if( (char)c == 27 ) + { break; } + + /// Update map_x & map_y. Then apply remap + update_map(); + remap( src, dst, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0,0, 0) ); + + /// Display results + imshow( remap_window, dst ); + } + + The function that applies the remapping is :remap:`remap <>`. We give the following arguments: + + * **src**: Source image + * **dst**: Destination image of same size as *src* + * **map_x**: The mapping function in the x direction. It is equivalent to the first component of :math:`h(i,j)` + * **map_y**: Same as above, but in y direction. Note that *map_y* and *map_x* are both of the same size as *src* + * **CV_INTER_LINEAR**: The type of interpolation to use for non-integer pixels. This is by default. + * **BORDER_CONSTANT**: Default + + How do we update our mapping matrices *mat_x* and *mat_y*? Go on reading: + +#. **Updating the mapping matrices:** We are going to perform 4 different mappings: + + a. Reduce the picture to half its size and will display it in the middle: + + .. math:: + + h(i,j) = ( 2*i - src.cols/2 + 0.5, 2*j - src.rows/2 + 0.5) + + for all pairs :math:`(i,j)` such that: :math:`\dfrac{src.cols}{4} src.cols*0.25 && i < src.cols*0.75 && j > src.rows*0.25 && j < src.rows*0.75 ) + { + map_x.at(j,i) = 2*( i - src.cols*0.25 ) + 0.5 ; + map_y.at(j,i) = 2*( j - src.rows*0.25 ) + 0.5 ; + } + else + { map_x.at(j,i) = 0 ; + map_y.at(j,i) = 0 ; + } + break; + case 1: + map_x.at(j,i) = i ; + map_y.at(j,i) = src.rows - j ; + break; + case 2: + map_x.at(j,i) = src.cols - i ; + map_y.at(j,i) = j ; + break; + case 3: + map_x.at(j,i) = src.cols - i ; + map_y.at(j,i) = src.rows - j ; + break; + } // end of switch + } + } + ind++; + } + + +Result +====== + +#. After compiling the code above, you can execute it giving as argument an image path. For instance, by using the following image: + + .. image:: images/Remap_Tutorial_Original_Image.jpg + :alt: Original test image + :width: 250pt + :align: center + +#. This is the result of reducing it to half the size and centering it: + + .. image:: images/Remap_Tutorial_Result_0.jpg + :alt: Result 0 for remapping + :width: 250pt + :align: center + +#. Turning it upside down: + + .. image:: images/Remap_Tutorial_Result_1.jpg + :alt: Result 0 for remapping + :width: 250pt + :align: center + +#. Reflecting it in the x direction: + + .. image:: images/Remap_Tutorial_Result_2.jpg + :alt: Result 0 for remapping + :width: 250pt + :align: center + +#. Reflecting it in both directions: + +.. image:: images/Remap_Tutorial_Result_3.jpg + :alt: Result 0 for remapping + :width: 250pt + :align: center + diff --git a/doc/tutorials/imgproc/imgtrans/warp_affine/images/Warp_Affine_Tutorial_Original_Image.jpg b/doc/tutorials/imgproc/imgtrans/warp_affine/images/Warp_Affine_Tutorial_Original_Image.jpg new file mode 100644 index 0000000..52737c5 Binary files /dev/null and b/doc/tutorials/imgproc/imgtrans/warp_affine/images/Warp_Affine_Tutorial_Original_Image.jpg differ diff --git a/doc/tutorials/imgproc/imgtrans/warp_affine/images/Warp_Affine_Tutorial_Result_Warp.jpg b/doc/tutorials/imgproc/imgtrans/warp_affine/images/Warp_Affine_Tutorial_Result_Warp.jpg new file mode 100644 index 0000000..611bfd6 Binary files /dev/null and b/doc/tutorials/imgproc/imgtrans/warp_affine/images/Warp_Affine_Tutorial_Result_Warp.jpg differ diff --git a/doc/tutorials/imgproc/imgtrans/warp_affine/images/Warp_Affine_Tutorial_Result_Warp_Rotate.jpg b/doc/tutorials/imgproc/imgtrans/warp_affine/images/Warp_Affine_Tutorial_Result_Warp_Rotate.jpg new file mode 100644 index 0000000..55763fd Binary files /dev/null and b/doc/tutorials/imgproc/imgtrans/warp_affine/images/Warp_Affine_Tutorial_Result_Warp_Rotate.jpg differ diff --git a/doc/tutorials/imgproc/imgtrans/warp_affine/warp_affine.rst b/doc/tutorials/imgproc/imgtrans/warp_affine/warp_affine.rst new file mode 100644 index 0000000..b4c75d5 --- /dev/null +++ b/doc/tutorials/imgproc/imgtrans/warp_affine/warp_affine.rst @@ -0,0 +1,117 @@ +.. _warp_affine: + +Affine Transformations +********************** + + +Goal +==== + +In this tutorial you will learn how to: + +a. Use the OpenCV function :warp_affine:`warpAffine <>` to implement simple remapping routines. +b. Use the OpenCV function :get_rotation_matrix_2d:`getRotationMatrix2D <>` to obtain a :math:`2 \times 3` rotation matrix + + +Theory +====== + +Code +==== + +.. code-block:: cpp + + #include "opencv2/highgui/highgui.hpp" + #include "opencv2/imgproc/imgproc.hpp" + #include + #include + + using namespace cv; + using namespace std; + + /// Global variables + char* source_window = "Source image"; + char* warp_window = "Warp"; + char* warp_rotate_window = "Warp + Rotate"; + + /** @function main */ + int main( int argc, char** argv ) + { + Point2f srcTri[3]; + Point2f dstTri[3]; + + Mat rot_mat( 2, 3, CV_32FC1 ); + Mat warp_mat( 2, 3, CV_32FC1 ); + Mat src, warp_dst, warp_rotate_dst; + + /// Load the image + src = imread( argv[1], 1 ); + + /// Set the dst image the same type and size as src + warp_dst = Mat::zeros( src.rows, src.cols, src.type() ); + + /// Set your 3 points to calculate the Affine Transform + srcTri[0] = Point2f( 0,0 ); + srcTri[1] = Point2f( src.cols - 1, 0 ); + srcTri[2] = Point2f( 0, src.rows - 1 ); + + dstTri[0] = Point2f( src.cols*0.0, src.rows*0.33 ); + dstTri[1] = Point2f( src.cols*0.85, src.rows*0.25 ); + dstTri[2] = Point2f( src.cols*0.15, src.rows*0.7 ); + + /// Get the Affine Transform + warp_mat = getAffineTransform( srcTri, dstTri ); + + /// Apply the Affine Transform just found to the src image + warpAffine( src, warp_dst, warp_mat, warp_dst.size() ); + + /** Rotating the image after Warp */ + + /// Compute a rotation matrix with respect to the center of the image + Point center = Point( warp_dst.cols/2, warp_dst.rows/2 ); + double angle = -50.0; + double scale = 0.6; + + /// Get the rotation matrix with the specifications above + rot_mat = getRotationMatrix2D( center, angle, scale ); + + /// Rotate the warped image + warpAffine( warp_dst, warp_rotate_dst, rot_mat, warp_dst.size() ); + + /// Show what you got + namedWindow( source_window, CV_WINDOW_AUTOSIZE ); + imshow( source_window, src ); + + namedWindow( warp_window, CV_WINDOW_AUTOSIZE ); + imshow( warp_window, warp_dst ); + + namedWindow( warp_rotate_window, CV_WINDOW_AUTOSIZE ); + imshow( warp_rotate_window, warp_rotate_dst ); + + /// Wait until user exits the program + waitKey(0); + + return 0; + } + +Explanation +=========== + +Result +====== + +.. image:: images/Warp_Affine_Tutorial_Original_Image.jpg + :alt: Original image + :width: 250pt + :align: center + +.. image:: images/Warp_Affine_Tutorial_Result_Warp.jpg + :alt: Original image + :width: 250pt + :align: center + +.. image:: images/Warp_Affine_Tutorial_Result_Warp_Rotate.jpg + :alt: Original image + :width: 250pt + :align: center + diff --git a/doc/tutorials/imgproc/table_of_content_imgproc/images/imgtrans/Remap_Tutorial_Cover.jpg b/doc/tutorials/imgproc/table_of_content_imgproc/images/imgtrans/Remap_Tutorial_Cover.jpg new file mode 100644 index 0000000..74d5982 Binary files /dev/null and b/doc/tutorials/imgproc/table_of_content_imgproc/images/imgtrans/Remap_Tutorial_Cover.jpg differ diff --git a/doc/tutorials/imgproc/table_of_content_imgproc/images/imgtrans/Warp_Affine_Tutorial_Cover.jpg b/doc/tutorials/imgproc/table_of_content_imgproc/images/imgtrans/Warp_Affine_Tutorial_Cover.jpg new file mode 100644 index 0000000..611bfd6 Binary files /dev/null and b/doc/tutorials/imgproc/table_of_content_imgproc/images/imgtrans/Warp_Affine_Tutorial_Cover.jpg differ diff --git a/doc/tutorials/imgproc/table_of_content_imgproc/table_of_content_imgproc.rst b/doc/tutorials/imgproc/table_of_content_imgproc/table_of_content_imgproc.rst index 363fa84..21a2706 100644 --- a/doc/tutorials/imgproc/table_of_content_imgproc/table_of_content_imgproc.rst +++ b/doc/tutorials/imgproc/table_of_content_imgproc/table_of_content_imgproc.rst @@ -239,3 +239,38 @@ In this section you will learn about the image processing (manipulation) functio :height: 100pt :width: 100pt +* :ref:`remap` + + ===================== ============================================== + |Remap| *Title:* **Remapping** + + *Compatibility:* > OpenCV 2.0 + + *Author:* |Author_AnaH| + + Where we learn how to manipulate pixels locations + + ===================== ============================================== + + .. |Remap| image:: images/imgtrans/Remap_Tutorial_Cover.jpg + :height: 100pt + :width: 100pt + + +* :ref:`warp_affine` + + ===================== ============================================== + |WarpAffine| *Title:* **Affine Transforms** + + *Compatibility:* > OpenCV 2.0 + + *Author:* |Author_AnaH| + + Where we learn how to rotate, translate and scale our images + + ===================== ============================================== + + .. |WarpAffine| image:: images/imgtrans/Warp_Affine_Tutorial_Cover.jpg + :height: 100pt + :width: 100pt +