我知道将正方形变换成梯形是一种线性变换,可以使用投影矩阵完成,但我有点难以构建这个矩阵。
使用投影矩阵进行平移、缩放、旋转和剪切是简单明了的。是否有一个简单的投影矩阵可以将正方形变换为梯形呢?
我知道将正方形变换成梯形是一种线性变换,可以使用投影矩阵完成,但我有点难以构建这个矩阵。
使用投影矩阵进行平移、缩放、旋转和剪切是简单明了的。是否有一个简单的投影矩阵可以将正方形变换为梯形呢?
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
h9=1
(因为H
可以用8个参数表示),然后解决一个包含8个未知数的线性方程组中的8个方程。您可以在Elan Dubrofsky的论文第2节Homography Estimation by Elan Dubrofsky中找到类似的说明。另一个解释是David Austin的《使用射影几何矫正相机》2013年3月《美国数学学会特征专栏》。对于那些知识和时间有限,寻求快速且可靠解决方案的人们,Wii-interact项目中提供了一个工作良好且相当可靠的Java实现。
转换过程在单应性源文件中。它归结为构建和解决矩阵:
/**
* 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 矩阵包