Matlab 中基本矩阵的不同结果

Mar*_* Ch 5 matlab surf disparity-mapping feature-detection matlab-cvst

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

[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');
Run Code Online (Sandbox Code Playgroud)

问题是,如果我使用相同的数据运行此函数,我仍然会得到不同的结果,导致每次运行相同数据时结果视差图存在差异。推测匹配点仍然相同,但内联点在每次运行中有所不同。在这里您可以看到一些匹配结果不同:

内联点

更新:我认为差异是由 RANSAC 方法引起的,但是使用 LMedS、MSAC,我仍然在相同的数据上得到不同的结果

cha*_*pjc 4

编辑:诚然,这只是部分答案,因为我只是解释为什么使用这些拟合方法甚至可以做到这一点,而不是如何改进输入关键点以从一开始就避免这个问题。正如其他答案中所述,关键点匹配的分布存在问题,并且有多种方法可以在关键点检测阶段解决该问题。但是,对于相同的关键点对重复执行,相同的输入可能会产生不同的结果,原因如下。(同样,这并没有为改进关键点以解决这个问题提供合理的建议)。estimateFundamentalMatrix

\n\n

重复执行结果不同的原因与RANSAC方法(以及LMedS和MSAC)有关它们都利用随机(随机)采样,因此是不确定的。Norm8Point除通过每次随机采样 8 对点(最多) 之外的所有方法进行操作NumTrials

\n\n

但首先请注意,相同输入得到的不同结果并不同样适合(它们不会具有相同的残差),但搜索空间很容易导致任何此类最小值,因为优化算法不是确定性的。正如其他答案正确地建议的那样,改进你的关键点,这不会成为问题,但这就是为什么稳健的拟合方法可以做到这一点以及一些修改其行为的方法。

\n\n

请注意该选项的文档'NumTrials'(添加注意:更改这不是解决方案,但这确实解释了该行为):

\n\n
\n

'NumTrials'\xe2\x80\x94 查找异常值的随机试验次数\n 500(默认)| 整数

\n\n

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

\n
\n\n

MSAC(M-estimator SAmple Consensus)是改进的 RANSAC(RANdom SAmple Consensus)。LMedS 的确定性算法具有指数复杂性,因此实际上需要随机采样。

\n\n

在决定使用Norm8Point(再次强调,不是解决方案)之前,请记住,此方法假设没有异常值,因此对错误匹配不稳健。尝试使用更多的试验来稳定其他方法(编辑:我的意思是,而不是切换到Norm8Point,但如果您能够备份您的算法,那么将输入 - 关键点 - 作为第一道攻击线)。另外,要重置随机数生成器,您可以rng('default')在每次调用 之前执行此操作estimateFundamentalMatrix。但再次请注意,虽然这将迫使每次运行得到相同的答案,但改善关键点分布通常是更好的解决方案。

\n

  • @MartinCh 默认是带有种子 0 的 Mersenne Twister,这很好。不要尝试通过更改生成器来获得更好的结果,而是通过增加“NumTrials”来获得更好的结果。要重置生成器,只需在每次调用“estimateFundamentalMatrix”之前执行“rnd('default')”即可。函数 `estimateFundamentalMatrix>generateRandomIndices` 使用系统范围的生成器,所以这应该可以工作。 (3认同)
  • @old-ufo 好点。如果生成器是系统范围的生成器,则可以在每次运行之前执行“rnd('default')”。 (2认同)