opencv 特征匹配 使用特征匹配和单应性查找对象

本文介绍了如何使用OpenCV的calib3d模块和SIFT特征检测器进行特征匹配,以在图像中查找对象。通过找到关键点、匹配描述符并应用RANSAC去除错误匹配,计算单应性矩阵实现对象的精确定位。最后,通过绘制匹配点展示了匹配效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值