python实现基于SIFT算法的图像配准(仿射变换)

话不多说,直接上代码,可以用的话别忘了请喝可乐!(手动笑哭脸)

【用法】

第45、46行的输入:

img1 = cv2.imread('sift/3.jpg')

img2 = cv2.imread('sift/4.jpg')

分别是两幅图像,改成你打算要配准的两幅图像即可(修改图像路径)。

python的跨平台特性好,windows和macOS系统都可用。输出:三幅图像。窗口1、窗口2是你输入的两幅图像,Result窗口展示的是本算法结果,即把img2移动变换到与img1匹配时的样子。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Apr 23 16:37:02 2019
SIFT
@author: youxinlin
"""

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/3.jpg')
img2 = cv2.imread('sift/4.jpg')
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.imshow('1',img1)
cv2.imshow('2',img2)
cv2.imshow('Result',result)


#cv2.imshow('Result',allImg)
if cv2.waitKey(2000) & 0xff == ord('q'):
    cv2.destroyAllWindows()
    cv2.waitKey(1) 

【注意】如果你懂python,并且懂数字图像技术原理,可以网上搜资料读一读。特别是本程序中用到的单应性矩阵、KNN、RANSAC算法等。不多解释了。另外本程序做了降采样以加快处理速度,请自行调整。如果想并排展示,请直接用cv2.imshow出allImg这个变量试试~

如果你要显示key points的配对结果(连线图),可以用:

macth_img = cv2.drawMatchesKnn(img1,kp1,img2,kp2,matches,None,flags=2)

然后show出macth_img。

 

部分代码来源整合于网络,仅供学习交流使用。

python实现基于SIFT算法的图像配准(仿射变换)_第1张图片

参考文献:Lowe, David G. "Object recognition from local scale-invariant features." iccv. Vol. 99. No. 2. 1999. 

你可能感兴趣的:(机器视觉/计算机视觉)