python利用sift和surf進行圖像配准


1.SIFT特征點和特征描述提取(注意opencv版本)

高斯金字塔:O組L層不同尺度的圖像(每一組中各層尺寸相同,高斯函數的參數不同,不同組尺寸遞減2倍)

特征點定位:極值點

特征點描述:根據不同bin下的方向給定一個主方向,對每個關鍵點,采用4*4*8共128維向量的描述子進項關鍵點表征,綜合效果最佳:

pip uninstall opencv-python
pip install opencv-contrib-python==3.4.2.16 
1.特征點檢測
def sift_kp(image):
    gray_image = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
    sift = cv2.xfeatures2d_SIFT.create()
    kp,des = sift.detectAndCompute(gray_image,None)
kp_image
= cv2.drawKeypoints(gray_image,kp,None) return kp_image,kp,des
2.SIFT特征點匹配
SIFT算法得到了圖像中的特征點以及相應的特征描述,一般的可以使用K近鄰(KNN)算法。K近鄰算法求取在空間中距離最近的K個數據點,並將這些數據點歸為一類。在進行特征點匹配時,一般使用KNN算法找到最近鄰的兩個數據點,如果最接近和次接近的比值大於一個既定的值,那么我們保留這個最接近的值,認為它和其匹配的點為good match
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

 3.單應性矩陣Homography Matrix

通過上面的步驟,我們找到了若干兩張圖中的匹配點,如何將其中一張圖通過旋轉、變換等方式將其與另一張圖對齊呢?這就用到了單應性矩陣了。Homography這個詞由Homo和graphy,Homo意為同一,graphy意為圖像,也就是同一個東西產生的圖像。
單應性矩陣有八個參數,如果要解這八個參數的話,需要八個方程,由於每一個對應的像素點可以產生2個方程(x一個,y一個),那么總共只需要四個像素點就能解出這個單應性矩陣。
RANSAC算法選擇其中最優的四個點

隨機抽樣一致算法(Random sample consensus:RANSAC)

H, status = cv2.findHomography(ptsA,ptsB,cv2.RANSAC,ransacReprojThreshold) #其中H為求得的單應性矩陣矩陣 #status則返回一個列表來表征匹配成功的特征點。 #ptsA,ptsB為關鍵點 #cv2.RANSAC, ransacReprojThreshold這兩個參數與RANSAC有關

4.圖像匹配

其中:

  • 第一個參數為需要投影的圖像(img2
  • 第二個參數為單應性矩陣(H
  • 第三個參數為所得圖像的矩陣大小((img1.shape[1],img1.shape[0]) )
  • 最后的參數cv2.INTER_LINEAR + cv2.WARP_INVERSE_MAP,為插值時使用的插值方法INTER_LINEAR,cv2.WARP_INVERSE_MAP則將M設置為dst--->src的方向變換。
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);
       imgOut = cv2.warpPerspective(img2, H, (img1.shape[1],img1.shape[0]),flags=cv2.INTER_LINEAR + cv2.WARP_INVERSE_MAP)
   return imgOut,H,status

  

5.綜合應用:

import numpy as np
import cv2
import Utility
img1 = cv2.imread('1.jpg')
img2 = cv2.imread('2.jpg')
result,_,_ = siftImageAlignment(img1,img2)
allImg = np.concatenate((img1,img2,result),axis=1)
cv2.namedWindow('Result',cv2.WINDOW_NORMAL)
cv2.imshow('Result',allImg)
cv2.waitKey(0)

6.SIFT速度太慢,利用surf檢測

def surf_kp(image):
    '''SIFT(surf)特征點檢測(速度比sift快)'''
    height, width = image.shape[:2]
    size = (int(width * 0.2), int(height * 0.2))
    shrink = cv2.resize(image, size, interpolation=cv2.INTER_AREA)
    gray_image = cv2.cvtColor(shrink,cv2.COLOR_BGR2GRAY)
    surf = cv2.xfeatures2d_SURF.create()
    kp, des = surf.detectAndCompute(gray_image, None)
    return kp,des

 為了再一次提升速度將圖片進行了縮放,再進行匹配的時候要對4對坐標點進行相應的放大即可。

ORB速度更快,不過效果較差


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM