1Affine Transformations {#tutorial_warp_affine}
2======================
3
4Goal
5----
6
7In this tutorial you will learn how to:
8
9-  Use the OpenCV function @ref cv::warpAffine to implement simple remapping routines.
10-  Use the OpenCV function @ref cv::getRotationMatrix2D to obtain a \f$2 \times 3\f$ rotation matrix
11
12Theory
13------
14
15### What is an Affine Transformation?
16
17-#  It is any transformation that can be expressed in the form of a *matrix multiplication* (linear
18    transformation) followed by a *vector addition* (translation).
19-#  From the above, We can use an Affine Transformation to express:
20
21    -#  Rotations (linear transformation)
22    -#  Translations (vector addition)
23    -#  Scale operations (linear transformation)
24
25    you can see that, in essence, an Affine Transformation represents a **relation** between two
26    images.
27
28-#  The usual way to represent an Affine Transform is by using a \f$2 \times 3\f$ matrix.
29
30    \f[
31    A = \begin{bmatrix}
32        a_{00} & a_{01} \\
33        a_{10} & a_{11}
34        \end{bmatrix}_{2 \times 2}
35    B = \begin{bmatrix}
36        b_{00} \\
37        b_{10}
38        \end{bmatrix}_{2 \times 1}
39    \f]
40    \f[
41    M = \begin{bmatrix}
42        A & B
43        \end{bmatrix}
44    =
45   \begin{bmatrix}
46        a_{00} & a_{01} & b_{00} \\
47        a_{10} & a_{11} & b_{10}
48   \end{bmatrix}_{2 \times 3}
49   \f]
50
51    Considering that we want to transform a 2D vector \f$X = \begin{bmatrix}x \\ y\end{bmatrix}\f$ by
52    using \f$A\f$ and \f$B\f$, we can do it equivalently with:
53
54    \f$T = A \cdot \begin{bmatrix}x \\ y\end{bmatrix} + B\f$ or \f$T = M \cdot  [x, y, 1]^{T}\f$
55
56    \f[T =  \begin{bmatrix}
57        a_{00}x + a_{01}y + b_{00} \\
58        a_{10}x + a_{11}y + b_{10}
59        \end{bmatrix}\f]
60
61### How do we get an Affine Transformation?
62
63-#  Excellent question. We mentioned that an Affine Transformation is basically a **relation**
64    between two images. The information about this relation can come, roughly, in two ways:
65    -#  We know both \f$X\f$ and T and we also know that they are related. Then our job is to find \f$M\f$
66    -#  We know \f$M\f$ and \f$X\f$. To obtain \f$T\f$ we only need to apply \f$T = M \cdot X\f$. Our information
67        for \f$M\f$ may be explicit (i.e. have the 2-by-3 matrix) or it can come as a geometric relation
68        between points.
69
70-#  Let's explain a little bit better (b). Since \f$M\f$ relates 02 images, we can analyze the simplest
71    case in which it relates three points in both images. Look at the figure below:
72
73    ![](images/Warp_Affine_Tutorial_Theory_0.jpg)
74
75    the points 1, 2 and 3 (forming a triangle in image 1) are mapped into image 2, still forming a
76    triangle, but now they have changed notoriously. If we find the Affine Transformation with these
77    3 points (you can choose them as you like), then we can apply this found relation to the whole
78    pixels in the image.
79
80Code
81----
82
83-#  **What does this program do?**
84    -   Loads an image
85    -   Applies an Affine Transform to the image. This Transform is obtained from the relation
86        between three points. We use the function @ref cv::warpAffine for that purpose.
87    -   Applies a Rotation to the image after being transformed. This rotation is with respect to
88        the image center
89    -   Waits until the user exits the program
90
91-#  The tutorial code's is shown lines below. You can also download it from
92    [here](https://github.com/Itseez/opencv/tree/master/samples/cpp/tutorial_code/ImgTrans/Geometric_Transforms_Demo.cpp)
93    @include samples/cpp/tutorial_code/ImgTrans/Geometric_Transforms_Demo.cpp
94
95Explanation
96-----------
97
98-#  Declare some variables we will use, such as the matrices to store our results and 2 arrays of
99    points to store the 2D points that define our Affine Transform.
100    @code{.cpp}
101    Point2f srcTri[3];
102    Point2f dstTri[3];
103
104    Mat rot_mat( 2, 3, CV_32FC1 );
105    Mat warp_mat( 2, 3, CV_32FC1 );
106    Mat src, warp_dst, warp_rotate_dst;
107    @endcode
108-#  Load an image:
109    @code{.cpp}
110    src = imread( argv[1], 1 );
111    @endcode
112-#  Initialize the destination image as having the same size and type as the source:
113    @code{.cpp}
114    warp_dst = Mat::zeros( src.rows, src.cols, src.type() );
115    @endcode
116-#  **Affine Transform:** As we explained lines above, we need two sets of 3 points to derive the
117    affine transform relation. Take a look:
118    @code{.cpp}
119    srcTri[0] = Point2f( 0,0 );
120    srcTri[1] = Point2f( src.cols - 1, 0 );
121    srcTri[2] = Point2f( 0, src.rows - 1 );
122
123    dstTri[0] = Point2f( src.cols*0.0, src.rows*0.33 );
124    dstTri[1] = Point2f( src.cols*0.85, src.rows*0.25 );
125    dstTri[2] = Point2f( src.cols*0.15, src.rows*0.7 );
126    @endcode
127    You may want to draw the points to make a better idea of how they change. Their locations are
128    approximately the same as the ones depicted in the example figure (in the Theory section). You
129    may note that the size and orientation of the triangle defined by the 3 points change.
130
131-#  Armed with both sets of points, we calculate the Affine Transform by using OpenCV function @ref
132    cv::getAffineTransform :
133    @code{.cpp}
134    warp_mat = getAffineTransform( srcTri, dstTri );
135    @endcode
136    We get as an output a \f$2 \times 3\f$ matrix (in this case **warp_mat**)
137
138-#  We apply the Affine Transform just found to the src image
139    @code{.cpp}
140    warpAffine( src, warp_dst, warp_mat, warp_dst.size() );
141    @endcode
142    with the following arguments:
143
144    -   **src**: Input image
145    -   **warp_dst**: Output image
146    -   **warp_mat**: Affine transform
147    -   **warp_dst.size()**: The desired size of the output image
148
149    We just got our first transformed image! We will display it in one bit. Before that, we also
150    want to rotate it...
151
152-#  **Rotate:** To rotate an image, we need to know two things:
153
154    -#  The center with respect to which the image will rotate
155    -#  The angle to be rotated. In OpenCV a positive angle is counter-clockwise
156    -#  *Optional:* A scale factor
157
158    We define these parameters with the following snippet:
159    @code{.cpp}
160    Point center = Point( warp_dst.cols/2, warp_dst.rows/2 );
161    double angle = -50.0;
162    double scale = 0.6;
163    @endcode
164-#  We generate the rotation matrix with the OpenCV function @ref cv::getRotationMatrix2D , which
165    returns a \f$2 \times 3\f$ matrix (in this case *rot_mat*)
166    @code{.cpp}
167    rot_mat = getRotationMatrix2D( center, angle, scale );
168    @endcode
169-#  We now apply the found rotation to the output of our previous Transformation.
170    @code{.cpp}
171    warpAffine( warp_dst, warp_rotate_dst, rot_mat, warp_dst.size() );
172    @endcode
173-#  Finally, we display our results in two windows plus the original image for good measure:
174    @code{.cpp}
175    namedWindow( source_window, WINDOW_AUTOSIZE );
176    imshow( source_window, src );
177
178    namedWindow( warp_window, WINDOW_AUTOSIZE );
179    imshow( warp_window, warp_dst );
180
181    namedWindow( warp_rotate_window, WINDOW_AUTOSIZE );
182    imshow( warp_rotate_window, warp_rotate_dst );
183    @endcode
184-#  We just have to wait until the user exits the program
185    @code{.cpp}
186    waitKey(0);
187    @endcode
188
189Result
190------
191
192-#  After compiling the code above, we can give it the path of an image as argument. For instance,
193    for a picture like:
194
195    ![](images/Warp_Affine_Tutorial_Original_Image.jpg)
196
197    after applying the first Affine Transform we obtain:
198
199    ![](images/Warp_Affine_Tutorial_Result_Warp.jpg)
200
201    and finally, after applying a negative rotation (remember negative means clockwise) and a scale
202    factor, we get:
203
204    ![](images/Warp_Affine_Tutorial_Result_Warp_Rotate.jpg)
205