2

我对如何使用 OpenCVfindHomography方法来计算最佳变换感到困惑。

我的使用方式如下:

cv::Mat h = cv::findHomography(src, dst, CV_RANSAC, 5.f);

无论我运行多少次,我都会得到相同的转换矩阵。我认为 RANSAC 应该随机选择一个点子集来进行拟合,那为什么每次都返回相同的变换矩阵呢?它与一些随机数初始化有关吗?我怎样才能使这种行为实际上是随机的?

其次,如何调整此设置中的 RANSAC 迭代次数?通常迭代次数基于内部比率和类似的东西。

4

2 回答 2

3

我认为 RANSAC 应该随机选择一个点子集来进行拟合,那为什么每次都返回相同的变换矩阵呢?

RANSAC反复选择点的子集,然后根据它们拟合模型,然后检查数据集中有多少数据点是给定拟合模型的内点。一旦完成了很多次,它就会选择具有最多内点的拟合模型,并将模型重新拟合到这些内点。

对于任何给定的数据集、变量模型参数集和构成内点的规则,将存在一个或多个(但通常恰好是一个)最大可能的“内点”集。例如,给定这个数据集(来自维基百科的图片):

显示一条直线的图,周围散布着一堆随机异常值

...然后通过对异常值的某种合理定义,任何线性模型可以具有的最大可能的内部值集是下面蓝色的那个:

与以前相同的图像,但内点为蓝色,异常点为红色,以及通过内点的最佳拟合蓝线

让我们称上面的蓝点集 - 最大可能的内点集 - I

如果您随机选择少量点(例如两个或三个)并通过它们绘制一条最适合的线,那么直观地希望它只需要您尝试几次,直到您遇到迭代,其中:

  • 您选择的所有随机选择的点都来自I,所以
  • 通过这些点的最佳拟合线大致等于上图中的最佳拟合线,因此
  • 在该迭代中发现的一组内点正是I

从那次迭代开始,所有进一步的迭代都是浪费,不可能进一步改进模型(尽管 RANSAC 无法知道这一点,因为它不能神奇地知道何时找到最大的内点集)。

如果相对于数据集的大小,您有足够多的迭代次数,并且有足够大比例的数据集是内点,那么您最终将找到最大的内点集,每次您都有接近 100% 的机会运行 RANSAC。因此,RANSAC 将(几乎)总是输出完全相同的模型。

这是一件好事!通常,您希望RANSAC 找到绝对最大的内点集,并且不想满足于任何更少的东西。如果在这种情况下每次运行 RANSAC 时都得到不同的结果,则表明您希望增加迭代次数。

(当然,在上面的例子中,我们谈论的是试图通过二维平面中的点拟合一条线,这不是什么findHomography,但原理是一样的;通常仍然会有一个最大的内点集最终RANSAC会找到它。)

我怎样才能使这种行为实际上是随机的?

减少迭代次数 ( maxIters) 以便 RANSAC 有时无法找到最大内点集。

但是除了纯粹的求知欲之外,通常没有理由这样做。您基本上会故意告诉 RANSAC 输出劣质模型。

于 2019-03-31T14:10:33.533 回答
3

findHomography已经为您提供了最佳转换。真正的问题是关于最佳的含义。

例如,RANSAC您将拥有具有最大内点数的模型,而LMEDS您将拥有具有最小中值误差的模型。

您可以通过以下方式修改默认行为:

  • RANSAC通过设置更改迭代次数maxIters(允许的最大次数为 2000)
  • 减少(增加)ransacReprojThreshold用于验证异常值和异常值(通常在 1 到 10 之间)的值。

关于你的问题。

无论我运行多少次,我都会得到相同的转换矩阵。

可能您的观点已经足够好,以至于您始终可以找到最佳模型。

我认为 RANSAC 应该随机选择一个点子集来进行拟合

RANSAC(RANdom SAmple Consensus)首先选择一个随机子集,检查用这些点构建的模型是否足够好。如果不是,它选择另一个随机子集。

我怎样才能使这种行为实际上是随机的?

我无法想象这会有用的场景,但您可以从srcand中随机选择 4 对点dst,然后使用getPerspectiveTransform。除非你的观点是完美的,否则你会为每个子集得到一个不同的矩阵。

于 2015-08-16T16:01:35.473 回答