如何在SURF,SIFT和ORB匹配结果上应用RANSAC

Hai*_*der 6 opencv feature-extraction ransac orb feature-descriptor

我正在进行图像处理.我想匹配2D功能,我在SURF,SIFT,ORB上做了很多测试.
如何在OpenCV中对SURF/SIFT/ORB应用RANSAC?

Dan*_*nny 23

OpenCV具有cv::findHomography可选择使用RANSAC来查找与两个图像相关的单应矩阵的功能.您可以在此处查看此功能的示例.

具体而言,您感兴趣的代码部分是:

FlannBasedMatcher matcher;
std::vector< DMatch > matches;
matcher.match( descriptors_object, descriptors_scene, matches );

for( int i = 0; i < good_matches.size(); i++ )
{
    //-- Get the keypoints from the good matches
    obj.push_back( keypoints_object[ good_matches[i].queryIdx ].pt );
    scene.push_back( keypoints_scene[ good_matches[i].trainIdx ].pt );
}

Mat H = findHomography( obj, scene, CV_RANSAC ); 
Run Code Online (Sandbox Code Playgroud)

然后,您可以cv::perspectiveTransform根据单应矩阵使用该函数来扭曲图像.

对于其他选项cv::findHomography比其它CV_RANSAC0它采用的每一点和CV_LMEDS它使用的最低中值法.有关详细信息,请参阅此处的OpenCV摄像机校准文档.


war*_*USP 5

ransac以下是在获得的 SIFT / SURF 关键点上使用skimagewithProjectiveTransformAffineTransform(即单应性)模型应用的 python 实现。此实现首先对获得的关键点进行 Lowe 比率测试,然后对 Lowe 比率测试中筛选出的关键点进行 ransac。

import cv2
from skimage.measure import ransac
from skimage.transform import ProjectiveTransform, AffineTransform
import numpy as np


def siftMatching(img1, img2):
    # Input : image1 and image2 in opencv format
    # Output : corresponding keypoints for source and target images
    # Output Format : Numpy matrix of shape: [No. of Correspondences X 2] 

    surf = cv2.xfeatures2d.SURF_create(100)
    # surf = cv2.xfeatures2d.SIFT_create()

    kp1, des1 = surf.detectAndCompute(img1, None)
    kp2, des2 = surf.detectAndCompute(img2, None)

    FLANN_INDEX_KDTREE = 0
    index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
    search_params = dict(checks = 50)
    flann = cv2.FlannBasedMatcher(index_params, search_params)
    matches = flann.knnMatch(des1,des2,k=2)

    # Lowe's Ratio test
    good = []
    for m, n in matches:
        if m.distance < 0.7*n.distance:
            good.append(m)

    src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1, 2)
    dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1, 2)

    # Ransac
    model, inliers = ransac(
            (src_pts, dst_pts),
            AffineTransform, min_samples=4,
            residual_threshold=8, max_trials=10000
        )

    n_inliers = np.sum(inliers)

    inlier_keypoints_left = [cv2.KeyPoint(point[0], point[1], 1) for point in src_pts[inliers]]
    inlier_keypoints_right = [cv2.KeyPoint(point[0], point[1], 1) for point in dst_pts[inliers]]
    placeholder_matches = [cv2.DMatch(idx, idx, 1) for idx in range(n_inliers)]
    image3 = cv2.drawMatches(img1, inlier_keypoints_left, img2, inlier_keypoints_right, placeholder_matches, None)

    cv2.imshow('Matches', image3)
    cv2.waitKey(0)

    src_pts = np.float32([ inlier_keypoints_left[m.queryIdx].pt for m in placeholder_matches ]).reshape(-1, 2)
    dst_pts = np.float32([ inlier_keypoints_right[m.trainIdx].pt for m in placeholder_matches ]).reshape(-1, 2)

    return src_pts, dst_pts
Run Code Online (Sandbox Code Playgroud)