<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          圖像配準(zhǔn):基于 OpenCV 的高效實現(xiàn)

          共 4779字,需瀏覽 10分鐘

           ·

          2023-02-04 08:27

          點擊下方卡片,關(guān)注“新機(jī)器視覺”公眾號

          重磅干貨,第一時間送達(dá)

          在這篇文章中,我將對圖像配準(zhǔn)進(jìn)行一個簡單概述,展示一個最小的 OpenCV 實現(xiàn),并展示一個可以使配準(zhǔn)過程更加高效的簡單技巧。


          什么是圖像配準(zhǔn)


          圖像配準(zhǔn)被定義為將不同成像設(shè)備或傳感器在不同時間和角度拍攝的兩幅或多幅圖像,或來自同一場景的兩幅或多幅圖像疊加起來,以幾何方式對齊圖像以進(jìn)行分析的過程(Zitová 和 Flusser,2003 年)。


          百度百科給出的解釋


          圖像配準(zhǔn):圖像配準(zhǔn)(Image registration)就是將不同時間、不同傳感器(成像設(shè)備)或不同條件下(天候、照度、攝像位置和角度等)獲取的兩幅或多幅圖像進(jìn)行匹配、疊加的過程,它已經(jīng)被廣泛地應(yīng)用于遙感數(shù)據(jù)分析、計算機(jī)視覺、圖像處理等領(lǐng)域。


          醫(yī)學(xué)科學(xué)、遙感和計算機(jī)視覺都使用圖像配準(zhǔn)。


          有兩種主要方法:

          • 經(jīng)典計算機(jī)視覺方法(使用 OpenCV)——我們將在本文中關(guān)注的內(nèi)容

          • 基于深度學(xué)習(xí)的方法

          雖然后者可以更好地工作,但它可能需要一些“域”適應(yīng)(在你的數(shù)據(jù)上微調(diào)神經(jīng)網(wǎng)絡(luò))并且可能計算量太大。


          使用 OpenCV 進(jìn)行圖像配準(zhǔn)


          基于特征的方法:由單應(yīng)變換關(guān)聯(lián)的圖像對


          此操作試圖發(fā)現(xiàn)兩張照片之間的匹配區(qū)域并在空間上對齊它們以最大限度地減少錯誤。


          我們的目標(biāo)是找到一個單應(yīng)性矩陣 H,它告訴我們需要如何修改其中一張圖像,使其與另一張圖像完美對齊。


          第 1 步:關(guān)鍵點檢測


          關(guān)鍵點定義了圖像中一個獨特的小區(qū)域(角、邊緣、圖案)。關(guān)鍵點檢測器的一個重要方面是找到的區(qū)域應(yīng)該對圖像變換(例如定位、比例和亮度)具有魯棒性,因為這些區(qū)域很可能出現(xiàn)在我們試圖對齊的兩個圖像中。有許多執(zhí)行關(guān)鍵點檢測的算法,例如 SIFT、ORB、AKAZE、SURF 等。


          第 2 步:特征匹配


          現(xiàn)在我們必須匹配來自兩個圖像的關(guān)鍵點,這些關(guān)鍵點實際上對應(yīng)于同一點。


          第 3 步:單應(yīng)性


          單應(yīng)性通常由一個 3x3 矩陣表示,它描述了應(yīng)該應(yīng)用于一個圖像以與另一個圖像對齊的幾何變換。


          第 4 步:圖像變形


          找到單應(yīng)性矩陣后,我們可以用它來對齊圖像。下面是該過程的代碼:

          import numpy as npimport cv2 as cvimport matplotlib.pyplot as plt
          img1 = cv.imread('image1.jpg', cv.IMREAD_GRAYSCALE) # referenceImageimg2 = cv.imread('image2.jpg', cv.IMREAD_GRAYSCALE) # sensedImage
          # Initiate SIFT detectorsift_detector = cv.SIFT_create()# Find the keypoints and descriptors with SIFTkp1, des1 = sift_detector.detectAndCompute(img1, None)kp2, des2 = sift_detector.detectAndCompute(img2, None)
          # BFMatcher with default paramsbf = cv.BFMatcher()matches = bf.knnMatch(des1, des2, k=2)
          # Filter out poor matchesgood_matches = []for m,n in matches: if m.distance < 0.75*n.distance: good_matches.append(m)
          matches = good_matches points1 = np.zeros((len(matches), 2), dtype=np.float32)points2 = np.zeros((len(matches), 2), dtype=np.float32)
          for i, match in enumerate(matches): points1[i, :] = kp1[match.queryIdx].pt points2[i, :] = kp2[match.trainIdx].pt
          # Find homographyH, mask = cv2.findHomography(points1, points2, cv2.RANSAC)
          # Warp image 1 to align with image 2img1Reg = cv2.warpPerspective(img1, H, (img2.shape[1], img2.shape[0]))cv.imwrite('aligned_img1.jpg', img1Reg)The problem is that this matrix H is found via a compute-intensive optimization process.


          高效的圖像配準(zhǔn)

          無論您為每個步驟選擇的參數(shù)如何,對執(zhí)行時間影響最大的是圖像的分辨率。您可以大幅調(diào)整它們的大小,但如果您需要對齊的圖像具有原始分辨率,會發(fā)生什么情況?


          幸運(yùn)的是,有辦法解決這個問題。事實證明,您可以計算低分辨率圖像的變換,然后調(diào)整此變換以適用于全分辨率圖像。


          詳細(xì)步驟:

          1. 調(diào)整圖像大小

          2. 在低分辨率圖像上計算矩陣 H

          3. 變換矩陣 H 使其適用于全分辨率圖像

          4. 將新矩陣應(yīng)用于原始圖像。


          第 3 步可能是這里最不明顯的部分,所以讓我們看看它是如何工作的:


          我們想要調(diào)整在低分辨率圖像上計算的變換以適用于高分辨率圖像。因此,我們希望高分辨率圖像中的每個像素執(zhí)行以下操作:


          縮小到低分辨率 -> 應(yīng)用變換 H -> 放大到高分辨率


          幸運(yùn)的是,所有這些步驟都只是矩陣乘法,我們可以將所有這些步驟組合在一個單一的轉(zhuǎn)換中。


          設(shè) H 為您計算出的變換。您可以將 H 乘以另一個單應(yīng)性 A,得到 AH = H',其中 H' 是進(jìn)行兩種變換的單應(yīng)性,相當(dāng)于先應(yīng)用 H,然后應(yīng)用 A。


          下面是詳細(xì)代碼:

          import numpy as npimport cv2 as cvimport matplotlib.pyplot as plt
          img1 = cv.imread('image1.jpg', cv.IMREAD_GRAYSCALE) # referenceImageimg2 = cv.imread('image2.jpg', cv.IMREAD_GRAYSCALE) # sensedImage
          # Resize the image by a factor of 8 on each side. If your images are # very high-resolution, you can try to resize even more, but if they are # already small you should set this to something less agressive.resize_factor = 1.0/8.0
          img1_rs = cv.resize(img1, (0,0), fx=resize_factor, fy=resize_factor)img2_rs = cv.resize(img2, (0,0), fx=resize_factor, fy=resize_factor)
          # Initiate SIFT detector sift_detector = cv.SIFT_create()
          # Find the keypoints and descriptors with SIFT on the lower resolution imageskp1, des1 = sift_detector.detectAndCompute(img1_rs, None)kp2, des2 = sift_detector.detectAndCompute(img2_rs, None)
          # BFMatcher with default paramsbf = cv.BFMatcher()matches = bf.knnMatch(des1, des2, k=2)
          # Filter out poor matchesgood_matches = []for m,n in matches: if m.distance < 0.75*n.distance: good_matches.append(m)
          matches = good_matchespoints1 = np.zeros((len(matches), 2), dtype=np.float32)points2 = np.zeros((len(matches), 2), dtype=np.float32)
          for i, match in enumerate(matches): points1[i, :] = kp1[match.queryIdx].pt points2[i, :] = kp2[match.trainIdx].pt
          # Find homographyH, mask = cv2.findHomography(points1, points2, cv2.RANSAC)
          # Get low-res and high-res sizeslow_height, low_width = img1_rs.shapeheight, width = img1.shapelow_size = np.float32([[0, 0], [0, low_height], [low_width, low_height], [low_width, 0]])high_size = np.float32([[0, 0], [0, height], [width, height], [width, 0]])
          # Compute scaling transformationsscale_up = cv.getPerspectiveTransform(low_size, high_size)scale_down = cv.getPerspectiveTransform(high_size, low_size)
          # Combine the transformations. Remember that the order of the transformation # is reversed when doing matrix multiplication# so this is actualy scale_down -> H -> scale_uph_and_scale_up = np.matmul(scale_up, H)scale_down_h_scale_up = np.matmul(h_and_scale_up, scale_down)
          # Warp image 1 to align with image 2img1Reg = cv2.warpPerspective( img1, scale_down_h_scale_up, (img2.shape[1], img2.shape[0]) )
          cv.imwrite('aligned_img1.jpg', img1Reg)

          本文僅做學(xué)術(shù)分享,如有侵權(quán),請聯(lián)系刪文。

          —THE END—

          瀏覽 115
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人午夜性爱视频 | 中文字幕一区二区三区乱码 | 伊人婷婷狠狠 | 北条麻妃久久 | 精品久久福利视频 |