基于OpenCV的Sift特征匹配(在drawMatchesKnn函数无法调用的情况下)

本实验基于opencv内置sift算子来对相似图像进行特征匹配。而在图像匹配显示中,由于莫名原因 “drawMatchesKnn” 函数无法直接调用。于是后面的图像显示部分是根据自己理解实现的。而在这个过程中也对匹配器中的匹配器对象(DMatch)多了一些了解。

DMatch对象具有下列属性:DMatch.distance 描述符之间的距离;DMatch.queryIdx 主影像的描述符索引;DMatch.trainIdx 第二影像的描述符索引;DMatch.imgIdx 目标影像的索引,也就是当有多个辅影像时的编号。而kp1和kp2是主影像和辅影像的关键点列表,存储了关键点的坐标信息(pt)。了解了这一层关系,我们就可以顺利地索引到关键点点坐标,从而画出特征匹配的情况。此外,我们还需要将原来分开的两张影像进行拼接处理,以便显示,在本代码中,拼接方法通过自定义函数“appendimages”实现。下面贴出完整代码。

import cv2
from pylab import *
img1=cv2.imread('ukbench00641.jpg',0)
img2=cv2.imread('ukbench00642.jpg',0)
m_h,n_l=img1.shape
sift=cv2.SIFT()
kp1,des1=sift.detectAndCompute(img1,None)
kp2,des2=sift.detectAndCompute(img2,None)
bf=cv2.BFMatcher()
matches=bf.knnMatch(des1,des2,k=2)
good=[]
for m,n in matches:
    if m.distance<0.75*n.distance:
        good.append([m])
def appendimages(I,I1):
    rows=I.shape[0]
    rows_1=I1.shape[0]
    if rowsrows_1:
        I1=concatenate((I1,zeros((rows-rows_1,I1.shape(0)))),axis=0)
    return concatenate((I,I1),axis=1)
I_12=appendimages(img1,img2)
c_coord1=[]
c_coord2=[]
c_coord1_1=[]
c_coord2_1=[]
#for i in range(len(good)):
for i in range(40):
    c_coord1.append(kp1[good[i][0].queryIdx].pt[0])
    c_coord2.append(kp1[good[i][0].queryIdx].pt[1])
    c_coord1_1.append(kp2[good[i][0].trainIdx].pt[0])
    c_coord2_1.append(kp2[good[i][0].trainIdx].pt[1])
c_coord1_1_1=[k+n_l for k in c_coord1_1]
imshow(I_12,cmap='gray')
plot(c_coord1,c_coord2,'r*')
plot(c_coord1_1_1,c_coord2_1,'bo')
X=[c_coord1[:],c_coord1_1_1[:]]
Y=[c_coord2[:],c_coord2_1[:]]
plot(X,Y)
show()
下面是结果展示,可以看到sift算子较harris算子来看,虽然也存在错误匹配点,但是效果明显好很多。

基于OpenCV的Sift特征匹配(在drawMatchesKnn函数无法调用的情况下)_第1张图片

你可能感兴趣的:(基于OpenCV的Sift特征匹配(在drawMatchesKnn函数无法调用的情况下))