Matlab中基础矩阵的计算结果不同。

5

我正在实现立体匹配算法,作为预处理,我尝试在没有相机标定的情况下进行图像校正。 我使用surf检测器检测和匹配图像上的特征,并尝试对齐它们。之后,我找到所有匹配点,并使用以下函数删除不在极线上的点:

[fMatrix, epipolarInliers, status] = estimateFundamentalMatrix(...
  matchedPoints1, matchedPoints2, 'Method', 'RANSAC', ...
  'NumTrials', 10000, 'DistanceThreshold', 0.1, 'Confidence', 99.99);

inlierPoints1 = matchedPoints1(epipolarInliers, :);
inlierPoints2 = matchedPoints2(epipolarInliers, :);

figure; showMatchedFeatures(I1, I2, inlierPoints1, inlierPoints2);
legend('Inlier points in I1', 'Inlier points in I2');

问题在于,如果我使用相同的数据运行此函数,仍然会得到不同的结果,在相同数据上每次运行都会导致结果偏差图中的差异。 预计匹配点仍然相同,但是内点在每次运行中都有所不同。 在此处您可以看到一些匹配结果不同的情况:

内点

更新:我认为这些差异是由RANSAC方法引起的,但是使用LMedS、MSAC,我仍然会在相同的数据上获得不同的结果。
3个回答

4
编辑:要说明的是,这只是一个部分回答,因为我只是解释了为什么使用这些拟合方法可以实现这一点,而不是如何改进输入关键点以避免从一开始就出现这个问题。正如其他答案所指出的那样,您的关键点匹配分布存在问题,并且有方法可以在关键点检测阶段解决这个问题。但是,同样的输入可能会导致在重复执行相同的关键点对估计基础矩阵的estimateFundamentalMatrix时产生不同的结果,原因如下(再次强调,这并不能提供改进关键点以解决此问题的可靠建议)。
重复执行产生不同结果的原因与RANSAC方法(以及LMedS和MSAC)有关。它们都利用随机抽样,因此具有非确定性。除了Norm8Point之外的所有方法都通过每次随机选取8对点(最多NumTrials次)进行操作。
首先,请注意,对于相同的输入,您获得的不同结果并不是同样适当的(它们将没有相同的残差),但是搜索空间很容易导致任何这样的最小值,因为优化算法不是确定性的。正如其他答案正确地建议的那样,改进您的关键点,这将不是一个问题,但是以下是鲁棒拟合方法可以做到这一点以及修改其行为的一些方法。
请注意'NumTrials'选项的文档(添加注释:更改此选项并不是解决方案,但这确实解释了行为):

'NumTrials' — 查找异常值的随机试验次数 500(默认) | 整数

查找异常值的随机试验次数,指定为由“NumTrials”和整数值组成的逗号分隔对。当您将Method参数设置为LMedS、RANSAC、MSAC或LTS时,此参数适用。

MSAC(M-estimator SAmple Consensus)是改进的RANSAC(RANdom SAmple Consensus)。 LMedS的确定性算法具有指数复杂度,因此实际上需要随机抽样。
在您决定使用Norm8Point之前,请记住,该方法假设没有异常值,因此对错误匹配不具有鲁棒性。尝试使用更多的试验来稳定其他方法(编辑:我是说,而不是切换到Norm8Point,但如果您能够在算法中备份,则将输入-关键点作为首要攻击线路)。此外,为了重置随机数生成器,您可以在每次调用estimateFundamentalMatrix之前执行rng('default')。但是,请注意,虽然这将强制每次运行相同的答案,但改进关键点分布通常是更好的解决方案。

那么有没有办法使它确定性的呢? - Martin Ch
有一种愚蠢的方法,特别是在C++中,但你需要修改源代码。伪随机生成器在给定相同种子的情况下总是产生相同的序列。因此,您不是使用随机数初始化随机生成器,而是使用一个预定义的数字。 - old-ufo
2
@old-ufo 很好的观点。如果生成器是系统范围内的生成器,你可以在每次运行前执行 rnd('default') - chappjc
是的,我可以在Matlab中修改随机生成器(设置自己的种子),但我怎么知道哪个随机数是“好”的,以获得最佳结果呢? - Martin Ch
3
默认情况下是使用种子为0的Mersenne Twister作为生成器,这很好。不要试图通过更改生成器来获得更好的结果,而是通过增加“NumTrials”的数量来实现。要重置生成器,只需在每次调用“estimateFundamentalMatrix”之前执行“rnd('default')”。函数“estimateFundamentalMatrix>generateRandomIndices”使用系统范围内的生成器,所以这应该可以工作。 - chappjc
显示剩余2条评论

3

我知道你的回答可能已经太晚了,但我想它对将来某个人会有用。实际上,你的情况存在两个问题:

  • 特征位置退化,即特征位置大多集中在一个地方(比如你身上:P),而没有在整个图像中广泛分布。

  • 这些匹配点基本处于同一平面上。我知道你会争辩说你的身体不是平面的,但与房间的深度相比,它差不多是。

从数学上讲,这意味着您正在从平面表面提取E(或F),而这总是具有无限的解决方案。为了解决这个问题,我建议对任何两个提取的SURF特征之间的距离使用一些约束条件,即用于匹配的任何两个SURF特征之间应至少相隔40或100个像素(取决于图像的分辨率)。


@jhegedus 这与答案的不确定性有什么关系?同样的输入产生不同的输出是因为随机抽样。结果不稳定是一个不同的问题,从这个角度来看,这个答案是有用的,但它不会改变你最终可能得到不同的关键点匹配的事实。OP并没有意识到这一点。请评论一下我的答案为什么是不正确的。问题不是“我如何获得最佳的关键点匹配”,而是“为什么我对于相同的数据每次都得到不同的结果”。 - chappjc
是的,多个有效答案的存在使得鲁棒拟合方法能够收敛于不同的解决方案,但即使在使用相同输入进行重复运行时,这种情况发生的原因是由于随机抽样。回答中的建议有助于理解为什么这个特定问题是不稳定的,我完全同意。OP需要理解这两个问题,但想知道为什么estimateFundamentalMatrix是不确定的。 - chappjc
很明显,由于RANSAC的随机性,存在差异。不明显的是为什么和何时这些差异是显著的。正如楼主所说,“我认为差异是由RANSAC引起的”,因为他知道RANSAC是随机的。所有知道该首字母缩写代表什么的人都知道它是随机的。因此,问题并不在于解释RANSAC是随机的,而在于解释为什么这些差异是显著的。这确实是一个非常困难的问题! - jhegedus
@jhegedus 如果您阅读该引用的其余部分,就会清楚地知道OP明显不知道LMedS和MSAC也是这样工作的。 仅供参考,从一般的理解角度来看,我认为这个答案比我的更好,但我认为我没有误导到需要获得负票......就这些。 - chappjc
@jhegedus 我认为 OP 并不知道有任何差别,而不仅仅是显著差别。没有提到差异的大小。他只是说有一个差别。因此,它似乎是一种琐事问题(例如,这怎么可能?)而不是要求一般指导以改善计算出的单应性的稳定性。对我来说,如果真的存在问题,更明显的是改进输入(关键点)是解决问题的首选方式,但再次没有迹象表明答案完全不正确。 - chappjc
显示剩余3条评论

2
另一种提高SURF特征的方法是将'detectSURFFeatures(rgb2gray(I1),'NumOctaves',5);'中的'NumOctaves'设置为更大的值。

我也遇到了同样的问题,这个方法有所帮助(但只是一点点)。


好的建议,但我要指出,无论你如何调整特征检测器和提取器,最终可能会出现错误的场景(也许是不可能的)在视频流中,并引起问题。在这种情况下,仍然有必要确保可重复的结果...这对于任何使用随机采样的方法来说都是一个挑战 :) 这就是我理解这个问题的方式。+1 无论如何。希望我的原始答案没有过于误导。干杯。 - chappjc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接