訂閱
糾錯
加入自媒體

BEBLID:減少執(zhí)行時間的同時提高圖像匹配精度!

OpenCV發(fā)行版4.5.1包含了BEBLID,這是一個新的本地特性描述符。opencv4.5.1中最令人興奮的特性之一是BEBLID(Boosted effective Binary Local Image Descriptor),它是一種新的描述符,能夠在減少執(zhí)行時間的同時提高圖像匹配精度!本文將向你展示一個具體的例子,所有源代碼都存儲在此GitHub存儲庫中:https://github.com/iago-suarez/beblid-opencv-demo/blob/main/demo.ipynb在這個例子中,我們將通過一個視角的改變來匹配這兩個圖像:

首先,確保安裝了正確版本的OpenCV。

在你喜愛的環(huán)境中,你可以使用以下工具安裝和檢查OpenCV Contrib版本:pip install "opencv-contrib-python>=4.5.1"
python
>>> import cv2 as cv
>>> print(f"OpenCV Version: {cv.__version__}")
OpenCV Version: 4.5.1
在Python中加載這兩個圖像所需的代碼是:import cv2 as cv
# Load grayscale images
img1 = cv.imread("graf1.png", cv.IMREAD_GRAYSCALE)
img2 = cv.imread("graf3.png", cv.IMREAD_GRAYSCALE)
if img1 is None or img2 is None:
   print('Could not open or find the images。В
   exit(0)

為了評估我們的圖像匹配程序,我們需要在兩幅圖像之間進行正確的幾何變換。這是一個稱為單應性的3x3矩陣,當我們將第一個圖像中的一個點(在齊次坐標中)相乘時,它將返回第二個圖像中該點的坐標。讓我們加載它:# Load homography (geometric transformation between image)
fs = cv.FileStorage("H1to3p.xml", cv.FILE_STORAGE_READ)
homography = fs.getFirstTopLevelNode().mat()
print(f"Homography from img1 to img2:{homography}")

下一步是檢測圖像中容易在其他圖像中找到的部分:局部圖像特征。在這個例子中,我們將用一個快速可靠的探測器ORB來檢測角點。ORB通過比較不同尺度下的角點來檢測強角點,并利用FAST或Harris響應來選擇最佳的角點,同時它還使用局部分塊的一階矩來確定每個角點的方向。允許在每個圖像中檢測最多10000個角點:detector = cv.ORB_create(10000)
kpts1 = detector.detect(img1, None)
kpts2 = detector.detect(img2, None)

在下圖中,你可以看到用綠點標記的檢測響應最強的500個角點特征:

現(xiàn)在使用該方式來表示這些關(guān)鍵點,我們可以在另一幅圖中找到它們,這一步稱為描述,因為每個角點附近的局部分塊中的紋理由來自圖像上不同操作的數(shù)字向量表示(即描述)。有很多描述符,但如果我們想要一些準確的東西,即使在移動電話或低功耗設備上也能實時運行,OpenCV有兩種重要的方法:ORB(Oriented FAST and Rotated BRIEF):一個經(jīng)典的替代品,已經(jīng)有10年的歷史了,效果相當不錯。BEBLID(Boosted effective Binary Local Image Descriptor):2020年推出的一種新的描述符,在多個任務中被證明可以提高ORB。由于BEBLID適用于多種檢測方法,因此必須將ORB關(guān)鍵點的比例設置為0.75~1。# Comment or uncomment to use ORB or BEBLID
descriptor = cv.xfeatures2d.BEBLID_create(0.75)
# descriptor = cv.ORB_create()
kpts1, desc1 = descriptor.compute(img1, kpts1)
kpts2, desc2 = descriptor.compute(img2, kpts2)

現(xiàn)在是時候匹配兩幅圖像的描述符來建立對應關(guān)系了。讓我們使用暴力算法,基本上比較第一個圖像中的每個描述符與第二個圖像中的所有描述符。當我們處理二進制描述符時,比較是用漢明距離來完成的,也就是說,計算每對描述符之間不同的位數(shù)。這里還使用了一個稱為比率測試的小技巧,它不僅確保描述符1和2彼此相似,而且沒有其他描述符像2那樣接近1。matcher = cv.DescriptorMatcher_create(cv.DescriptorMatcher_BRUTEFORCE_HAMMING)
nn_matches = matcher.knnMatch(desc1, desc2, 2)
matched1 = []
matched2 = []
nn_match_ratio = 0.8  # Nearest neighbor matching ratio
for m, n in nn_matches:
   if m.distance < nn_match_ratio * n.distance:
       matched1.a(chǎn)ppend(kpts1[m.queryIdx])
       matched2.a(chǎn)ppend(kpts2[m.trainIdx])

因為我們知道正確的幾何變換,所以讓我們檢查有多少匹配是正確的(inliers)。如果圖2中的點和從圖1投射到圖2的點距離小于2.5像素,我們將認為它是有效的。inliers1 = []
inliers2 = []
good_matches = []
inlier_threshold = 2.5  # Distance threshold to identify inliers with homography check
for i, m in enumerate(matched1):
   # Create the homogeneous point
   col = np.ones((3, 1), dtype=np.float64)
   col[0:2, 0] = m.pt
   # Project from image 1 to image 2
   col = np.dot(homography, col)
   col /= col[2, 0]
   # Calculate euclidean distance
   dist = sqrt(pow(col[0, 0] - matched2[i].pt[0], 2) + pow(col[1, 0] - matched2[i].pt[1], 2))
   if dist < inlier_threshold:
       good_matches.a(chǎn)ppend(cv.DMatch(len(inliers1), len(inliers2), 0))
       inliers1.a(chǎn)ppend(matched1[i])
       inliers2.a(chǎn)ppend(matched2[i])

現(xiàn)在我們在inliers1和inliers2變量中具有正確的匹配項,我們可以使用cv.drawMatches對結(jié)果進行定性評估。每個對應點都可以幫助我們完成更高層次的任務,例如單應性估計,透視n點,平面跟蹤,實時姿態(tài)估計或圖像拼接。單應性估計:https://docs.opencv.org/4.5.1/d9/d0c/group__calib3d.html#ga4abc2ece9fab9398f2e560d53c8c9780透視n點:https://docs.opencv.org/4.5.1/d9/d0c/group__calib3d.html#ga549c2075fac14829ff4a58bc931c033d平面跟蹤:https://docs.opencv.org/4.5.1/dc/d16/tutorial_akaze_tracking.html實時姿態(tài)估計:https://docs.opencv.org/4.5.1/dc/d2c/tutorial_real_time_pose.html圖像拼接:https://docs.opencv.org/4.5.1/df/d8c/group__stitching__match.htmlres = np.empty((max(img1.shape[0], img2.shape[0]), img1.shape[1] + img2.shape[1], 3), dtype=np.uint8)
cv.drawMatches(img1, inliers1, img2, inliers2, good_matches, res)
plt.figure(figsize=(15, 5))
plt.imshow(res)

由于很難比較這種定性的結(jié)果,所以我們需要一些定量的評價指標,最能反映描述符可靠性的指標是inliers的百分比:

Matching Results (BEBLID)
*******************************
# Keypoints 1:                          9105
# Keypoints 2:                          9927
# Matches:                              660
# Inliers:                              512
# Percentage of Inliers:                77.57%

使用BEBLID描述符可以獲得77.57%的inliers。如果我們在description單元格中注釋BEBLID并取消注釋ORB descriptor,結(jié)果將下降到63.20%:# Comment or uncomment to use ORB or BEBLID
# descriptor = cv.xfeatures2d.BEBLID_create(0.75)
descriptor = cv.ORB_create()
kpts1, desc1 = descriptor.compute(img1, kpts1)
kpts2, desc2 = descriptor.compute(img2, kpts2)
Matching Results (ORB)
*******************************
# Keypoints 1:                          9105
# Keypoints 2:                          9927
# Matches:                              780
# Inliers:                              493
# Percentage of Inliers:                63.20%

總之,用BEBLID替換ORB描述符只需一行代碼,就可以將兩幅圖像的匹配結(jié)果提高14%,這對需要局部特征匹配才能工作的更高級別任務有很大收益。

聲明: 本文由入駐維科號的作者撰寫,觀點僅代表作者本人,不代表OFweek立場。如有侵權(quán)或其他問題,請聯(lián)系舉報。

發(fā)表評論

0條評論,0人參與

請輸入評論內(nèi)容...

請輸入評論/評論長度6~500個字

您提交的評論過于頻繁,請輸入驗證碼繼續(xù)

暫無評論

暫無評論

人工智能 獵頭職位 更多
掃碼關(guān)注公眾號
OFweek人工智能網(wǎng)
獲取更多精彩內(nèi)容
文章糾錯
x
*文字標題:
*糾錯內(nèi)容:
聯(lián)系郵箱:
*驗 證 碼:

粵公網(wǎng)安備 44030502002758號