我正在研究图像处理。我想匹配 2D 特征,我在 SURF、SIFT、ORB 上做了很多测试。
如何在 OpenCV 的 SURF/SIFT/ORB 上应用 RANSAC?
问问题
29551 次
2 回答
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 );
然后,您可以使用该函数cv::perspectiveTransform
根据单应矩阵扭曲图像。
cv::findHomography
除此之外的其他选项CV_RANSAC
是0
使用每个点和CV_LMEDS
使用最小中值方法。更多信息可在此处的 OpenCV 相机校准文档中找到。
于 2013-04-15T00:09:28.437 回答
2
ransac
这是在获得的 SIFT / SURF 关键点上使用skimage
withProjectiveTransform
或AffineTransform
(即 Homography)模型应用的 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
于 2021-02-15T10:00:16.027 回答