我正在努力深入拼接。我正在使用cv::detail
。
我正在尝试关注this example:
我粗略地了解拼接管道。
有一个返回图形的函数matchesGraphAsString()
。我想知道它是如何计算这个图的。此外,在这种情况下,置信区间的定义是什么。
输出采用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"];
}
label
,Nm
和Ni
在这里是什么意思?官方文件似乎缺乏这些细节。
答案 0 :(得分:5)
这确实是一个非常有趣的问题。正如@hatboyzero指出的那样,变量的含义相当简单:
通过在所有图像中查找兴趣点并为其计算描述符来构建全景图。开发了这些描述符,如SIFT,SURF和ORB,以便可以检测到图像的相同部分。它们只是一个中等尺寸的矢量(典型的是64或128维)。通过计算L2或两个描述符之间的某个其他距离,可以找到匹配。一对图像中找到多少匹配由术语 Nm 描述。
请注意,到目前为止,匹配仅通过感兴趣点周围的图像区域的外观完成。通常,许多这些匹配都是完全错误的。这可能是因为描述符看起来相同(想想:像多窗口建筑物上的窗台一样重复的对象,或树上的叶子),或者因为描述符只是有点太缺乏信息。
常见的解决方案是添加几何约束:图像对是使用相同的相机从相同的位置拍摄的,因此在一个图像中靠近的点必须在另一个图像中接近。更具体地说,所有点必须经历相同的转换。在全景情况下,相机围绕相机镜头系统的节点旋转,这种转换必须是2D单应性。
Ransac 是找到最佳转换的金标准算法,以及与此转换一致的所有匹配。这些一致匹配的数量称为 Ni 。 Ransac通过在这种情况下随机选择4个匹配(参见论文第3.1节)并将单应性拟合到这四个匹配。然后,计算所有可能匹配的匹配数将与此单应性一致。重复500次(见论文),最后采用内部最多的模型。然后使用所有内点重新计算模型。该算法的名称来自RANdom SAmple Consensus: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;
mentioned paper 在第3.2节("图像匹配验证的概率模型")中有一些更详细的含义。
阅读本节有一些突出的事情。
虽然在实践中我们选择了p0,p1,p(m = 0),p(m = 1)和pmin的值,但原则上它们可以从数据中学习。
所以,这只是一个理论上的练习,因为参数已经凭空剔除。注意原则上可以学习。
该论文在等式13中具有置信度计算。如果读取正确,则表示matches_info.confidence
表示两个图像之间的正确匹配,如果其值大于1。
当置信度高于3时,我没有看到删除匹配的任何理由(将置信度设置为0)。这只是意味着非常少的异常值。我认为程序员认为大量的匹配结果是异常值意味着图像重叠很多,但这背后的算法并没有提供。 (简单地说,匹配基于特征的外观。)
答案 1 :(得分:2)
浏览一下在线提供的OpenCV源代码,我认为它们意味着以下内容:
我的假设是基于OpenCV源代码版本2.4.2中modules/stitching/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";
此外,我还查看detail::MatchesInfo的文档,了解有关 Ni 和 C 条款的信息。