python图像匹配_Opencv for python(2)--图像匹配

近期一直研究图像的拼接问题。图像拼接前,找到各个图像的特征点是个非常关键的步骤。这期专栏,我将介绍两种较常用的特征匹配方法(基于OpenCV),Brute-Force匹配和FLANN匹配。

1、BF匹配

cv2.BFMatch( normType, crossCheck=True/False)

其中normType是用来指定要使用的距离测试类型。默认值为cv2.Norm_L2,适用于SIFT,SURF方法,还有一个参数为cv2.Norm_L1。如果是ORB,BRIEF,BRISK算法等,要是用cv2.NORM_HAMMING,如果ORB算法的参数设置为VTA_K==3或4,normType就应该设置为cv2.NORM_HAMMING2.

第二个参数是crossCheck,默认值是False。如果设置为True,匹配条件会更加严格。举例来说,如果A图像中的i点和B图像中的j点距离最近,并且B中的j点到A中的i点距离也最近,相互匹配,这个匹配结果才会返回。

import cv2 as cv

from matplotlib import pyplot as plt

#读取需要特征匹配的两张照片,格式为灰度图。

img1=cv.imread("image/work1.jpg",0)

img2=cv.imread("image/work2.jpg",0)

orb=cv.ORB_create()#建立orb特征检测器

kp1,des1=orb.detectAndCompute(img1,None)#计算img1中的特征点和描述符

kp2,des2=orb.detectAndCompute(img2,None) #计算img2中的

bf = cv.BFMatcher(cv.NORM_HAMMING,crossCheck=True) #建立匹配关系

mathces=bf.match(des1,des2) #匹配描述符

mathces=sorted(mathces,key=lambda x:x.distance) #据距离来排序

img3= cv.drawMatches(img1,kp1,img2,kp2,mathces[:40],is=2) #画出匹配关系

plt.imshow(img3),plt.show() #matplotlib描绘出来图1 BF匹配结果

2、FLANN匹配

import cv2 as cv

from matplotlib import pyplot as plt

queryImage=cv.imread("image/work1.jpg",0)

trainingImage=cv.imread("image/work2.jpg",0)#读取要匹配的灰度照片

sift=cv.xfeatures2d.SIFT_create()#创建sift检测器

kp1, des1 = sift.detectAndCompute(queryImage,None)

kp2, des2 = sift.detectAndCompute(trainingImage,None)

#设置Flannde参数

FLANN_INDEX_KDTREE=0

indexParams=dict(algorithm=FLANN_INDEX_KDTREE,trees=5)

searchParams= dict(checks=50)

flann=cv.FlannBasedMatcher(indexParams,searchParams)

matches=flann.knnMatch(des1,des2,k=2)

#设置好初始匹配值

matchesMask=[[0,0] for i in range (len(matches))]

for i, (m,n) in enumerate(matches):

if m.distance< 0.7*n.distance: #舍弃小于0.7的匹配结果

matchesMask[i]=[1,0]

drawParams=dict(matchColor=(0,0,255),singlePointColor=(255,0,0),matchesMask=matchesMask,flags=0) #给特征点和匹配的线定义颜色

resultimage=cv.drawMatchesKnn(queryImage,kp1,trainingImage,kp2,matches,None,**drawParams) #画出匹配的结果

plt.imshow(resultimage,),plt.show()

FLANN 匹配器有两个参数,一个是indexParams,另一个是searchParams,以字典的形式进行参数传递。为了计算匹配,FLANN内部会决定如何处理索引和搜索对象。

索引方法可以选择LinearIndex,KTreeIndex,KMeansIndex等,其中KTreeIndex配置索引简单,只需制定待处理核密度的数量即可,推荐值为1~16。SearchParams只包含一个字段,checks,表示制定索引树要被遍历的次数。经验值推荐,5 kd—trees,50 checks 可以取得较好的匹配精度,并且可以在较短的时间内完成。

在匹配结果中我们根据Lowe的论文,删除匹配结果距离大于0.7的。通过这种过滤,可以避免几乎90%的错误匹配。原文“Distinctive Image Feature from scale Scale-Invariant Keypoints”

匹配结果如下:图2 FLANN匹配结果

更新一下。

3、FLANN单应性匹配

两幅不在一个平面角度的照片,通过其中一幅照片(小图像)的特征点,与第二幅(大图像)中的特征点可以确定这部分位置在第二幅中的位置。我们通过cv2.findHomography()函数,计算这对图像的透视变化矩阵,然后通过cv2.perspectiveTransform()找到在第二图像(大图像)中的第一幅图像的位置。

import numpy as np

import cv2 as cv

from matplotlib import pyplot as plt

MIN_MATCH_COUNT=10 #设置最低匹配数量为10

img1=cv.imread("image/pen.jpg",0) #读取第一个图像(小图像)

img2=cv.imread("image/work2.jpg",0) #读取第二个图像(大图像)

sift=cv.xfeatures2d.SIFT_create() #创建sift检测器

kp1,des1=sift.detectAndCompute(img1,None)

kp2,des2=sift.detectAndCompute(img2,None)

#创建设置FLAAN匹配

FLANN_INDEX_KDTREE=0

index_params=dict(algorithm=FLANN_INDEX_KDTREE, trees=5)

search_params=dict(checks=50)

flann=cv.FlannBasedMatcher(index_params,search_params)

mathces=flann.knnMatch(des1,des2,k=2)

good=[]

#过滤不合格的匹配结果,大于0.7的都舍弃

for m,n in mathces:

if m.distance<0.7*n.distance:

good.append(m)

#如果匹配结果大于10,则获取关键点的坐标,用于计算变换矩阵

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=cv.findHomography(src_pts,dst_pts,cv.RANSAC,10.0)

matchesMask=mask.ravel().tolist()

#根据变换矩阵进行计算,找到小图像在大图像中的位置

h,w=img1.shape

pts=np.float32([[0,0],[0,h-1],[w-1,h-1],[w-1,0]]).reshape(-1,1,2)

dst=cv.perspectiveTransform(pts,M)

cv.polylines(img2,[np.int32(dst)],True,0,5,cv.LINE_AA)

else:

print(" Not Enough matches are found")

matchesMask=None

#画出特征匹配线

draw_params=dict(matchColor=(0,255,0),singlePointColor=None,

matchesMask=matchesMask,flags=2)

#plt展示最终的结果

img3=cv.drawMatches(img1,kp1,img2,kp2,good,None,**draw_params)

plt.imshow(img3),plt.show()

展示下最终的结果,其中白色和黑色的边框,就是通过变换矩阵计算得到的。原始照片(大图像)原始照片(小图像)FLANN单应性匹配原始图像(大图像)原始图像(小图像)FLANN单应性匹配

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenCV-Python提供了一系列用于图像处理和计算机视觉任务的功能,其中包括图像匹配图像匹配是指在一幅图像中寻找与目标图像相似的区域。通过OpenCV-Python,你可以使用模板匹配技术来实现图像匹配。 模板匹配是一种基于像素值相似度的匹配方法,它通过在输入图像中滑动一个模板图像,并计算模板与滑动窗口区域的相似度来找到最佳匹配位置。在OpenCV-Python中,你可以使用cv2.matchTemplate()函数来实现模板匹配。 下面是一个简单的图像匹配的例子代码: ```python import cv2 import numpy as np # 读取输入图像和目标图像 input_img = cv2.imread('input_img.jpg') target_img = cv2.imread('target_img.jpg') # 将输入图像和目标图像转换为灰度图像 input_gray = cv2.cvtColor(input_img, cv2.COLOR_BGR2GRAY) target_gray = cv2.cvtColor(target_img, cv2.COLOR_BGR2GRAY) # 执行模板匹配 result = cv2.matchTemplate(input_gray, target_gray, cv2.TM_CCOEFF_NORMED) # 获取最佳匹配位置 min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result) top_left = max_loc # 获取目标图像的宽度和高度 target_width, target_height = target_gray.shape[::-1] # 绘制矩形框标记目标图像 cv2.rectangle(input_img, top_left, (top_left + target_width, top_left + target_height), (0, 255, 0), 2) # 显示结果图像 cv2.imshow('Result', input_img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在这个例子中,我们首先读取了输入图像和目标图像,并将它们转换为灰度图像。然后,我们使用cv2.matchTemplate()函数执行模板匹配,并通过获取最佳匹配位置来找到目标图像在输入图像中的位置。最后,我们使用cv2.rectangle()函数在输入图像上绘制一个矩形框来标记目标图像的位置,并显示结果图像。 请注意,这只是一个简单的图像匹配示例,你可以根据自己的需求进行更复杂的图像匹配操作,例如使用不同的匹配方法、应用阈值、使用多个目标图像等。同时,确保你已经安装了OpenCV-Python库,并准备好了输入图像和目标图像以供匹配使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值