低分辨率图像的特征检测器和描述符

时间:2014-06-26 23:09:33

标签: image opencv feature-detection feature-extraction feature-tracking

我正在使用低分辨率(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()

enter image description here Image 2 http://oi61.tinypic.com/vertrk.jpg

3 个答案:

答案 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的匹配。当修复后,我建议你切换到那个,或者只是对图像应用一些智能。

例如,如果您将陀螺仪添加到系统中,则可以通过缩小搜索窗口来抛出窗口外的匹配项。