nic*_*ine 6 python opencv feature-detection
我正在尝试在我使用 OpenCV 检测到的两个图像之间匹配 SIFT 特征:
sift = cv2.xfeatures2d.SIFT_create()
kp, desc = sift.detectAndCompute(img, None)
Run Code Online (Sandbox Code Playgroud)
这两个图像似乎都包含许多特征,每个大约 15,000 个,用绿点显示。
但是在匹配它们之后,我只保留了 87 个,有些是异常值。
我试图弄清楚我是否做错了什么。我匹配两个图像的代码是:
def match(this_filename, this_desc, this_kp, othr_filename, othr_desc, othr_kp):
E_RANSAC_PROB = 0.999
F_RANSAC_PROB = 0.999
E_PROJ_ERROR = 15.0
F_PROJ_ERROR = 15.0
LOWE_RATIO = 0.9
# FLANN Matcher
# FLANN_INDEX_KDTREE = 1 # 1? https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_feature2d/py_matcher/py_matcher.html#basics-of-brute-force-matcher
# index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
# search_params = dict(checks=50) # or pass empty dictionary
# flann = cv2.FlannBasedMatcher(index_params, search_params)
# matcherij = flann.knnMatch(this_desc, othr_desc, k=2)
# matcherji = flann.knnMatch(othr_desc, this_desc, k=2)
# BF Matcher
this_matches = {}
othr_matches = {}
bf = cv2.BFMatcher()
matcherij = bf.knnMatch(this_desc, othr_desc, k=2)
matcherji = bf.knnMatch(othr_desc, this_desc, k=2)
matchesij = []
matchesji = []
for i,(m,n) in enumerate(matcherij):
if m.distance < LOWE_RATIO*n.distance:
matchesij.append((m.queryIdx, m.trainIdx))
for i,(m,n) in enumerate(matcherji):
if m.distance < LOWE_RATIO*n.distance:
matchesji.append((m.trainIdx, m.queryIdx))
# Make sure matches are symmetric
symmetric = set(matchesij).intersection(set(matchesji))
symmetric = list(symmetric)
this_matches[othr_filename] = [ (a, b) for (a, b) in symmetric ]
othr_matches[this_filename] = [ (b, a) for (a, b) in symmetric ]
src = np.array([ this_kp[index[0]].pt for index in this_matches[othr_filename] ])
dst = np.array([ othr_kp[index[1]].pt for index in this_matches[othr_filename] ])
if len(this_matches[othr_filename]) == 0:
print("no symmetric matches")
return 0
# retain inliers that fit x.F.xT == 0
F, inliers = cv2.findFundamentalMat(src, dst, cv2.FM_RANSAC, F_PROJ_ERROR, F_RANSAC_PROB)
if F is None or inliers is None:
print("no F matrix estimated")
return 0
inliers = inliers.ravel()
this_matches[othr_filename] = [ this_matches[othr_filename][x] for x in range(len(inliers)) if inliers[x] ]
othr_matches[this_filename] = [ othr_matches[this_filename][x] for x in range(len(inliers)) if inliers[x] ]
return this_matches, othr_matches, inliers.sum()
Run Code Online (Sandbox Code Playgroud)
这是两张原始图片:https : //www.dropbox.com/s/pvi247be2ds0noc/images.zip?dl=0
我不明白为什么在代码中您要过滤掉距离大于 0.9 ( LOWE_RATIO) 的匹配项。点已经匹配。通过过滤掉这些点,您可以将匹配的特征从大约 15000 个减少到 839 个,然后内点检测器仅将其中的 87 个识别为内点。
此外,使用下面使用 ORB(Oriented FAST 和 Rotated Brief)的代码,我得到了 500 个关键点和 158 个有意义的匹配。我相信它可能是 SIFT 的一个很好的替代方案:
import cv2
from matplotlib import pyplot as plt
img1 = cv2.imread('IMG_1598.png', cv2.COLOR_BGR2GRAY) # queryImage
img2 = cv2.imread('IMG_1596.png', cv2.COLOR_BGR2GRAY) # trainImage
# Initiate detector
orb = cv2.ORB_create()
# find the keypoints and descriptors
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, 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)
plt.imshow(img3)
plt.show()
plt.savefig('foo.png')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
563 次 |
| 最近记录: |