opencv 特征匹配
使用特征匹配和单应性查找对象
在一张杂乱的图像中找到了一个对象(的某些部分)的位置。这些信息足以帮助我们在目标图像中准确的找到(查询图像)对象。为了达到这个目的我们可以使用 calib3d 模块中的
cv2.findHomography()函数。如果将这两幅图像中的特征点集传给这个函数,他就会找到这个对象的透视图变换。然后我们就可以使用函数 cv2.perspectiveTransform() 找到这个对象了。至少要 4 个正确的点才能找到这种变换。
我们已经知道在匹配过程可能会有一些错误,而这些错误会影响最终结果。为了解决这个问题,算法使用 RANSAC 和 LEAST_MEDIAN(可以通过参数来设定)。所以好的匹配提供的正确的估计被称为 inliers,剩下的被称为outliers。cv2.findHomography() 返回一个掩模,这个掩模确定了 inlier 和outlier 点。
和通常一样我们先在图像中来找到 SIFT 特征点,然后再使用比值测试找到最佳匹配。
“”"
单应性匹配:
两幅图像中的一幅 出现投影畸变的时候,他们还能彼此匹配
“”"
import cv2
import numpy as np
#最小匹配数量设为10个, 大于这个数量从中筛选出10个最好的
MIN_MATCH_COUNT
= 10
#读入两幅图片 图片中有相同部分
img1= cv2.imread(“10.png”,cv2.IMREAD_GRAYSCALE)
img2= cv2.imread(“11.png”,cv2.IMREAD_GRAYSCALE)
#获取sift特征检测器
sift= cv2.xfeatures2d.SIFT_create()
#检测关键点 计算描述符
kp1,des1 = sift.detectAndCompute(img1, None)
kp2,des2 = sift.detectAndCompute(img2, None)
#kdtree建立索引方式的常量参数
FLANN_INDEX_KDTREE= 0
index_params= dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
search_params= dict(checks=50) # checks指定索引树要被遍历的次数
flann= cv2.FlannBasedMatcher(index_params, search_params)
#进行匹配搜索
matches= flann.knnMatch(des1, des2, k=2)
#寻找距离近的放入good列表
good= []
form, n in matches:
if m.distance < 0.7 * n.distance:
good.append(m)
#如果足够多 就筛选
if len(good)> MIN_MATCH_COUNT:
#通过距离近的描述符 找到两幅图片的关键点
src_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)
dst_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)
#单应性匹配图关键点匹配线。。
M, mask = cv2.findHomography(src_pts,dst_pts, cv2.RANSAC, 5.0)
matchesMask = mask.ravel().tolist()
h, w = img1.shape
#计算第二张图相对于第一张图的畸变
pts = np.float32([[0, 0], [0, h-1], [w-1,0]]).reshape(-1, 1, 2)
dst = cv2.perspectiveTransform(pts, M)
img2 = cv2.polylines(img2, [np.int32(dst)],True, 255, 3, cv2.LINE_AA)
else:
print (“No enough matches are found -
%d/%d” % (len(good),MIN_MATCH_COUNT))
matchesMask = None
#draw matches in green color
#draw only in liners
draw_params= dict(matchColor=(0, 255, 0),singlePointColor=None,matchesMask=matchesMask,flags=2)
img3= cv2.drawMatches(img1, kp1, img2, kp2, good, None, **draw_params)
cv2.imshow(“new”,img3)
cv2.waitKey()