不,你需要将矩阵相乘以实现级联效果。我不会详细解释数学,但将变换应用到坐标上是通过执行矩阵乘法来完成的。如果你想知道为什么这样做,请参考这篇关于级联矩阵变换的
优秀维基百科文章。给定坐标
X
和变换矩阵
M
,可以通过以下方式获得输出坐标
Y
:
Y = M*X
在这里,我使用*
来指代矩阵乘法,而非逐元素乘法。你所拥有的是一对转换矩阵,这些矩阵从img1
到img2
,然后再从img2
到img3
。你需要执行两次操作。因此,为了从img1
到img2
(其中X
属于img1
的坐标空间),我们可以采用以下方法(假设我们正在使用仿射矩阵):
Y1 = M1*X
接下来,从img2
到img3
,我们有:
Y2 = M2*Y1 --> Y2 = M2*M1*X --> Y2 = M3*X --> M3 = M2*M1
因此,为了获得所需的链式效应,您需要创建一个新矩阵,使
M2
乘以
M1
。与
H2
和
H1
相同。
因此,定义一个新矩阵如下:
cv::Mat M3 = M2*M1;
同样的,对于你的投影矩阵,你可以执行以下操作:
cv::Mat H3 = H2*H1
然而,
estimateRigidTransform
(在您的情况下输出为
M
)会给出一个
2 x 3
矩阵。一个技巧是增加该矩阵的维度,使其变为3 x 3,其中我们添加一行,除了最后一个元素设置为1之外,其余都是0。因此,您将得到最后一行,使其成为
[0 0 1]
。您需要对两个矩阵都这样做,然后将它们相乘,再将前两行提取到一个新矩阵中,以输入到
warpAffine
中。因此,请执行以下操作:
// Create padded matrix for M1
cv::Mat M1new = cv::Mat(3,3,M1.type());
M1new.at<double>(0,0) = M1.at<double>(0,0);
M1new.at<double>(0,1) = M1.at<double>(0,1);
M1new.at<double>(0,2) = M1.at<double>(0,2);
M1new.at<double>(1,0) = M1.at<double>(1,0);
M1new.at<double>(1,1) = M1.at<double>(1,1);
M1new.at<double>(1,2) = M1.at<double>(1,2);
M1new.at<double>(2,0) = 0.0;
M1new.at<double>(2,1) = 0.0;
M1new.at<double>(2,2) = 1.0;
// Create padded matrix for M2
cv::Mat M2new = cv::Mat(3,3,M2.type());
M2new.at<double>(0,0) = M2.at<double>(0,0);
M2new.at<double>(0,1) = M2.at<double>(0,1);
M2new.at<double>(0,2) = M2.at<double>(0,2);
M2new.at<double>(1,0) = M2.at<double>(1,0);
M2new.at<double>(1,1) = M2.at<double>(1,1);
M2new.at<double>(1,2) = M2.at<double>(1,2);
M2new.at<double>(2,0) = 0.0;
M2new.at<double>(2,1) = 0.0;
M2new.at<double>(2,2) = 1.0;
// Multiply the two matrices together
cv::Mat M3temp = M2new*M1new;
// Extract out relevant rows and place into M3
cv::Mat M3 = cv::Mat(2, 3, M3temp.type());
M3.at<double>(0,0) = M3temp.at<double>(0,0);
M3.at<double>(0,1) = M3temp.at<double>(0,1);
M3.at<double>(0,2) = M3temp.at<double>(0,2);
M3.at<double>(1,0) = M3temp.at<double>(1,0);
M3.at<double>(1,1) = M3temp.at<double>(1,1);
M3.at<double>(1,2) = M3temp.at<double>(1,2);
处理
cv::Mat
和
*
运算符时,
它被重载以执行特定的矩阵乘法操作。
然后可以将
M3
和
H3
分别用于
warpAffine
和
warpPerspective
。
希望能对您有所帮助!
H3 = H1*H2;
。但是仿射矩阵是一个2x3矩阵,我不能简单地将两个仿射矩阵相乘,我不能这样做:M3 = M1*M2;
。那么我该如何对仿射变换-M进行操作呢? - AlexestimateRigidTransform();
给我一个 2x3 的矩阵,而estimateAffine3D();
给我一个 3x4 的矩阵。 - AlexestimateRigidTransform
。对于之前没有发现的问题,我感到抱歉。但是,estimateAffine3D
处理的是一个三维点云到另一个三维点云之间的转换。你不能用它来扭曲图像,因为图像本质上是一个二维坐标空间。 - rayryengH2*H1
和M2*M1
。 - rayryeng