Calculate a 2D homogeneous perspective transformation matrix from 4 points in MATLAB

前端 未结 2 850
伪装坚强ぢ
伪装坚强ぢ 2021-02-09 05:22

I\'ve got coordinates of 4 points in 2D that form a rectangle and their coordinates after a perspective transformation has been applied.

The perspective transfo

2条回答
  •  猫巷女王i
    2021-02-09 06:02

    OpenCV has a neat function that does this called getPerspectiveTransform. The source code for this function is available on github with this description:

    /* Calculates coefficients of perspective transformation
     * which maps (xi,yi) to (ui,vi), (i=1,2,3,4):
     *
     *      c00*xi + c01*yi + c02
     * ui = ---------------------
     *      c20*xi + c21*yi + c22
     *
     *      c10*xi + c11*yi + c12
     * vi = ---------------------
     *      c20*xi + c21*yi + c22
     *
     * Coefficients are calculated by solving linear system:
     * / x0 y0  1  0  0  0 -x0*u0 -y0*u0 \ /c00\ /u0\
     * | x1 y1  1  0  0  0 -x1*u1 -y1*u1 | |c01| |u1|
     * | x2 y2  1  0  0  0 -x2*u2 -y2*u2 | |c02| |u2|
     * | x3 y3  1  0  0  0 -x3*u3 -y3*u3 |.|c10|=|u3|,
     * |  0  0  0 x0 y0  1 -x0*v0 -y0*v0 | |c11| |v0|
     * |  0  0  0 x1 y1  1 -x1*v1 -y1*v1 | |c12| |v1|
     * |  0  0  0 x2 y2  1 -x2*v2 -y2*v2 | |c20| |v2|
     * \  0  0  0 x3 y3  1 -x3*v3 -y3*v3 / \c21/ \v3/
     *
     * where:
     *   cij - matrix coefficients, c22 = 1
     */
    

    This system of equations is smaller as it avoids solving for W and M33 (called c22 by OpenCV). So how does it work? The linear system can be recreated by the following steps:

    Start with the formulas for projection transformation:

         c00*xi + c01*yi + c02
    ui = ---------------------
         c20*xi + c21*yi + c22
    
         c10*xi + c11*yi + c12
    vi = ---------------------
         c20*xi + c21*yi + c22
    

    Multiply both sides with the denominator:

    (c20*xi + c21*yi + c22) * ui = c00*xi + c01*yi + c02
    (c20*xi + c21*yi + c22) * vi = c10*xi + c11*yi + c12
    

    Distribute ui and vi:

    c20*xi*ui + c21*yi*ui + c22*ui = c00*xi + c01*yi + c02
    c20*xi*vi + c21*yi*vi + c22*vi = c10*xi + c11*yi + c12
    

    Assume c22 = 1:

    c20*xi*ui + c21*yi*ui + ui = c00*xi + c01*yi + c02
    c20*xi*vi + c21*yi*vi + vi = c10*xi + c11*yi + c12
    

    Collect all cij on the left hand side:

    c00*xi + c01*yi + c02 - c20*xi*ui - c21*yi*ui = ui
    c10*xi + c11*yi + c12 - c20*xi*vi - c21*yi*vi = vi
    

    And finally convert to matrix form for four pairs of points:

    / x0 y0  1  0  0  0 -x0*u0 -y0*u0 \ /c00\ /u0\
    | x1 y1  1  0  0  0 -x1*u1 -y1*u1 | |c01| |u1|
    | x2 y2  1  0  0  0 -x2*u2 -y2*u2 | |c02| |u2|
    | x3 y3  1  0  0  0 -x3*u3 -y3*u3 |.|c10|=|u3|
    |  0  0  0 x0 y0  1 -x0*v0 -y0*v0 | |c11| |v0|
    |  0  0  0 x1 y1  1 -x1*v1 -y1*v1 | |c12| |v1|
    |  0  0  0 x2 y2  1 -x2*v2 -y2*v2 | |c20| |v2|
    \  0  0  0 x3 y3  1 -x3*v3 -y3*v3 / \c21/ \v3/
    

    This is now in the form of Ax=b and the solution can be obtained with x = A\b. Remember that c22 = 1.

提交回复
热议问题