方形到梯形

时间:2011-05-27 21:28:54

标签: matrix transform linear-algebra projection perspective

我知道将一个正方形转换为一个正方形是一个线性变换,并且可以使用投影矩阵来完成,但我在弄清楚如何构造矩阵时遇到了一些麻烦。

使用投影矩阵进行平移,缩放,旋转和剪切非常简单。是否有一个简单的投影矩阵将一个正方形转换为梯形?

3 个答案:

答案 0 :(得分:11)

a,b,c,d是2D正方形的四个角。

a,b,c,d用齐次坐标表示,因此它们是3x1矩阵。

alpha,beta,gamma,delta是2D梯形的四个角。

alpha,beta,gamma,delta以齐次坐标表示,因此它们是3x1矩阵。

H是您正在寻找的3x3矩阵,它也称为单应性

    h1 h2 h3
H = h4 h5 h6
    h7 h8 h9

H将a,b,c,d映射为alpha,beta,gamma,delta,因此您有以下四个方程式

alpha=H*a
beta=H*b
gamma=H*c
delta=H*d

假设您知道a,b,c,d和alpha,beta,gamma,delta,您可以为九个未知数h1,h2,h3,h4,h5,h6,h7,h8,h9求解前四个方程系统。

这里我刚刚描述了一个问题的“原始”解决方案,原则上可以解决;有关上述方法的详细说明,您可以看到例如此页http://www.corrmap.com/features/homography_transformation.php,其中h9=1(因为H只能用8个参数表示),然后求解线性系统八个未知数中的八个方程。您可以在论文的第2部分Homography Estimation by Elan Dubrofsky中找到类似的解释。

另一种解释是大卫·奥斯汀在2013 March issue of Feature Column from the AMS使用投射几何来纠正相机

上述方法及其缺点,在Richard Hartley和Andrew Zissermann的第二版计算机视觉中的多视图几何中的第四章“估计 - 二维投影变换”中进行了描述。还描述了不同的更好的算法;您可以查看此链接http://www.cse.iitd.ac.in/~suban/vision/geometry/node24.html,该链接似乎与同一本书相同。

您可以在本书Computer Vision: Models, Learning, and Inference by Simon J.D. Prince的第15.1.4节“投影变换模型”中找到对单应性的另一种解释。算法算法15.4:投影变换(单应性)的最大似然学习在他的Algorithms booklet中概述:问题通过非线性最小化来解决。

答案 1 :(得分:3)

也许你可以使用四边形?请在此处查看我的回答:

https://stackoverflow.com/a/12820877/202451

然后你可以完全控制每个点,并且可以轻松地制作任何四角形状。 :)

答案 2 :(得分:0)

具有最小依赖性的Java实现

对于那些知识和时间有限的人寻找快速而肮脏的解决方案,Wii-interact项目中有一个可靠且可靠的Java实现。

转化是在The Homography source file。它归结为构建和解决矩阵:

/**
* Please note that Dr. John Zelle assisted us in developing the code to
* handle the matrices involved in solving for the homography mapping.
* 
**/
Matrix A = new Matrix(new double[][]{
                {x1, y1, 1, 0,  0,  0, -xp1*x1, -xp1*y1},
                {0,  0,  0, x1, y1, 1, -yp1*x1, -yp1*y1},
                {x2, y2, 1, 0,  0,  0, -xp2*x2, -xp2*y2},
                {0,  0,  0, x2, y2, 1, -yp2*x2, -yp2*y2},
                {x3, y3, 1, 0,  0,  0, -xp3*x3, -xp3*y3},
                {0,  0,  0, x3, y3, 1, -yp3*x3, -yp3*y3},
                {x4, y4, 1, 0,  0,  0, -xp4*x4, -xp4*y4},
                {0,  0,  0, x4, y4, 1, -yp4*x4, -yp4*y4}
        });

        Matrix XP = new Matrix(new double[][]
                          {{xp1}, {yp1}, {xp2}, {yp2}, {xp3}, {yp3}, {xp4}, {yp4}});
        Matrix P = A.solve(XP);
        transformation = new Matrix(new double[][]{
                {P.get(0, 0), P.get(1, 0), P.get(2,0)},
                {P.get(3, 0), P.get(4, 0), P.get(5,0)},
                {P.get(6, 0), P.get(7, 0), 1}
        });

用法:以下方法进行最终转换:

public Point2D.Double transform(Point2D.Double point) {
    Matrix p = new Matrix(new double[][]{{point.getX()}, {point.getY()}, {1}});
    Matrix result = transformation.times(p);
    double z = result.get(2, 0);
    return new Point2D.Double(result.get(0, 0) / z, result.get(1, 0) / z);
}

Matrix类依赖来自JAMA: Java Matrix Package

许可证

  1. Wii-interact GNU GPL v3
  2. JAMA public domain