日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

图像处理之图像特征匹配

發布時間:2025/3/15 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 图像处理之图像特征匹配 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在本章中, - 我們將看到如何將一個圖像中的特征與其他圖像進行匹配。 - 我們將在OpenCV中使用Brute-Force匹配器和FLANN匹配器
一、Brute-Force匹配器
它使用第一組中一個特征的描述符,并使用一些距離計算將其與第二組中的所有其他特征匹配。并返回最接近的一個。

對于BF匹配器,首先我們必須使用cv.BFMatcher()創建BFMatcher對象。 它需要兩個可選參數。第一個是normType,它指定要使用的距離測量。默認情況下為cv.NORM_L2。對于SIFT,SURF等(也有cv.NORM_L1)很有用。 對于基于二進制字符串的描述符,例如ORB,BRIEF,BRISK等,應使用cv.NORM_HAMMING,該函數使用漢明距離作為度量。如果ORB使用WTA_K == 3或4,則應使用cv.NORM_HAMMING2。

第二個參數是布爾變量,即crossCheck,默認情況下為false。如果為true,則Matcher僅返回具有值(i,j)的那些匹配項,以使集合A中的第i個描述符具有集合B中的第j個描述符為最佳匹配,反之亦然。即兩組中的兩個特征應彼此匹配。它提供了一致的結果,并且是D.Lowe在SIFT論文中提出的比率測試的良好替代方案。

創建之后,兩個重要的方法是BFMatcher.match()和BFMatcher.knnMatch()。第一個返回最佳匹配。第二種方法返回k個最佳匹配,其中k由用戶指定。當我們需要對此做其他工作時,它可能會很有用。

就像我們使用cv.drawKeypoints()繪制關鍵點一樣,cv.drawMatches()可以幫助我們繪制匹配項。它水平堆疊兩張圖像,并繪制從第一張圖像到第二張圖像的線,以顯示最佳匹配。還有cv.drawMatchesKnn繪制所有k個最佳匹配。如果k=2,它將為每個關鍵點繪制兩條匹配線。因此,如果要選擇性地繪制,則必須通過掩碼。
使用ORB描述符進行Brute-Force匹配

在這里,我們將看到一個有關如何在兩個圖像之間匹配特征的簡單示例。在這種情況下,我有一個queryImage和trainImage。我們將嘗試使用特征匹配在trainImage中找到queryImage。(圖像是/samples/data/box.png和/samples/data/box_in_scene.png)

我們正在使用ORB描述符來匹配特征。因此,讓我們從加載圖像,查找描述符等開始。

import numpy as np import cv2 as cv import matplotlib.pyplot as plt img1 = cv.imread('box.png',cv.IMREAD_GRAYSCALE) # 索引圖像 img2 = cv.imread('box_in_scene.png',cv.IMREAD_GRAYSCALE) # 訓練圖像 # 初始化ORB檢測器 orb = cv.ORB_create() # 基于ORB找到關鍵點和檢測器 kp1, des1 = orb.detectAndCompute(img1,None) kp2, des2 = orb.detectAndCompute(img2,None)

接下來,我們創建一個距離測量值為cv.NORM_HAMMING的BFMatcher對象(因為我們使用的是ORB),并且啟用了CrossCheck以獲得更好的結果。然后,我們使用Matcher.match()方法來獲取兩個圖像中的最佳匹配。我們按照距離的升序對它們進行排序,以使最佳匹配(低距離)排在前面。然后我們只抽出前10的匹配(只是為了提高可見度。您可以根據需要增加它)

# 創建BF匹配器的對象 bf = cv.BFMatcher(cv.NORM_HAMMING, crossCheck=True) # 匹配描述符. matches = bf.match(des1,des2) # 根據距離排序 matches = sorted(matches, key = lambda x:x.distance) # 繪制前10的匹配項 img3 = cv.drawMatches(img1,kp1,img2,kp2,matches[:10],None,flags=cv.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS) plt.imshow(img3),plt.show()

運行結果:

什么是Matcher對象?

matchs = bf.match(des1,des2)行的結果是DMatch對象的列表。該DMatch對象具有以下屬性: - DMatch.distance-描述符之間的距離。越低越好。 - DMatch.trainIdx-火車描述符中的描述符索引 - DMatch.queryIdx-查詢描述符中的描述符索引 - DMatch.imgIdx-火車圖像的索引。

帶有SIFT描述符和比例測試的Brute-Force匹配

這次,我們將使用BFMatcher.knnMatch()獲得k個最佳匹配。在此示例中,我們將k = 2,以便可以應用D.Lowe在他的論文中闡述的比例測試。

import numpy as np import cv2 as cv import matplotlib.pyplot as plt img1 = cv.imread('box.png',cv.IMREAD_GRAYSCALE) # 索引圖像 img2 = cv.imread('box_in_scene.png',cv.IMREAD_GRAYSCALE) # 訓練圖像 # 初始化SIFT描述符 sift = cv.xfeatures2d.SIFT_create() # 基于SIFT找到關鍵點和描述符 kp1, des1 = sift.detectAndCompute(img1,None) kp2, des2 = sift.detectAndCompute(img2,None) # 默認參數初始化BF匹配器 bf = cv.BFMatcher() matches = bf.knnMatch(des1,des2,k=2) # 應用比例測試 good = [] for m,n in matches:if m.distance < 0.75*n.distance:good.append([m]) # cv.drawMatchesKnn將列表作為匹配項。 img3 = cv.drawMatchesKnn(img1,kp1,img2,kp2,good,None,flags=cv.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS) plt.imshow(img3),plt.show()

查看結果:

三、基于匹配器的FLANN

FLANN是近似最近鄰的快速庫。它包含一組算法,這些算法針對大型數據集中的快速最近鄰搜索和高維特征進行了優化。對于大型數據集,它的運行速度比BFMatcher快。我們將看到第二個基于FLANN的匹配器示例。

對于基于FLANN的匹配器,我們需要傳遞兩個字典,這些字典指定要使用的算法,其相關參數等。第一個是IndexParams。對于各種算法,要傳遞的信息在FLANN文檔中進行了說明。概括來說,對于SIFT,SURF等算法,您可以通過以下操作:

FLANN_INDEX_KDTREE = 1 index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)

使用ORB時,你可以參考下面。根據文檔建議使用帶注釋的值,但在某些情況下未提供必需的參數。其他值也可以正常工作。

FLANN_INDEX_LSH = 6 index_params= dict(algorithm = FLANN_INDEX_LSH,table_number = 6, # 12key_size = 12, # 20multi_probe_level = 1) #2

第二個字典是SearchParams。它指定索引中的樹應遞歸遍歷的次數。較高的值可提供更好的精度,但也需要更多時間。如果要更改值,請傳遞search_params = dict(checks = 100)

import numpy as np import cv2 as cv import matplotlib.pyplot as plt img1 = cv.imread('box.png',cv.IMREAD_GRAYSCALE) # 索引圖像 img2 = cv.imread('box_in_scene.png',cv.IMREAD_GRAYSCALE) # 訓練圖像 # 初始化SIFT描述符 sift = cv.xfeatures2d.SIFT_create() # 基于SIFT找到關鍵點和描述符 kp1, des1 = sift.detectAndCompute(img1,None) kp2, des2 = sift.detectAndCompute(img2,None) # FLANN的參數 FLANN_INDEX_KDTREE = 1 index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5) search_params = dict(checks=50) # 或傳遞一個空字典 flann = cv.FlannBasedMatcher(index_params,search_params) matches = flann.knnMatch(des1,des2,k=2) # 只需要繪制好匹配項,因此創建一個掩碼 matchesMask = [[0,0] for i in range(len(matches))] # 根據Lowe的論文進行比例測試 for i,(m,n) in enumerate(matches):if m.distance < 0.7*n.distance:matchesMask[i]=[1,0] draw_params = dict(matchColor = (0,255,0),singlePointColor = (255,0,0),matchesMask = matchesMask,flags = cv.DrawMatchesFlags_DEFAULT) img3 = cv.drawMatchesKnn(img1,kp1,img2,kp2,matches,None,**draw_params) plt.imshow(img3,),plt.show()

運行結果:

總結

以上是生活随笔為你收集整理的图像处理之图像特征匹配的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。