我正在使用低分辨率(VGA)和jpg压缩的图像序列,以便在移动机器人上进行可视化导航。目前我正在使用SURF来检测关键点并从图像中提取描述符,并使用FLANN来跟踪它们。我在每张图像上获得4000-5000个特征,并且在应用RANSAC之前,每对连续图像通常会产生350-450个匹配(通常会减少20%的匹配数量)
我正在努力增加比赛的数量(和质量)。我尝试过另外两个探测器:SIFT和ORB。 SIFT显着增加了功能的数量(总体上跟踪功能的35%),但速度要慢得多。 ORB提取的功能大致与SURF一样多,但匹配性能更差(在最佳情况下约为100次匹配)。我在ORB的opencv中的实现是:
cv::ORB orb = cv::ORB(10000, 1.2f, 8, 31);
orb(frame->img, cv::Mat(), im_keypoints, frame->descriptors);
frame->descriptors.convertTo(frame->descriptors, CV_32F); //so that is the same type as m_dists
然后,匹配时:
cv::Mat m_indices(descriptors1.rows, 2, CV_32S);
cv::Mat m_dists(descriptors1.rows, 2, CV_32F);
cv::flann::Index flann_index(descriptors2, cv::flann::KDTreeIndexParams(6));
flann_index.knnSearch(descriptors1, m_indices, m_dists, 2, cv::flann::SearchParams(64) );
使用低分辨率和嘈杂图像时,最佳特征检测器和提取器是什么?我应该根据所使用的特征检测器更改FLANN中的任何参数吗?
修改
我发布了一些相当简单的序列图片来跟踪。这些图片是我给他们的特征检测器方法。它们已经过预处理以消除一些噪音(通过cv::bilateralFilter()
)
答案 0 :(得分:2)
在许多情况下,基于Pyramidal Lucas Kanade光流的方法是一个不错的选择。该方法有一些限制,例如照明的巨大变化。如果使用21x21或大于跟踪器的大窗口应该对噪声更加鲁棒。您可以从最喜欢的SIFT,SURF,FAST或GFT特征检测器获取要跟踪的功能,或者将它们初始化为常规采样网格。这为您提供了场景中常规样本运动信息的优势。
答案 1 :(得分:0)
如果您可以控制跟踪的功能,那么它们可以旋转不变并使用相关性。
答案 2 :(得分:0)
我几个月来一直在使用ORB功能检测。 我发现ORB本身没有问题,尽管作者谈到微调一些参数以使其表现更好。
h t t s://github.com/wher0001/Image-Capture-and-Processing
当我使用您的图片和标准距离排序运行ORB时,我得到以下图片,显然有一些不好的匹配。 ORB Matching - standard sorting
我总是将nfeatures的数量设置为高(5000)并从那里开始。 默认为500,这是我用于这些图片的内容。 从那里你可以改变我在这里展示的排序方式,可以减少nfeatures数量,甚至只使用前X个匹配数。
import numpy as np
import cv2
from matplotlib import pyplot as plt
img1 = cv2.imread("c:/Users/rwheatley/Desktop/pS8zi.jpg")
img2 = cv2.imread("c:/Users/rwheatley/Desktop/vertrk.jpg")
grey1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
grey2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
# Initiate ORB detector
orb = cv2.ORB_create(nfeatures=5000)
# find the keypoints and descriptors with ORB
kp1, des1 = orb.detectAndCompute(grey1,None)
kp2, des2 = orb.detectAndCompute(grey2,None)
# create BFMatcher object
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
# Match descriptors.
matches = bf.match(des1,des2)
# Sort them in the order of their distance.
matches = sorted(matches, key = lambda x:x.distance)
# Draw first 10 matches.
img3 = cv2.drawMatches(img1,kp1,img2,kp2,matches,None,flags=2)
print(len(matches))
plt.imshow(img3),plt.show()
然后我转而使用一些不同的方法,当我使用一个糟糕的戴尔网络摄像头(借口这个术语)时,我觉得这些方法很有用。 ORB with knnMatching
import numpy as np
import cv2
from matplotlib import pyplot as plt
img1 = cv2.imread("c:/Users/rwheatley/Desktop/pS8zi.jpg")
img2 = cv2.imread("c:/Users/rwheatley/Desktop/vertrk.jpg")
grey1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
grey2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
# Initiate ORB detector
orb = cv2.ORB_create(nfeatures=5000)
# find the keypoints and descriptors with ORB
kp1, des1 = orb.detectAndCompute(grey1,None)
kp2, des2 = orb.detectAndCompute(grey2,None)
# BFMatcher with default params
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1,des2, k=2)
# Apply ratio test
good = []
for m,n in matches:
if m.distance < 0.75*n.distance:
good.append([m])
# cv2.drawMatchesKnn expects list of lists as matches.
img3 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,good,None,flags=2)
print(len(matches))
plt.imshow(img3),plt.show()
即使在最新版本的OpenCV中,也存在第三种类型的匹配。基于Flann的匹配。当修复后,我建议你切换到那个,或者只是对图像应用一些智能。
例如,如果您将陀螺仪添加到系统中,则可以通过缩小搜索窗口来抛出窗口外的匹配项。