24

我在论坛里发现了一个类似的问题。但是那里的答案并没有回答我的问题。

  • 如果我在第一张图片上只做一次特征检测(goodFeaturesToTrack) ,然后使用光流(calcOpticalFlowPyrLK)跟踪这些特征,问题是:只能跟踪在第一张图片上检测到的特征。当这些特征超出图像时,将没有要跟踪的特征。

  • 如果我对每张新图像进行特征检测,特征跟踪是不稳定的,因为上次检测到的特征这次可能检测不到。

我正在使用光流进行 3D 重建。所以我对跟踪什么特征不感兴趣,相反,我只关心视野中的特征是否可以稳定地跟踪。总而言之,我的问题是:如何使用光流跟踪旧特征,同时添加进入视野的新图像特征并删除超出视野的旧特征?

4

3 回答 3

19

几种方法是可能的。一个好的方法是这样的:

  1. 在第 1 帧中检测 N 个特征,这是关键帧m=1
  2. 在第 k 帧中,通过光流跟踪特征
  3. 如果成功跟踪的特征数量下降到 N/2 以下,则在第 k 帧中:
    • 这一帧是关键帧m+1
    • 计算描述关键帧m 和 m+1之间运动的单应性或基本矩阵
    • 检测 N 个特征并丢弃旧特征
    • k := k+1 转到 2

在这种方法中,您基本上可以估计最后两个关键帧之间的相机运动。

由于您没有提到用于 3D 重建的方法,我假设HF首先被计算为估计运动。为了准确地估计它们,关键帧之间的基线应该尽可能宽。一般来说,最好的策略是考虑相机的粗略运动模型。如果相机是用手握住的,则与将相机固定在汽车或机器人顶部时相比,应该使用不同的策略。如果有帮助,我可以在 Python 中提供一个最小的工作示例,请告诉我。

于 2012-04-16T10:14:22.897 回答
3

仅出于文档目的,光流跟踪有几个很好的 GPU / C++ 实现。您的代码可能更适合您的目的,但如果您只需要轨道的输出数据,请考虑检查以下任何来源:hereherehere

于 2012-04-17T17:04:58.927 回答
0

还有另一种向现有功能添加新功能的好方法。您可以将掩码传递到cv::goodFeaturesToTrack(). 因此,您将创建一个新 Mat(与原始图像大小相同type: CV_8UC1),将所有像素设置为 255,并将每个特征点作为黑色圆圈绘制到该 Mat 中。当您将此掩码传递给goodFeaturesToTrack()那些黑色圆圈时,该功能将跳过这些圆圈。

我还建议限制功能的数量。假设您将其限制为MAX_FEATURES = 300. 然后,您检查每个周期是否有少于MAX_FEATURES - z (e.g. z = 30). 如果您这样做,请按照上述方法搜索多达 z 个新功能并将它们添加到您的功能容器中。

另请注意,您必须在跟踪失败时主动删除要素。因此,您必须查看 的状态输出calcOpticalFlowPyrLK

于 2016-03-29T20:39:30.000 回答