Python+Opencv实现SIFT尺度不变特征转换图像配准(版本安装 + 源码)
为了做图像配准要用到SIFT,大概查了一下,MATLAB实现各种资源收费,Python加opencv因为cv版本和版权问题找不到xfeature。虽说是cv3.4.2之前版本都能用,但是python和3.4.x的cv配对版本又是试了好几遍从才行,实现过程一波三折,到处找资料,写文章记录一下。
opencv安装
现在经过测试,确实可以进行运行的版本为python3.7 + opencv3.4.2.16,开始还根据轮子网在找3.4的我,发现3.7也能,找了半天结果本身环境就能用,肝疼。
确保环境变量Path第一个是3.7(因为我用Anaconda3的默认环境是3.7.4所以这里第一个就是Anaconda3了)
WIN + R 输入 cmd打开控制台
输入
pip install opencv-python==3.4.2.16
显示successful后再输入
pip install opencv-contrib-python==3.4.2.16
显示successful后再输入pip list查看是否安装上
在列表中应该可以找到对应的库
SIFT的实现需要用的Numpy库,没有安装过的使用pip安装
pip install numpy
安装完后在cmd输入
import cv2
import numpy
尝试载入库,成功。
SIFT实现
实现代码很多,这里提供一种,出处见引用。
import numpy as np
import cv2
def sift_kp(image):
gray_image = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
sift = cv2.xfeatures2d_SIFT.create()
kp,des = sift.detectAndCompute(image,None)
kp_image = cv2.drawKeypoints(gray_image,kp,None)
return kp_image,kp,des
def get_good_match(des1,des2):
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)
return good
def siftImageAlignment(img1,img2):
_,kp1,des1 = sift_kp(img1)
_,kp2,des2 = sift_kp(img2)
goodMatch = get_good_match(des1,des2)
if len(goodMatch) > 4:
ptsA= np.float32([kp1[m.queryIdx].pt for m in goodMatch]).reshape(-1, 1, 2)
ptsB = np.float32([kp2[m.trainIdx].pt for m in goodMatch]).reshape(-1, 1, 2)
ransacReprojThreshold = 4
H, status =cv2.findHomography(ptsA,ptsB,cv2.RANSAC,ransacReprojThreshold);
#其中H为求得的单应性矩阵矩阵
#status则返回一个列表来表征匹配成功的特征点。
#ptsA,ptsB为关键点
#cv2.RANSAC, ransacReprojThreshold这两个参数与RANSAC有关
imgOut = cv2.warpPerspective(img2, H, (img1.shape[1],img1.shape[0]),flags=cv2.INTER_LINEAR + cv2.WARP_INVERSE_MAP)
return imgOut,H,status
img1 = cv2.imread('sift/1.tif')
img2 = cv2.imread('sift/5.tif')
while img1.shape[0] > 1000 or img1.shape[1] >1000:
img1 = cv2.resize(img1,None, fx=0.5,fy=0.5,interpolation = cv2.INTER_AREA)
while img2.shape[0] > 1000 or img2.shape[1] >1000:
img2 = cv2.resize(img2,None, fx=0.5,fy=0.5,interpolation = cv2.INTER_AREA)
result,_,_ = siftImageAlignment(img1,img2)
allImg = np.concatenate((img1,img2,result),axis=1)
cv2.namedWindow('1',cv2.WINDOW_NORMAL)
cv2.namedWindow('2',cv2.WINDOW_NORMAL)
cv2.namedWindow('Result',cv2.WINDOW_NORMAL)
cv2.imwrite('1.jpg',img1)
cv2.imwrite('2.jpg',img2)
cv2.imwrite('result.jpg',result)
#cv2.imshow('Result',allImg)
if cv2.waitKey(2000) & 0xff == ord('q'):
cv2.destroyAllWindows()
cv2.waitKey(1)
img1 = cv2.imread(‘sift/1.tif’)
img2 = cv2.imread(‘sift/5.tif’)为输入图像,图片路径和名称后缀根据需求修改
cv2.imwrite(‘result.jpg’,result)为以1为标准进行配准后的2图像
进行配准过后的遥感图像
模板
配准图像
引用
https://blog.csdn.net/weixin_43848827/article/details/104316721
https://blog.csdn.net/lyxleft/article/details/89476175