Python+Opencv实现SIFT(版本安装 + 实现代码)

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


版权声明:本文为electric_sheep原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。