不,您需要将矩阵相乘才能获得级联效果。我不会讨论数学,但对坐标应用变换是执行矩阵乘法的问题。如果您想知道为什么会这样,我建议您参考good Wikipedia article on cascading matrix transformations。给定一个坐标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,我们添加一个额外的行,其中最后一个元素全部为 0 except,该元素设置为 1。因此,您将拥有最后一行,使其变为[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 和* 运算符时,it is overloaded to specifically perform matrix multiplication。
然后您可以将M3 和H3 分别用于warpAffine 和warpPerspective。
希望这会有所帮助!