图像拼接细节与OpenCV

Image Stitching details with OpenCV

本文关键字:OpenCV 细节 图像拼接      更新时间:2023-10-16

我正在努力深入缝合。我正在使用cv::detail

我试着以为例

我大致了解缝合管线。

存在返回图形的函数CCD_ 2。我想知道它是如何计算这张图的。此外,在这种情况下,置信区间的定义是什么。

输出为DOT格式,示例图看起来像

graph matches_graph{
"15.jpg" -- "13.jpg"[label="Nm=75, Ni=50, C=1.63934"];
"15.jpg" -- "12.jpg"[label="Nm=47, Ni=28, C=1.26697"];
"15.jpg" -- "14.jpg"[label="Nm=149, Ni=117, C=2.22011"];
"11.jpg" -- "13.jpg"[label="Nm=71, Ni=52, C=1.77474"];
"11.jpg" -- "9.jpg"[label="Nm=46, Ni=37, C=1.69725"];
"11.jpg" -- "10.jpg"[label="Nm=87, Ni=73, C=2.14076"];
"9.jpg" -- "8.jpg"[label="Nm=122, Ni=99, C=2.21973"];
}

labelNmNi在这里是什么意思?官方文件似乎缺少这些细节。

这确实是一个非常有趣的问题。正如@hatboyzero所指出的,变量的含义相当简单:

  • Nm是匹配次数(在重叠区域,因此明显的异常值已经被删除)
  • Ni是在找到与Ransac的单应性后的内点数
  • C是两个图像匹配的置信度

匹配的背景

构建全景是通过在所有图像中找到兴趣点并为它们计算描述符来完成的。这些描述符,如SIFT、SURF和ORB,是为了检测图像的相同部分而开发的。它们只是一个中等维度的向量(通常为64或128个维度)。通过计算L2或两个描述符之间的一些其他距离,可以找到匹配。在一对图像中找到的匹配数量由术语Nm描述。

请注意,到目前为止,匹配仅通过兴趣点周围图像区域的外观来完成。通常情况下,许多匹配都是完全错误的。这可能是因为描述符看起来是一样的(想想:重复的对象,比如多窗口建筑上的窗台,或者树上的树叶),或者因为描述符太没有信息了。

常见的解决方案是添加几何约束:图像对是用同一台相机从同一位置拍摄的,因此在一张图像中靠近的点在另一张图像也必须靠近。更具体地说,所有的点都必须经历同样的转变。在全景图的情况下,相机围绕相机镜头系统的节点旋转,这种变换必须是2D单应性。

Ransac是找到最佳变换和与该变换一致的所有匹配的金标准算法。这些一致匹配的数量被称为Ni。Ransac的工作方法是在这种情况下随机选择4个匹配(见论文第3.1节),并将单应性拟合到这四个匹配。然后,计算所有可能的匹配中有多少匹配符合这种单应性。重复500次(见论文),最后取入口最多的模型。然后用所有的inlier重新计算模型。该算法的名称来自RANdom-SAmple共识:RanSaC。

置信度术语

我的问题是,关于这种神秘的自信。我很快就找到了计算的地方。

来自stitching/sources/matches.cpp:

// These coeffs are from paper M. Brown and D. Lowe. "Automatic Panoramic Image Stitching
// using Invariant Features"
matches_info.confidence = matches_info.num_inliers / (8 + 0.3 * matches_info.matches.size());
// Set zero confidence to remove matches between too close images, as they don't provide
// additional information anyway. The threshold was set experimentally.
matches_info.confidence = matches_info.confidence > 3. ? 0. : matches_info.confidence;

上述文件在第3.2节("图像匹配验证的概率模型")中有更多关于这意味着什么的细节。

读到这一节,有几件事很突出。

  1. 他们的模型中有很多变量(大部分是概率)。这些值是在没有任何理由的情况下在论文中定义的。以下是关键句子:

尽管在实践中我们已经选择了p0、p1、p(m=0)、p(m/1)和pmin的值,但原则上可以从数据中学习它们。

所以,这只是一个理论练习,因为参数是凭空提取出来的。请注意,原则上可以学习

  1. 本文在方程13中进行了置信度计算。如果读取正确,则意味着matches_info.confidence指示当其值大于1时两个图像之间的适当匹配。

  2. 当置信度高于3时,我看不出有任何理由取消比赛(将置信度设置为0)。这只是意味着很少有异常值。我认为程序员们认为,大量的匹配结果是异常的,这意味着图像有很大的重叠,但这并不是由背后的算法提供的。(简单地说,匹配是基于特征的外观。)

浏览一下在线可用的OpenCV源代码,我认为它们的意思如下:

  • Nm-成对匹配的数量
  • Ni-几何一致匹配数
  • C-置信度两张图像来自同一全景

我的假设基于OpenCV源代码2.4.2版本的modules/sitching/src/motion_estimators.cpp中matchesGraphAsString正文中的一个片段。即

        str << """ << name_src << "" -- "" << name_dst << """
            << "[label="Nm=" << pairwise_matches[pos].matches.size()
            << ", Ni=" << pairwise_matches[pos].num_inliers
            << ", C=" << pairwise_matches[pos].confidence << ""];n";

此外,我还在文档中查看详细信息::MatchesInfo,了解有关NiC术语的信息。