zoukankan      html  css  js  c++  java
  • 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速度更快,不过效果较差

  • 相关阅读:
    简单明了的带你理解springboot原理和三大核心注解
    Spring Boot(一):入门篇
    【Mysql优化】聚簇索引与非聚簇索引概念
    Mysql索引原理与优化
    Mysql全文索引的使用
    索引的优缺点,如何创建索引
    184 01 Android 零基础入门 03 Java常用工具类03 Java字符串 02 String类 04 例:字符串与byte(即:字节)数组间的相互转换
    183 01 Android 零基础入门 03 Java常用工具类03 Java字符串 02 String类 03 String常用方法(下)
    182 01 Android 零基础入门 03 Java常用工具类03 Java字符串 02 String类 02 String常用方法(上)
    181 01 Android 零基础入门 03 Java常用工具类03 Java字符串 02 String类 01 String常用方法简介
  • 原文地址:https://www.cnblogs.com/lzq116/p/11836657.html
Copyright © 2011-2022 走看看