5

我正在使用低分辨率 (VGA) 和 jpg 压缩的图像序列在移动机器人上进行视觉导航。目前我正在使用 SURF 来检测关键点并从图像中提取描述符,并使用 FLANN 来跟踪它们。在应用 RANSAC 之前,我每张图像获得 4000-5000 个特征,通常每对连续图像进行 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()

在此处输入图像描述 图 2

4

3 回答 3

2

在许多情况下,基于Pyramidal Lucas Kanade光流的方法是一个不错的选择。该方法有一些限制,例如照明的大变化。如果您使用 21x21 或更大的大窗口,则跟踪器应该对噪声更鲁棒。您可以从您最喜欢的 SIFT、SURF、FAST 或 GFT 特征检测器中获取要跟踪的特征,或者将它们初始化为常规采样网格。这为您提供了场景中常规样本运动信息的优势。

于 2014-11-05T20:31:27.377 回答
1

几个月来,我一直在使用 ORB 功能检测。我发现 ORB 本身没有问题,尽管作者谈到微调一些参数以使其性能更好。

https://github.com/wher0001/Image-Capture-and-Processing

当我使用您的图片和标准距离排序运行 ORB 时,我得到以下图片,显然有一些不匹配的图片。 ORB 匹配 - 标准排序

我总是将 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 与 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 的匹配。解决此问题后,我建议您切换到该问题或仅对图像应用一些智能。

例如,如果您将陀螺仪添加到系统中,您可以在通过缩小搜索窗口创建的窗口之外丢弃匹配项。

于 2017-04-27T20:34:17.843 回答
0

如果您可以控制您跟踪的特征,则可以使其旋转不变并使用相关性。

于 2014-08-04T21:37:12.170 回答