初学opencv/特征匹配

来源:互联网 发布:没有激素的护肤品知乎 编辑:程序博客网 时间:2024/05/17 08:56

环境:opencv 2.4

尺度不变特征变换(SIFT),这个算法可以帮助我们提取图像中的关键点并计算它们的描述符。 特征点检测和匹配是计算机视觉中一个很有用的技术,常见的有FAST。其中,ORB算法中,是采用了FAST作为特征点检测算子,ORB检测算法具备旋转不变性和抗噪声性。

#coding:utf-8import numpy as npimport cv2import matplotlib.pyplot as pltimport datetime"""opencv 2.4中没有drawMatches函数,定义一个drarMatches函数"""#定义一个drawmatches函数def drawMatches(img1, kp1, img2, kp2, matches):    # Create a new output image that concatenates the two images together    # (a.k.a) a montage    rows1 = img1.shape[0]    cols1 = img1.shape[1]    rows2 = img2.shape[0]    cols2 = img2.shape[1]    out = np.zeros((max([rows1,rows2]),cols1+cols2,3), dtype='uint8')    # Place the first image to the left    out[:rows1,:cols1] = np.dstack([img1, img1, img1])    # Place the next image to the right of it    out[:rows2,cols1:] = np.dstack([img2, img2, img2])    # For each pair of points we have between both images    # draw circles, then connect a line between them    for mat in matches:        # Get the matching keypoints for each of the images        img1_idx = mat.queryIdx        img2_idx = mat.trainIdx        # x - columns        # y - rows        (x1,y1) = kp1[img1_idx].pt        (x2,y2) = kp2[img2_idx].pt        # Draw a small circle at both co-ordinates        # radius 4        # colour blue        # thickness = 1        cv2.circle(out, (int(x1),int(y1)), 4, (201, 186, 131), 1)           cv2.circle(out, (int(x2)+cols1,int(y2)), 4, (28, 127, 135), 1)        # Draw a line in between the two points        # thickness = 1        # colour blue        cv2.line(out, (int(x1),int(y1)), (int(x2)+cols1,int(y2)), (137, 69, 148), 1)    # Show the image    cv2.imshow('Matched Features', out)    cv2.waitKey(0)    cv2.destroyWindow('Matched Features')    # Also return the image if you'd like a copy    return outbeaver = cv2.imread('images/haha.PNG')#彩色图#plt.imshow(cv2.cvtColor(beaver,cv2.COLOR_BGR2RGB))#灰度图gray = cv2.cvtColor(beaver,cv2.COLOR_BGR2GRAY)#SIFT特征检测器opencv2.4中不能使用xfeatures2d.SIFT_create()sift=cv2.SIFT()keypoints = sift.detect(beaver,None)#在图片中将特征点显示beaver_sift = cv2.drawKeypoints(beaver,keypoints,None)#找到关键点和描述符(128*kp)kp,des = sift.compute(gray,keypoints)#plt.imshow(cv2.cvtColor(beaver_sift, cv2.COLOR_BGR2RGB))#plt.show()##img1 = cv2.imread('images/box.png')#img2 = cv2.imread('images/box_in_scene.png')#img1 = cv2.imread('images/haha1.PNG')#img2 = cv2.imread('images/haha.PNG')img1 = cv2.imread('images/jianjian.jpg')img2 = cv2.imread('images/jianjian1.jpg')#plt.subplot(1,2,1)#plt.imshow(cv2.cvtColor(img1,cv2.COLOR_BGR2RGB))#plt.subplot(1,2,2)#plt.imshow(cv2.cvtColor(img2,cv2.COLOR_BGR2RGB))gray1 = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)gray2 = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)#采用ORB特征检测算法orb = cv2.ORB(1000, 1.2)#detectAndCompute()一步到位直接找到关键点并计算出其描述符(kp1,des1) = orb.detectAndCompute(gray1, None)(kp2,des2) = orb.detectAndCompute(gray2, None)#采用暴力匹配的方式bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)matches = bf.match(des1,des2)matches = sorted(matches, key=lambda val: val.distance)out = drawMatches(gray1, kp1, gray2, kp2, matches[:30])"""kp1, des1 = sift.detectAndCompute(gray1, None)kp2, des2 = sift.detectAndCompute(gray2, None)#采用Hellinger距离定义匹配特征des1 = des1 / np.repeat(np.sum(des1, axis = 1).reshape(des1.shape[0], 1), des1.shape[1], axis=1)des2 = des2 / np.repeat(np.sum(des2, axis = 1).reshape(des2.shape[0], 1), des2.shape[1], axis=1)dist_mat = np.sqrt(np.abs(1.0 - np.dot(np.sqrt(des1), np.sqrt(des2).transpose())))min_arg = np.argsort(dist_mat, axis=1)good_matches = []for i in range(dist_mat.shape[0]):    m, n = min_arg[i][0:2]    if dist_mat[i][m] < dist_mat[i][n] * 0.75:        dmatch = cv2.DMatch(i, m, 0, dist_mat[i][m]) # _queryIdx, _trainIdx, _imgIdx, _distance        good_matches.append(dmatch)out = drawMatches(gray1, kp1, gray2, kp2, good_matches[:30])"""

结果:

特征点描述
这里写图片描述
ORB检测算法和采用Hellinger距离进行特征匹配都具有旋转不变性
这里写图片描述
实验表明采用Hellinger距离的匹配效果更好
这里写图片描述

原创粉丝点击