首页 文章

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

提问于
浏览
4

我正在使用低分辨率(VGA)和jpg压缩的图像序列,以便在移动机器人上进行可视化导航 . 目前我正在使用SURF来检测关键点并从图像中提取描述符,并使用FLANN来跟踪它们 . 我在每张图像上获得4000-5000个特征,并且在应用RANSAC(通常减少20%的匹配数量)之前,每对连续图像通常会产生350-450个匹配

我正在努力增加比赛的数量(和质量) . 我尝试过另外两个探测器: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中的任何参数吗?

EDIT:

我发布了一些相当简单的序列图片来跟踪 . 这些图片是我给他们的特征检测器方法 . 它们经过预处理以消除一些噪音(通过 cv::bilateralFilter()

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

3 回答

  • 2

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

  • 0

    如果您可以控制跟踪的特征,则可以将它们旋转为不变并使用相关性 .

  • 0

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

    h t t s://github.com/wher0001/Image-Capture-and-Processing

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

    我总是将nfeatures的数量设置为高(5000)并从那里开始 . It defaults to 500 which is what I used for these pictures. 从那里你可以改变我在这里展示的排序方式,可以减少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的匹配 . 当修复后,我建议你切换到那个或只是应用一些智能图像 .

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

相关问题