The Perspective Transformation (Perspective transformation) is the projection of a picture into a new visual plane (viewing Plane), also known as a projection map (projective Mapping). The General transformation formula is:
U,v is the original picture to the left, corresponding to get the transformed picture coordinates x,y, which.
The transformation matrix can be divided into 4 parts, representing linear transformations, such as scaling,shearing and ratotion. For panning, resulting in perspective transformations. So it can be understood that affine is a special form of perspective transformation. A picture after a perspective transformation is usually not a parallelogram (unless the mapped visual plane is parallel to the original plane).
Before you rewrite the transformation formula, you can get:
Therefore, we can find the transformation formula by a few points corresponding to the transformation. Conversely, a particular transformation formula can also be transformed by a new image. Simply look at the transformation of a square to a quadrilateral:
The 4 sets of corresponding points of the transformation can be expressed as:
According to the transformation formula:
Define several auxiliary variables:
All for 0 o'clock the transformation plane is parallel to the original, and can be obtained:
Not for 0 o'clock, get:
The transformed matrix can transform a square to a quadrilateral. Conversely, the quadrilateral transformation to the square is the same. So we can transform any quadrilateral to another quadrilateral by two transformations: quadrilateral transformation to square + square transformation to quadrilateral.
Read a piece of code:
[cpp] View Plain copy Perspectivetransform::P erspectivetransform (float ina11, float inA21, float inA31, float ina12, float ina22, float ina32, float inA13, float inA23, &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;FLOAT&NBSP;INA33) : a11 (inA11), a12 (inA12 ), a13 (inA13), a21 (inA21), a22 (inA22), a23 (inA23), a31 (inA31), a32 (inA32), a33 (inA33) {} perspectivetransform Perspectivetransform::quadrilateraltoquadrilateral (FLOAT&NBSP;X0,&NBSP;FLOAT&NBSP;Y0,&NBSP;FLOAT&NBSP;X1, float y1, float x2, float y2, float x3, float y3, float x0p, float y0p, float x1p, float y1p, float x2p, float y2p, float x3p, float y3p) { Perspectivetransform qtos = perspectivetransform::quadrilateraltosquare (X0,&NBSP;Y0,&NBSP;X1, &NBSP;Y1,&NBSP;X2,&NBSP;Y2,&NBSP;X3,&NBSP;Y3); perspectivetransform stoq = perspectivetransform::squaretoquadrilateral (x0p, y0p, x1p, y1p, x2p, y2p, x3p, y3p); return stoq.times (QToS); } perspectivetransform perspectivetransform::squaretoquadrilateral (float x0, float y0, float x1, float y1, float x2, &NBSP;FLOAT&NBSP;Y2,&NBSP;FLOAT&NBSP;X3,&NBSP;FLOAT&NBSP;Y3) { float dx3 = x0 - x1 + x2 - x3; float dy3 = y0 - y1 + y2 - y3; if (dx3 == 0.0f && dy3 == 0.0f) { perspectivetransform result ( Perspectivetransform (x1 - x0, x2 - x1, x0, y1 - y0, y2 - y1, y0, 0.0f, 0.0f, 1.0f)); return result; } else { float dx1 = x1 - x2; float dx2 = x3 - x2; float dy1 = y1 - y2; float dy2 = y3 - y2; float denominator = dx1 * dy2 - dx2 * dy1; float a13 = (dx3 &NBSP;*&NBSP;DY2&NBSP;-&NBSP;DX2&NBSP;*&NBSP;DY3) / denominator; float a23 = (dx1 * dy3 - dx3 * dy1) / denominator; perspectivetransform result (Perspectivetransform (x1 - x0 + a13 * x1, x3 - x0 + a23 * x3, x0, y1 - y0 + a13 * y1, y3 - y0 + a23 * y3 , y0, a13, a23, 1.0f)); return result; } } Perspectivetransform perspectivetransform::quadrilateraltosquare (float x0, float y0, float x1, float y1, float x2, &NBSP;FLOAT&NBSP;Y2,&NBSP;FLOAT&NBSP;X3,&NBSP;FLOAT&NBSP;Y3) { // Here, the adjoint serves as the inverse: return Squaretoquadrilateral (X0, y0, x1, y1, x2, y2, x3, y3). BuildAdjoint (); } perspectivetransform perspectivetransform::buildadjoint () { // adjoint is the transpose of the cofactor matrix: perspectivetransform result (Perspectivetransform (a22 * a33 - A23 * a32, a23 * a31 - a21 * a33, a21 * a32 - a22 * a31, a13 * a32 - a12 * a33, a11 * a33 - a13 * a31, a12 * a31 - a11 * a32, a12 * a23 - a13 * a22, a13 * a21 - a11 * a23, a11 * a22 &NBSP;-&NBSP;A12&NBSP;*&NBSP;A21); return result; } PerspectivetranSform perspectivetransform::times (perspectivetransform other) { Perspectivetransform result (Perspectivetransform (a11 * other.a11 + a21 * other.a12 + a31 * other.a13, a11 * other.a21 + a21 * other.a22 + a31 * other.a23, a11 * other.a31 + a21 * other.a32 + a31 * other.a33, a12 * other.a11 + a22 * other.a12 + a32 * other.a13, a12 * other.a21 + a22 * other.a22 + a32 * other.a23, a12 * other.a31 + a22 * other.a32 + a32 * other.a33, a13 * other.a11 + a23 * other.a12 + a33 * other.a13, a13 * other.a21 + a23 * other.a22 + a33 &Nbsp; * other.a23, a13 &NBSP;*&NBSP;OTHER.A31&NBSP;+&NBSP;A23&NBSP;*&NBSP;OTHER.A32&NBSP;+&NBSP;A33&NBSP;*&NBSP;OTHER.A33)); return result; } void perspectivetransform:: Transformpoints (vector<float> &points) { int max = Points.size (); for (int i = 0; i < max; i &NBSP;+=&NBSP;2) { float x = points[i]; float y = points[i + 1]; float denominator = a13 * x + a23 * y + a33; points[i] = (a11 * x + a21 * y + &NBSP;A31) / denominator; points[i + 1] = (a12 * x + &NBSP;A22&NBSP;*&NBSP;Y&NBSP;+&NBSP;A32) / denominator; } } Change the effect of a perspective picture back to a positive image:
[cpp] View Plain copy Int main () { mat img=imread (" Boy.png "); int img_height = img.rows; int img_width = img.cols; mat img_ Trans = mat::zeros (IMG_HEIGHT,IMG_WIDTH,CV_8UC3); Perspectivetransform tansform = perspectivetransform::quadrilateraltoquadrilateral ( 0,0, img_width-1,0, 0,img_height-1, img_width-1,img_height-1, 150,250, // top left 771,0, // top right 0,1023,// bottom left 650,1023 ); vector<float> ponits; for (int i=0;i (i); for (int j=0;j (img_width-1) | | y<0| | Y> (img_height-1)) continue; uchar* p = img.ptr<uchar> (y); t[j*3] = p[x*3]; t[j*3+1] = p[x*3+1]; t[j*3+2] = p[x*3+2]; } } imwrite ("Trans.png", Img_trans); return 0; }
In addition, the basic perspective transformation operation is also implemented in OpenCV, see next: "OpenCV" Perspective Transformation Perspective Transformation (cont.)
(reprint please indicate author and origin: Http://blog.csdn.net/xiaowei_cqu do not use for commercial use without permission)
from:http://blog.csdn.net/xiaowei_cqu/article/details/26471527