【问题标题】:OpenCV - Feature Matching vs Optical FlowOpenCV - 特征匹配与光流
【发布时间】:2018-05-08 00:20:15
【问题描述】:

我对使用 OpenCV 制作运动跟踪应用程序很感兴趣,并且在线提供了大量信息。但是,我对使用 Lucas-Kanade 等稀疏光流算法的特征匹配和跟踪特征感到有点困惑。考虑到这一点,我有以下问题:

  • 如果我指定了要跟踪的像素区域,两者(特征匹配和光流)之间的主要区别是什么?如果这有助于消除任何假设,我对实时跟踪不感兴趣。

  • 此外,由于我没有进行实时跟踪,使用密集光流 (Farneback) 跟踪指定感兴趣区域中的像素是否更好?

谢谢。

【问题讨论】:

    标签: opencv computer-vision


    【解决方案1】:

    特征匹配使用特征描述符在特征描述符空间中使用最近邻搜索(通常)将特征相互匹配。基本思想是你有描述符向量,并且两个图像中的相同特征在描述符空间中应该彼此靠近,所以你只需这样匹配。

    光流算法不查看描述符空间,而是查看特征周围的像素块并尝试匹配这些块。如果您熟悉密集光流,那么稀疏光流只会在特征点周围的图像小块上进行密集光流。因此,光流假设亮度恒定,即像素亮度在帧之间不会改变。此外,由于您正在查看相邻像素,因此您需要假设特征的相邻点与您的特征类似地移动。最后,由于它在小块上使用密集流算法,它们移动的点在图像中与原始特征位置的距离不会很远。如果是,则建议使用金字塔分辨率方法,在执行此操作之前先缩小图像,这样曾经的 16 像素平移现在变成 2 像素平移,然后您可以使用找到的变换放大你以前的。

    因此,在使用比例不完全相同的模板,或者图像和模板存在透视差异,或者转换很大的情况下,特征匹配算法总体上要好得多。但是,您的匹配仅与您的特征检测器准确无误一样好。在光流算法上,只要它在正确的位置,转换就可以非常非常精确。它们在计算上都有点昂贵。光流算法是一种迭代方法,因此成本很高(尽管您认为金字塔方法可以通过在更多图像上运行来消耗更多成本,但它实际上可以在某些情况下更快地达到所需的精度),以及最近邻搜索也很昂贵。光流算法 OTOH 可以在转换较小的情况下工作得非常好,但是如果场景中的任何东西干扰了您的照明或者您得到了一些不正确的像素(例如,即使是轻微的遮挡),它真的可以让它消失。

    使用哪一个绝对取决于项目。对于我从事的卫星图像项目,我使用了密集光流,因为我正在使用的沙漠地形图像没有足够精确的特征(在位置上),并且不同的特征描述符恰好看起来相对相似,因此搜索该特征空间是不会提供大量精彩的比赛。在这种情况下,光流是更好的方法。但是,如果您在建筑物可能遮挡部分场景的城市的卫星图像上进行图像对齐,则有很多特征将保持匹配并提供更好的结果。

    OpenCV Lucas-Kanade tutorial 没有提供很多洞察力,但应该让您的代码朝着正确的方向前进,同时牢记上述内容。

    【讨论】:

    • 哇,多么棒的帖子!那是丰富的信息。谢谢你,亚历山大。根据您的帖子,为您的 ROI 应用形状掩码是否会改善密集光流的结果,例如 cv::calcOpticalFlowFarneback 之类返回的结果的“形状”?
    • @JDBones 恐怕我不关注; OpenCV 中的光流方法不允许包含掩码。还是你的意思是别的?
    • 对迟到的回复表示歉意。我的意思是用黑色掩盖我的 ROI 的像素区域,因此只保留我的掩码点范围内的子图像。只要imgPrevimgCur 的尺寸相同,这不应该在我的密集光流调用中失败。
    • @JDBones 抱歉,还没关注。你的意思是你有一个非矩形的 ROI,因此你想把矩形 ROI 内的一些像素涂黑来弥补它?如果是这样,no---dense 光流将假设这些黑色像素也将出现在下一张图像中,而稀疏算法会将这些黑色像素作为图像的特征(例如边缘)。
    • 对于稀疏算法,您可以删除非矩形 ROI 之外的特征点。对于密集算法,C++ 接口确实允许在 findTransformECC() 中使用掩码,请参阅 docs
    【解决方案2】:

    我想就该主题添加一些想法,因为我发现这也是一个非常有趣的问题。 如前所述,特征匹配是一种基于以下技术的技术:

    • 一个特征检测步骤,它返回一组所谓的特征点。这些特征点位于具有显着图像结构的位置,例如使用 FAST 时为边缘状结构,使用 SIFT 或 SURF 时为 blob 状结构。

    • 第二步是匹配。从两个不同图像中提取的特征点的关联。匹配基于局部视觉描述符,例如梯度或二进制模式的直方图,在特征位置周围局部提取。描述符是一个特征向量,相关的特征点对是最小特征向量距离的对。

    大多数特征匹配方法是 scalerotation invariant 并且 对于光照变化具有鲁棒性(例如通过阴影或不同的对比度)。因此,这些方法可以应用于图像序列,但更经常用于对齐从不同视图或不同设备捕获的图像对。缺点特征匹配方法的困难在于定义特征匹配的产生位置以及特征对(在图像序列中是运动向量)通常非常稀疏。此外,匹配方法的亚像素精度非常有限,因为大多数检测器都精细分级到整数位置。

    根据我的经验,特征匹配方法的主要优势是它们可以计算非常大的运动/位移

    OpenCV 提供了一些特征匹配方法,但在线上有很多更新、更快和更准确的方法,例如:

    • DeepMatching 依赖于深度学习,通常用于初始化光流方法以帮助他们处理远程运动。
    • Stereoscann 这是一种非常快速的方法,最初是为视觉里程计提出的。
    相比之下,

    光流方法依赖于亮度恒定性的最小化和额外的约束,例如平滑度等。因此,它们基于一系列连续帧的空间和时间图像梯度推导出运动矢量。因此,它们更适合图像序列,而不是从非常不同的视点捕获的图像对。用光流向量估计运动的主要挑战大运动遮挡强光照变化对象外观的变化,主要是低运行时间。然而,光流方法可以高度准确并计算密集运动场,这与场景中对象的共享运动边界有关。

    但是,不同的光流方法的精度差异很大。 Local 方法,例如 PLK (Lucas Kanade) 通常不太准确,但只允许计算预先选择的运动矢量,因此速度非常快。 (近年来,我们进行了一些研究以提高局部方法的准确性,请参阅here 了解更多信息)。

    OpenCV 主干提供了全局方法,例如 Farnback。但这是一种相当过时的方法。试试 OpenCV contrib 主干,其中有更新的方法。但要对最新方法有一个很好的了解,请查看公共光流基准。在这里您还可以找到代码和实现,例如:

    但从我的角度来看,我不会在早期阶段拒绝特定的方法匹配或光流。尽可能多地尝试可用的在线实现,看看什么最适合您的应用程序。

    【讨论】:

    • "因此,它们更适合图像序列,而不是从非常不同的视点捕获的图像对。"这很有趣,大多数我的测试来自视频素材,我使用 OpenCV 的 LK 实现获得的结果远远超过了我们的要求(到目前为止...)。谢谢你。这很有帮助!
    【解决方案3】:

    关键点匹配 = 稀疏光流

    KLT 跟踪是稀疏流的一个很好的例子,请参阅演示 LKDemo.cpp(它也有一些 python 包装器示例,现在不记得了)。

    有关密集示例,请参阅 samples/python/opt_flow.py,使用 Farnebäcks 方法。

    你的困惑是对的……整个世界都对这个非常简单的话题感到困惑。很多原因是因为人们认为 Lucas-Kanade 是稀疏流(由于 openCV 中一个非常糟糕的命名和评论示例:LKdemo,应该称为 KLTDemo)。

    【讨论】:

      猜你喜欢
      • 2018-04-27
      • 1970-01-01
      • 1970-01-01
      • 2017-08-13
      • 2014-04-04
      • 2011-09-04
      • 2018-03-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多