機器學習進階-案例實戰-圖像全景拼接-圖像全景拼接(RANSCA) 1.sift.detectAndComputer(獲得sift圖像關鍵點) 2.cv2.findHomography(計算單應性矩陣H) 3.cv2.warpPerspective(獲得單應性變化后的圖像) 4.cv2.line(對關鍵點位置進行連線畫圖)


1. sift.detectAndComputer(gray, None)  # 計算出圖像的關鍵點和sift特征向量

參數說明:gray表示輸入的圖片

2.cv2.findHomography(kpA, kpB, cv2.RANSAC, reproThresh) # 計算出單應性矩陣

參數說明:kpA表示圖像A關鍵點的坐標, kpB圖像B關鍵點的坐標, 使用隨機抽樣一致性算法來進行迭代,reproThresh表示每次抽取樣本的個數

3.cv2.warpPespective(imageA, H, (imageA.shape[1] + imageB.shape[1], imageA.shape[0]))  # 獲得根據單應性矩陣變化后的圖像

參數說明:image表示輸入圖像,H表示單應性的矩陣,(imageA.shape[1] + imageB.shape[1], imageA.shape[0])表示矩陣變化后的維度

4. cv2.line(imageA, kpsA, imageB, kpsB, (0,0,255), 2)   進行畫出直線的操作
參數說明:imageA和imageB表示輸入圖片, kpsA和kpsB表示關鍵點的坐標(x, y) ,(0, 0, 255)表示顏色, 2表示直線的寬度 

 

RANSAC算法(隨機抽樣一致性算法), 對於左邊的圖,可以看到使用最小二乘法盡可能多的滿足點可以分布在擬合曲線周圍,減小均分根誤差,因此擬合的曲線在一定程度上容易發生偏離,而RANSAC卻不會出現這種情況

RANSCA原理, 因為擬合一條直線只需要兩個點,因此我們每次隨機選取兩個點,做出直線,划定一個距離,判斷落在直線周圍距離范圍點的個數,不斷的迭代,直到找出擬合的直線,使得點落在上面最多的擬合曲線

圖像拼接的關鍵是在於對圖像進行變化,變化后的點與需要拼接的圖片中的sift點,越接近,即歐式距離越短,對圖像拼接的過程中,至少需要有4對特征點,求取變化矩陣Hi

我們使用RANSAC不斷去取隨機從兩個圖像中取4對的sift特征點,計算出H,定義損失值,即x’,與x的距離,即y‘與y的距離之和是否是最小值,不斷迭代,找出最佳的H

 

上述就是計算出來了H值,也就是變化矩陣

代碼思路:

第一步:對圖像進行灰度化,使用sift.detectAndCompute(image, None) 進行ksp關鍵點,dpSIFT特征向量,將kps進行向量化操作,即kps.pt 

第二步:構建BMFmatch匹配器,獲得符合條件的匹配值,matches獲得的是ksp關鍵點的匹配值得索引,使用索引獲得符合條件的kspA和kspB

第三步:使用cv2.findHomography(kpA, kpB, cv2.RANSAC,reproThresh) 隨機抽取4個點,求得最合適的H變化矩陣

第四步:使用獲得的變化矩陣H, cv.warpPerspective 對imageA求取變化后的圖像

第五步:將imageB加入到變化后的圖像獲得最終圖像

第六步:如果需要進行展示,構造新的圖像,尺寸為imageA.shape[0], imageB.shape[1] +imageA.shape[1], 使用matches的索引,使用cv2.line將符合條件的點進行連接

第七步:返回最終的結果,進行畫圖展示

import cv2
import numpy as np
import matplotlib.pyplot as plt


class Stitcher:

    def stitch(self, imgs, ratio=0.75, reproThresh=4, showMathes = False):

        (imageB, imageA) = imgs
        # 第一步:計算kpsA和dpsA
        (kpsA, dpsA) = self.detectandcompute(imageA)
        (kpsB, dpsB) = self.detectandcompute(imageB)
        # 獲得變化的矩陣H
        M = self.matchKeypoint(kpsA, dpsA, kpsB, dpsB, ratio, reproThresh)

        if M is None:
            return None
        (matches, H, status) = M

        # 第四步:使用cv2.warpPerspective獲得經過H變化后的圖像
        result = cv2.warpPerspective(imageA, H, (imageA.shape[1] + imageB.shape[1], imageB.shape[0]))
        
        # 第五步:將圖像B填充到進過H變化后的圖像,獲得最終的圖像
        result[0:imageB.shape[0], 0:imageB.shape[1]] = imageB

        if showMathes:
            # 第六步:對圖像的關鍵點進行連接
            via = self.showMatches(imageA, imageB, kpsA, kpsB, matches, status)

            return (via, result)

        return result



        # 進行畫圖操作


    def showMatches(self, imageA, imageB, kpsA, kpsB, matches, status):
        # 將兩個圖像進行拼接
        # 根據圖像的大小,構造全零矩陣
        via = np.zeros((max(imageB.shape[0], imageA.shape[0]), imageA.shape[1] + imageB.shape[1], 3), np.uint8)
        # 將圖像A和圖像B放到全部都是零的圖像中
        via[0:imageA.shape[0], 0:imageA.shape[1]] = imageA
        via[0:imageB.shape[0], imageA.shape[1]:] = imageB
        # 根據matches中的索引,構造出點的位置信息
        for (trainIdx, queryIdx), s in zip(matches, status):
            if s==1:
                ptA = (int(kpsA[queryIdx][0]), int(kpsA[queryIdx][1]))
                ptB = (int(kpsB[trainIdx][0] + imageA.shape[1]), int(kpsB[trainIdx][1]))
                # 使用cv2.line進行畫圖操作
                cv2.line(via, ptA, ptB, (0, 255, 0), 1)

        return via




    def matchKeypoint(self, kpsA, dpsA, kpsB, dpsB, ratio, reproThresh):

        # 第二步:實例化BFM匹配, 找出符合添加的關鍵點的索引
        bf = cv2.BFMatcher()

        matcher = bf.knnMatch(dpsA, dpsB, 2)

        matches = []

        for match in matcher:

            if len(match) == 2 and match[0].distance < match[1].distance * ratio:
                # 加入match[0]的索引
                matches.append((match[0].trainIdx, match[0].queryIdx))
        #第三步:使用cv2.findHomography找出符合添加的H矩陣
        if len(matches) > 4:
            # 根據索引找出符合條件的位置
            kpsA = np.float32([kpsA[i] for (_, i) in matches])
            kpsB = np.float32([kpsB[i] for (i, _) in matches])
            (H, status) = cv2.findHomography(kpsA, kpsB, cv2.RANSAC, reproThresh)

            return (matches, H, status)
        return None


    def cv_show(self, img, name):
        cv2.imshow(name, img)


    def detectandcompute(self, image):
        # 進行灰度值轉化
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        #實例化sift函數
        sift = cv2.xfeatures2d.SIFT_create()
        # 獲得kps關鍵點和dps特征向量sift
        kps, dps = sift.detectAndCompute(gray, None)
        # 獲得特征點的位置信息, 並轉換數據類型
        kps = np.float32([kp.pt for kp in kps])

        return (kps, dps)

    使用cv2.warpPesctive即根據H變化后的圖片                                  經過圖像拼接后的result圖片                                          經過圖片關鍵點連接的圖片

 


免責聲明!

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



猜您在找 機器學習進階-案例實戰-圖像全景拼接-書籍SIFT特征點連接 1.cv2.drawMatches(對兩個圖像的關鍵點進行連線操作) 機器學習進階-圖像特征sift-SIFT特征點 1.cv2.xfeatures2d.SIFT_create(實例化sift) 2. sift.detect(找出關鍵點) 3.cv2.drawKeypoints(畫出關鍵點) 4.sift.compute(根據關鍵點計算sift向量) 機器學習進階-光流估計 1.cv2.goodFeaturesToTrack(找出光流估計所需要的角點) 2.cv2.calcOpticalFlowPyrLK(獲得光流檢測后的角點位置) 3.cv2.add(進行像素點的加和) 機器學習進階-圖像金字塔與輪廓檢測-輪廓檢測 1.cv2.cvtColor(圖像顏色轉換) 2.cv2.findContours(找出圖像的輪廓) 3.cv2.drawContours(畫出圖像輪廓) 4.cv2.contourArea(輪廓面積) 5.cv2.arcLength(輪廓周長) 6.cv2.aprroxPloyDP(獲得輪廓近似) 7.cv2.boudingrect(外接圓).. 基於RANSAC的圖像全景拼接 機器學習進階-直方圖與傅里葉變換-傅里葉變換(高低通濾波) 1.cv2.dft(進行傅里葉變化) 2.np.fft.fftshift(將低頻移動到圖像的中心) 3.cv2.magnitude(計算矩陣的加和平方根) 4.np.fft.ifftshift(將低頻和高頻移動到原來位置) 5.cv2.idft(傅里葉逆變換) 機器學習進階-項目實戰-信用卡數字識別 1.cv2.findContour(找出輪廓) 2.cv2.boudingRect(輪廓外接矩陣位置) 3.cv2.threshold(圖片二值化操作) 4.cv2.MORPH_TOPHAT(禮帽運算突出線條) 5.cv2.MORPH_CLOSE(閉運算圖片內部膨脹) 6. cv2.resize(改變圖像大小) 7.cv2.putText(在圖片上放上文本) 機器學習進階-目標跟蹤-KCF目標跟蹤方法 1.cv2.multiTracker_create(構造選框集合) 2. cv2.TrackerKCF_create(獲得KCF追蹤器) 3. cv2.resize(變化圖像大小) 4.cv2.selectROI(在圖像上框出選框) opencv實戰-全景圖像拼接 計算兩幅圖的單應矩陣,實現圖像拼接
 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM