如何从单个组件创建 2D 透视变换矩阵?

Vin*_*ean 3 opencv transformation affinetransform perspective

我正在尝试从单个组件(如平移、旋转、缩放、剪切)创建一个 2D 透视变换矩阵。但最终矩阵并没有产生如下图所示的真实透视效果。我想我在为创建矩阵而编写的代码中缺少一些组件。有人可以帮我在下面的函数中添加缺少的组件及其公式吗?我的代码使用了 opencv 库

在此处输入图片说明

cv::Mat getPerspMatrix2D( double rz, double s, double tx, double ty ,double shx, double shy)
{

cv::Mat R = (cv::Mat_<double>(3,3) <<
        cos(rz), -sin(rz), 0,
        sin(rz), cos(rz), 0,
        0, 0, 1);

cv::Mat S = (cv::Mat_<double>(3,3) <<
        s, 0, 0,
        0, s, 0,
        0, 0, 1);


cv::Mat Sh = (cv::Mat_<double>(3,3) <<
        1, shx, 0,
        shy, 1, 0,
        0, 0, 1);


cv::Mat T = (cv::Mat_<double>(3,3) <<
        1, 0, tx,
        0, 1, ty,
        0, 0, 1);

return T * Sh * S * R;
}
Run Code Online (Sandbox Code Playgroud)

r2d*_*2d2 5

关键字是单应8DOF。取自12,存在两个用于透视变换的系数。但是它需要第二步来计算它。我不熟悉 OpenCV,但我希望以一种基本的方式来回答你的问题;-)

第1步

你可以想象 lx 描述了 x 轴上的一个消失点。图像显示 a31=lx=1。lx=100 是较少的变换。对于 lx=0,位置无限远意味着没有透视变换 = 单位矩阵。

     [1  0  0] 
PL = [0  1  0] 
     [lx ly 1]

lx/ly are perspective foreshortening parameters
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

第2步

当您应用右手矩阵乘法 P x [u; v; 1] 你会发现结果中的最后一个值有时不是 1。对于仿射变换,透视投影总是 1,而不是。在第二步中,结果被缩放以使最后一个系数为 1。这是效果的一部分。

在此处输入图片说明

您的示例图片

 Image' = P4 x P3 x P2 x P1 x Image
Run Code Online (Sandbox Code Playgroud)
  1. 我会将蓝色矩形的中心转换为原点tx=-w/2ty=-h/2= P1。
  2. 应用投影投影ly = h(使两侧成一定角度)
  3. 最终翻译回来所有点都位于一个象限
  4. 最终缩放到所需的大小

透视投影的步骤 2 可以在 2.) 之后或在最后完成。