OpenCV estimateRigidTransform()

时间:2017-06-20 06:20:35

标签: c++ opencv math

在阅读了几篇关于将2D点从一个图像转换为另一个图像的帖子后,estimateRigidTransform()似乎是推荐。我试图使用它。我修改了源代码(更改RANSAC参数,因为它的硬编码和硬编码参数不是很好)(此函数的源代码在lkpyramid.cpp)。我已阅读了RANSAC的工作原理,并尝试了解estimateRigidTransform()中的步骤。

// choose random 3 non-complanar points from A & B
...
// additional check for non-complanar vectors
a[0] = pA[idx[0]];
a[1] = pA[idx[1]];
a[2] = pA[idx[2]];

b[0] = pB[idx[0]];
b[1] = pB[idx[1]];
b[2] = pB[idx[2]];

double dax1 = a[1].x - a[0].x, day1 = a[1].y - a[0].y;
double dax2 = a[2].x - a[0].x, day2 = a[2].y - a[0].y;
double dbx1 = b[1].x - b[0].x, dby1 = b[1].y - b[0].y;
double dbx2 = b[2].x - b[0].x, dby2 = b[2].y - b[0].y;
const double eps = 0.01;

if( fabs(dax1*day2 - day1*dax2) < eps*std::sqrt(dax1*dax1+day1*day1)*std::sqrt(dax2*dax2+day2*day2) ||
    fabs(dbx1*dby2 - dby1*dbx2) < eps*std::sqrt(dbx1*dbx1+dby1*dby1)*std::sqrt(dbx2*dbx2+dby2*dby2) )
    continue;

是否使用非共面向量是一个错字?我的意思是2D点都在同一个平面上吗?

我的第二个问题是if条件在做什么?我知道如果点是共线的,左侧(给出三角形乘以2的区域)将为零或接近零,而右侧是三角形的两侧长度的乘法。

1 个答案:

答案 0 :(得分:1)

共线性保留在仿射变换中(例如您可能正在估计的变换),但此变换也会计算视点旋转的变化(就像您在3d世界中旋转对象一样)。但是,这些点也将是共线的,因此对于算法而言,它可能没有唯一的解决方案。看看图片:

test

想象在第一幅图像的第一行中选择每个黑色方块的3个中心点。然后将其映射到下一个图像中的相同中心。它可以生成到该解决方案的映射,但也可以映射到第一个解决方案的缩放版本。第三个可能会发生同样的情况,只是这次可能会映射到第一个的缩小版本(没有任何其他更改)。但是,如果这些点不共线,例如3个角点中心,则会找到唯一的映射。

我希望这可以帮助你澄清你的疑虑。如果没有,请发表评论