from PIL import Image
import cv2
import numpy as np
import matplotlib.pyplot as plt
#计算特征点
cs1 = cv2.imread("cs1.jpg")
img1 = cv2.resize(cs1,(500,500))
gray = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
cv2.imshow("img1",img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
sift = cv2.xfeatures2d.SIFT_create()
kp = sift.detect(gray,None) #搜索关键点
img_sift = cv2.drawKeypoints(img1,kp,img1) #绘制关键点
cv2.imshow("img_sift",img_sift)
cv2.waitKey(0)
cv2.destroyAllWindows()
kp,des = sift.compute(gray,kp) #计算关键点 得到关键点参数
print(len(kp))
print (des.shape)
print (des[0])
#蛮力匹配
cs1 = cv2.imread("cs1.jpg")
cs2 = cv2.imread("cs2.jpg")
img1 = cv2.resize(cs1,(500,500))
img2 = cv2.resize(cs2,(500,500))
kp1 = sift.detect(img1,None)
kp2 = sift.detect(img2,None)
kp1,des1 = sift.compute(img1,kp1,img1)
kp2,des2 = sift.compute(img2,kp2,img2)
bf = cv2.BFMatcher(crossCheck=True) #计算本图特诊算子与对比图特征算子的距离并返回最小值
matches = bf.match(des1,des2)
matches = sorted(matches,key=lambda x:x.distance)
img3 = cv2.drawMatches(img1,kp1,img2,kp2,matches[:50],None,flags=2)
cv2.imshow("img3",img3)
cv2.waitKey(0)
cv2.destroyAllWindows()
#一对多的匹配
bf = cv2.BFMatcher()
matches2 = bf.knnMatch(des1,des2,k=2)
good = []
for m,n in matches2:
if m.distance<n.distance*0.75:
good.append([m])
img4 = cv2.drawMatches(img1,kp1,img2,kp2,good,None,flags=2)
cv2.imshow("img4",img4)
cv2.waitKey(0)
cv2.destroyAllWindows()
# FLANN
FLANN_INDEX_KDTREE = 1
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params,search_params)
matches = flann.knnMatch(des1,des2,k=2)
matchesMask = [[0,0] for i in range(len(matches))]
for i,(m,n) in enumerate(matches):
#如果第一个邻近距离比第二个邻近距离的0.7倍小,则保留
if m.distance < 0.7*n.distance:
matchesMask[i]=[1,0]
draw_params = dict(matchColor = (0,255,0),
singlePointColor = (255,0,0),
matchesMask = matchesMask,
flags = 0)
img5 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,matches,None,**draw_params)
cv2.imshow("img5",img5)
cv2.waitKey(0)
cv2.destroyAllWindows()
# plt.imshow(img3,),plt.show()


