我正在开发一个功能跟踪应用程序,到目前为止,在尝试几乎所有的功能检测器/描述符后,我用ORB获得了最满意的整体结果。 我的特征描述符和检测器都是ORB。
我正在选择一个特定区域来检测源图像上的特征(通过屏蔽)。然后将其与后续帧中检测到的功能进行匹配。
然后我通过对从以下代码获得的'匹配'执行比率测试来过滤我的匹配:
std::vector<std::vector<DMatch>> matches1;
m_matcher.knnMatch( m_descriptorsSrcScene, m_descriptorsCurScene, matches1,2 );
我也尝试过双向比率测试(从源到当前场景的过滤匹配,反之亦然,然后过滤掉常见的匹配)但是没有做太多,所以我继续进行单向比率测试。 / p>
我还在我的比率测试中添加了一个最小距离检查,它可以提供更好的结果
if (distanceRatio < m_fThreshRatio && bestMatch.distance < 5*min_dist)
{
refinedMatches.push_back(bestMatch);
}
最后,我估计了Homography。
Mat H = findHomography(points1,points2);
我尝试使用RANSAC方法估算内联线,然后使用它们重新计算我的Homography,但这会导致更多不稳定性并消耗更多时间。
然后在最后我在我要跟踪的特定区域周围绘制一个矩形。我得到了飞机坐标:
perspectiveTransform( obj_corners, scene_corners, H);
其中'objcorners'是我蒙面(或未屏蔽)区域的坐标。
我使用'scene_corners'绘制的反射角似乎在振动。增加功能的数量已经减少了很多,但由于时间的限制,我不能过多地增加它们。
如何提高稳定性?
任何建议都将不胜感激。
感谢。
答案 0 :(得分:1)
如果振动对你来说真的很麻烦,那么你可以尝试随时间推移单应矩阵的移动平均值:
cv::Mat homoG = cv::findHomography(obj, scene, CV_RANSAC);
if (homography.empty()) {
homoG.copyTo(homography);
}
cv::accumulateWeighted(homoG, homography, 0.1);
制作&#39;单应性&#39;变量global,并在每次获得新帧时继续调用它。 accumulateWeighted的alpha参数是移动平均线周期的倒数。
所以0.1取最后10帧的平均值,0.2取最后5帧的平均值,等等......
答案 1 :(得分:0)
从特征检测/匹配经验中想到的一个建议是,有时您必须接受匹配的特征点将无法完美地工作。即使您正在观察的场景中的细微变化也会引起一些令人讨厌的问题,例如光线或不需要的物体的变化会进入视野。
在我看来,你有一个正常工作的功能与你说的相匹配,你可能想要保持感兴趣区域不变的方式。如果您知道您尝试在帧之间跟踪的任何对象所特有的典型速度或任何其他移动模式,或者与相机位置相关的任何约束,则可能有助于避免重新计算不必要地引起振动的感兴趣区域。或者实际上它可能有助于创建更有效的搜索算法,允许您增加可以检测和使用的特征点的数量。
如果前一个窗口具有相似的大小和位置,则可以使用的另一个(小)黑客是避免重绘区域窗口。