多语言展示
当前在线:156今日阅读:84今日分享:32

用SIFT算法检测图像特征并进行图像匹配

SIFT算法是David Lowe于1999年提出来的图像特征检测算法。本文试图用SIFT算法,找出下面两幅图片的特征点,并加以匹配。这两幅图是从不同视角观察这个路标的情景。注意,请安装3.3.0.10版本的opencv模块,理由可以参考《基于python的图形的配准、拼接和融合》。1基于python的图形的配准、拼接和融合
工具/原料
1

电脑

2

python

方法/步骤
1

加载模块、图片,并把图片变成灰度图片。import cv2import numpy as npMIN_MATCH_COUNT = 4img1 = cv2.imread('D:/……/a.jpg')img2 = cv2.imread('D:/……/b.jpg')g1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)g2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

2

灰度图。

3

创建SIFT对象:sift = cv2.xfeatures2d.SIFT_create()创建Flann匹配:match = cv2.FlannBasedMatcher(dict(algorithm =2, trees =1), {})检测特征点,并描述特征点:kp1, de1 = sift.detectAndCompute(g1,None)kp2, de2 = sift.detectAndCompute(g2,None)

4

用knn匹配,来提取de1和de2的靠前的数据m = match.knnMatch(de1, de2, 2)

5

重新排序:m = sorted(m,key = lambda x:x[0].distance)

6

提取效果较好的几个可匹配特征点:ok = [m1 for (m1, m2) in m if m1.distance < 0.7 * m2.distance]

7

根据匹配的特征点,对第1幅图片进行透视变换,使之与第一幅图的已经匹配的特征点尽量重合:if len(ok)>MIN_MATCH_COUNT:    pts0 = np.float32([ kp1[i.queryIdx].pt for i in ok]).reshape(-1,1,2)    pts1 = np.float32([ kp2[i.trainIdx].pt for i in ok]).reshape(-1,1,2)    M, mask = cv2.findHomography(pts0,pts1, cv2.RANSAC,5.0)    h,w = img1.shape[:2]    pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2)    dst = cv2.perspectiveTransform(pts,M)    cv2.polylines(img2,[np.int32(dst)],True,(0,255,0),3, cv2.LINE_AA)else:    print( '匹配点的数目不够! - {}/{}'.format(len(ok),MIN_MATCH_COUNT))

8

用线把匹配的特征点连接起来:med = cv2.drawMatches(img1,kp1,img2,kp2,ok,None)可以看出来,有些匹配的特征点,并不匹配。这说明,如果发生位移,那么,匹配结果会有所出入。

9

整体代码如下图所示。

注意事项
1

SIFT算法,如果待匹配图像被遮住了一小部分,也是能够匹配到的。

2

opencv版本需要指定为opencv-contrib-python==3.3.0.10,否则sift功能有可能使用不了。

推荐信息