我是Open Cv的新手,我想要转换两个图像src和dst图像。我使用cv::estimateRigidTransform()
计算转换矩阵,然后使用cv::warpAffine()
从dst转换为src。当我将新的变换图像与src图像进行比较时,它几乎相同(变换),但是当我得到新变换图像和src图像的abs差异时,会有很多不同。我该怎么办,因为我的dst图像也有一些旋转和平移因子。这是我的代码
cv::Mat transformMat = cv::estimateRigidTransform(src, dst, true);
cv::Mat output;
cv::Size dsize = leftImageMat.size(); //This specifies the output image size--change needed
cv::warpAffine(src, output, transformMat, dsize);
Src Image
目标图片
输出图片
绝对差异图像
由于
答案 0 :(得分:4)
您对此过程存在一些误解。
方法 cv :: estimateRigidTransform 将两组对应点作为输入。然后求解方程组以找到变换矩阵。变换的输出将src点与dst点匹配(如果不可能完全匹配,则精确或紧密 - 例如浮点坐标)。
如果对两个图像应用estimateRigidTransform,OpenCV首先使用一些内部方法找到匹配的点对(参见opencv docs)。
然后cv :: warpAffine 根据给定的变换矩阵将src图像转换为dst。但任何(几乎任何)转变都是亏损操作。该算法必须估计一些数据,因为它们不可用。此过程称为插值,使用您计算未知值的已知信息。有关图像缩放的一些信息可以在wiki上找到。同样的规则适用于其他转换 - 旋转,倾斜,透视......显然这不适用于翻译。
鉴于您的测试图像,我猜测OpenCV将灯罩作为参考。从差异很明显,灯罩转换得最好。默认情况下,OpenCV使用线性插值进行变形,因为它是最快的方法。但您可以设置更多预付款方法以获得更好的结果 - 再次咨询opencv docs。
结论: 你得到的结果非常好,如果你记住,这是自动化过程的结果。如果想要更好的结果,则必须找到另一种选择相应点的方法。或者使用更好的插值方法。无论哪种方式,在变换之后,diff都不会为0.实际上不可能实现这一点,因为位图是离散的像素网格,因此总会有一些需要估计的间隙。