使用光流进行特征跟踪
Feature tracking using optical flow
我在论坛中发现了类似的问题。但是那里的答案并没有回答我的问题。
-
如果我只在第一张图像上做一次特征检测(goodFeaturesToTrack),然后使用光流(calcOpticalFlowPyrLK)来跟踪这些特征,问题是:只能在第一张图像上检测到的特征才能被跟踪。当这些特征超出图像范围时,将没有要跟踪的特征。
-
如果我对每个新图像进行特征检测,则特征跟踪不稳定,因为上次检测到的特征这次可能无法检测到。
我正在使用光流进行3D重建。 所以我对跟踪哪些特征不感兴趣,而是只关心视野中的特征是否可以稳定跟踪。总而言之,我的问题是:如何使用光流来跟踪旧特征,同时添加进入视野的新图像特征并删除超出视野的旧特征?
有几种方法。一个好方法是这样的:
- 在第 1 帧中检测 N 个特征,这是关键帧 m=1
- 在帧 k 中通过光流跟踪特征
- 如果成功追踪的要素数低于 N/2,则在帧 k 中:
- 此帧是关键帧 M+1
- 计算描述关键帧 m 和 m+1 之间运动的单应性或基本矩阵
- 检测 N 个特征并丢弃旧特征
- k := k+1 转到 2
在这种方法中,基本上您可以估计最后两个关键帧之间的相机运动。
由于您没有提到使用什么方法进行3D重建,因此我假设首先计算H或F以估计运动。为了准确估计它们,关键帧之间的基线应尽可能宽。通常,最佳策略是考虑相机的粗略运动模型。如果用手握住相机,则与将相机固定在汽车或机器人顶部时相比,应使用不同的策略。如果有帮助,我可以在 Python 中提供一个最小的工作示例,请告诉我。
仅出于文档目的,光流跟踪有几个很好的GPU/C++实现。您的代码可能更适合您的目的,但如果您只需要轨道的输出数据,请考虑检查以下任何来源:此处、此处或此处。
还有另一种向现有功能添加新功能的好方法。您可以将掩码传递到cv::goodFeaturesToTrack()
中。因此,您将创建一个新的垫子(与原始图像的大小相同,type: CV_8UC1
),将所有像素设置为 255,并将每个特征点作为黑色圆圈绘制到此垫子中。当您将此掩码传递到goodFeaturesToTrack()
函数将跳过这些黑色圆圈时。
我还建议限制功能的数量。假设您将其限制为 MAX_FEATURES = 300
.然后,您检查每个周期的曲目是否少于MAX_FEATURES - z (e.g. z = 30)
。如果您这样做,请如上所述搜索最多 z 个新功能,并将它们添加到您的功能容器中。
另请注意,当追踪失败时,您必须主动删除要素。因此,您必须查看 calcOpticalFlowPyrLK
的状态输出。
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 光线跟踪器灯光反射错误
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 人脸跟踪arduino代码的优化
- 特征命名访问向量段
- 将特征矩阵的向量设置为0
- 特征:模板函数中矩阵的平面图
- 跟踪滚动条上的鼠标事件
- basic_string的前导/尾部不区分空格的特征
- 特征 3 类的模板专用化
- 如何使用新运算符跟踪在循环中创建的 QLabel
- 特征 c++:复矩阵的面积双曲正切(atanh)
- C++ 中的特征向量计算
- 根据C++标准的定义实现"is_similar"类型特征
- C++类型特征,以查看是否可以<uint32_t>对类型"K"的任何变量调用"static_cast(k)"
- 如何使用像Farneback这样的密集光流方法跟踪稀疏特征?
- 如何通过 solve() 跟踪特征对象
- 使用光流进行特征跟踪
- 连续帧的跟踪特征