5

我是 Open Cv 的新手,我想转换两个图像 src 和 dst image 。我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);

源图像

在此处输入图像描述

目的地图片

在此处输入图像描述

输出图像

在此处输入图像描述

绝对差异图像

在此处输入图像描述

谢谢

4

1 回答 1

5

你对这个过程有一些误解。

方法cv::estimateRigidTransform将两组对应点作为输入。然后求解一组方程以找到变换矩阵。转换的输出将 src 点与 dst 点匹配(精确或紧密,如果不可能精确匹配 - 例如浮点坐标)。

如果您在两个图像上应用estimateRigidTransform,OpenCV 首先使用一些内部方法找到匹配的点对(参见opencv 文档)。

cv::warpAffine然后根据给定的变换矩阵将 src 图像变换为 dst。但是任何(几乎所有)转换都是损失操作。该算法必须估计一些数据,因为它们不可用。这个过程称为插值,使用已知信息计算未知值。有关图像缩放的一些信息可以在wiki上找到。相同的规则适用于其他转换 - 旋转、倾斜、透视......显然这不适用于平移。

鉴于您的测试图像,我猜 OpenCV 将灯罩作为参考。从差异中可以清楚地看出,灯罩被改造得最好。默认情况下,OpenCV 使用线性插值进行翘曲,因为它是最快的方法。但是您可以设置更高级的方法以获得更好的结果 - 再次咨询opencv 文档

结论:你得到的结果很好,如果你记住,它是自动化过程的结果。如果您想要更好的结果,您将不得不找到另一种选择对应点的方法。或者使用更好的插值方法。无论哪种方式,在变换之后,diff 都不会为 0。这实际上是不可能实现的,因为位图是像素的离散网格,所以总会有一些差距,需要估计。

于 2013-05-31T12:32:36.113 回答