亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

應用OpenCV和Python進行SIFT算法的實現詳解

系統 2048 0

應用OpenCV和Python進行SIFT算法的實現

如下圖為進行測試的gakki101和gakki102,分別驗證基于BFmatcher、FlannBasedMatcher等的SIFT算法,對比其優劣。為體現出匹配效果對于旋轉特性的優勢,將圖gakki101做成具有旋轉特性的效果。

應用OpenCV和Python進行SIFT算法的實現詳解_第1張圖片

基于BFmatcher的SIFT實現

BFmatcher(Brute-Force Matching)暴力匹配,應用BFMatcher.knnMatch( )函數來進行核心的匹配,knnMatch(k-nearest neighbor classification)k近鄰分類算法。

kNN算法則是從訓練集中找到和新數據最接近的k條記錄,然后根據他們的主要分類來決定新數據的類別。該算法涉及3個主要因素:訓練集、距離或相似的衡量、k的大小。kNN算法的核心思想是如果一個樣本在特征空間中的k個最相鄰的樣本中的大多數屬于某一個類別,則該樣本也屬于這個類別,并具有這個類別上樣本的特性。該方法在確定分類決策上只依據最鄰近的一個或者幾個樣本的類別來決定待分樣本所屬的類別。

kNN方法在類別決策時,只與極少量的相鄰樣本有關。由于kNN方法主要靠周圍有限的鄰近的樣本,而不是靠判別類域的方法來確定所屬類別的,因此對于類域的交叉或重疊較多的待分樣本集來說,kNN方法較其他方法更為適合。
經檢驗 BFmatcher在做匹配時會耗費大量的時間。

代碼段如下:

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

imgname1 = 'E:/other/gakki101.jpg'
imgname2 = 'E:/other/gakki102.jpg'

sift = cv2.xfeatures2d.SIFT_create()

img1 = cv2.imread(imgname1)
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY) #灰度處理圖像
kp1, des1 = sift.detectAndCompute(img1,None)  #des是描述子

img2 = cv2.imread(imgname2)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)#灰度處理圖像
kp2, des2 = sift.detectAndCompute(img2,None) #des是描述子

hmerge = np.hstack((gray1, gray2)) #水平拼接
cv2.imshow("gray", hmerge) #拼接顯示為gray
cv2.waitKey(0)

img3 = cv2.drawKeypoints(img1,kp1,img1,color=(255,0,255)) #畫出特征點,并顯示為紅色圓圈
img4 = cv2.drawKeypoints(img2,kp2,img2,color=(255,0,255)) #畫出特征點,并顯示為紅色圓圈
hmerge = np.hstack((img3, img4)) #水平拼接
cv2.imshow("point", hmerge) #拼接顯示為gray
cv2.waitKey(0)
# BFMatcher解決匹配
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1,des2, k=2)
# 調整ratio
good = []
for m,n in matches:
  if m.distance < 0.75*n.distance:
    good.append([m])

img5 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,matches,None,flags=2)
cv2.imshow("BFmatch", img5)
cv2.waitKey(0)
cv2.destroyAllWindows()
          

首先是針對圖像的灰度化顯示:

應用OpenCV和Python進行SIFT算法的實現詳解_第2張圖片

之后完成特征點的標注,用紅色圓圈表示:

應用OpenCV和Python進行SIFT算法的實現詳解_第3張圖片

在cv2.drawMatchesKnn(img1,kp1,img2,kp2,matches,None,flags=2)下的匹配效果,比較雜亂,且會出錯。

應用OpenCV和Python進行SIFT算法的實現詳解_第4張圖片

如果更換為cv2.drawMatchesKnn(img1,kp1,img2,kp2,good,None,flags=2),明顯優于上面的匹配,并且為預想的匹配區域,其效果為:

應用OpenCV和Python進行SIFT算法的實現詳解_第5張圖片

基于FlannBasedMatcher的SIFT實現

FLANN(Fast_Library_for_Approximate_Nearest_Neighbors)快速最近鄰搜索包,它是一個對大數據集和高維特征進行最近鄰搜索的算法的集合,而且這些算法都已經被優化過了。在面對大數據集時它的效果要好于 BFMatcher。
經驗證,FLANN比其他的最近鄰搜索軟件快10倍。使用 FLANN 匹配,我們需要傳入兩個字典作為參數。這兩個用來確定要使用的算法和其他相關參數等。

第一個是 IndexParams
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
這里使用的是KTreeIndex配置索引,指定待處理核密度樹的數量(理想的數量在1-16)。

第二個字典是 SearchParams
search_params = dict(checks=100) 用它來指定遞歸遍歷的次數。值越高結果越準確,但是消耗的時間也越多。實際上,匹配效果很大程度上取決于輸入。

5kd-trees 50checks 總能取得合理精度,而且短時間完成。在之下的代碼中,丟棄任何距離大于0.7的值,則可以避免幾乎90%的錯誤匹配,但是好的匹配結果也會很少。

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

imgname1 = 'E:/other/gakki101.jpg'
imgname2 = 'E:/other/gakki102.jpg'

sift = cv2.xfeatures2d.SIFT_create()

# FLANN 參數設計
FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params,search_params)

img1 = cv2.imread(imgname1)
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY) #灰度處理圖像
kp1, des1 = sift.detectAndCompute(img1,None)#des是描述子

img2 = cv2.imread(imgname2)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
kp2, des2 = sift.detectAndCompute(img2,None)

hmerge = np.hstack((gray1, gray2)) #水平拼接
cv2.imshow("gray", hmerge) #拼接顯示為gray
cv2.waitKey(0)

img3 = cv2.drawKeypoints(img1,kp1,img1,color=(255,0,255))
img4 = cv2.drawKeypoints(img2,kp2,img2,color=(255,0,255))

hmerge = np.hstack((img3, img4)) #水平拼接
cv2.imshow("point", hmerge) #拼接顯示為gray
cv2.waitKey(0)
matches = flann.knnMatch(des1,des2,k=2)
matchesMask = [[0,0] for i in range(len(matches))]

good = []
for m,n in matches:
  if m.distance < 0.7*n.distance:
    good.append([m])

img5 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,matches,None,flags=2)
cv2.imshow("FLANN", img5)
cv2.waitKey(0)
cv2.destroyAllWindows()
          

首先是針對圖像的灰度化顯示:

應用OpenCV和Python進行SIFT算法的實現詳解_第6張圖片

之后完成特征點的標注,用紅色圓圈表示:

應用OpenCV和Python進行SIFT算法的實現詳解_第7張圖片

在cv2.drawMatchesKnn(img1,kp1,img2,kp2,matches,None,flags=2)下的匹配效果,比較雜亂,且會出錯。

應用OpenCV和Python進行SIFT算法的實現詳解_第8張圖片

如果更換為cv2.drawMatchesKnn(img1,kp1,img2,kp2,good,None,flags=2),明顯優于上面的匹配,并且為預想的匹配區域,其效果為:

應用OpenCV和Python進行SIFT算法的實現詳解_第9張圖片

修改if m.distance < 0.7*n.distance:為 if m.distance < 1*n.distance:,顯示效果為:

應用OpenCV和Python進行SIFT算法的實現詳解_第10張圖片

可見,雖然值越大,匹配的線條越密集,但錯誤匹配點也會增多,在lowe論文中,Lowe推薦ratio的閾值為0.8,但作者對大量任意存在尺度、旋轉和亮度變化的兩幅圖片進行匹配,結果表明ratio取值在0. 4~0. 6 之間最佳,小于0. 4的很少有匹配點,大于0. 6的則存在大量錯誤匹配點,所以建議ratio的取值原則如下:

ratio=0. 4:對于準確度要求高的匹配;
ratio=0. 6:對于匹配點數目要求比較多的匹配;
ratio=0. 5:一般情況下。

基于FlannBasedMatcher的SURF實現

SURF全稱為“加速穩健特征”(Speeded Up Robust Feature),不僅是尺度不變特征,而且是具有較高計算效率的特征。可被認為SURF是尺度不變特征變換算法(SIFT算法)的加速版。SURF最大的特征在于采用了haar特征以及積分圖像的概念,SIFT采用的是DoG圖像,而SURF采用的是Hessian矩陣(SURF算法核心)行列式近似值圖像。SURF借鑒了SIFT算法中簡化近似的思想,實驗證明,SURF算法較SIFT算法在運算速度上要快3倍,綜合性優于SIFT算法。

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

imgname1 = 'E:/other/gakki101.jpg'
imgname2 = 'E:/other/gakki102.jpg'

surf = cv2.xfeatures2d.SURF_create()

FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params,search_params)

img1 = cv2.imread(imgname1)
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY) #灰度處理圖像
kp1, des1 = surf.detectAndCompute(img1,None)#des是描述子

img2 = cv2.imread(imgname2)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
kp2, des2 = surf.detectAndCompute(img2,None)

hmerge = np.hstack((gray1, gray2)) #水平拼接
cv2.imshow("gray", hmerge) #拼接顯示為gray
cv2.waitKey(0)

img3 = cv2.drawKeypoints(img1,kp1,img1,color=(255,0,255))
img4 = cv2.drawKeypoints(img2,kp2,img2,color=(255,0,255))

hmerge = np.hstack((img3, img4)) #水平拼接
cv2.imshow("point", hmerge) #拼接顯示為gray
cv2.waitKey(0)

matches = flann.knnMatch(des1,des2,k=2)

good = []
for m,n in matches:
  if m.distance < 0.7*n.distance:
    good.append([m])
img5 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,good,None,flags=2)
cv2.imshow("SURF", img5)
cv2.waitKey(0)
cv2.destroyAllWindows()
          

在cv2.drawMatchesKnn(img1,kp1,img2,kp2,matches,None,flags=2)下的匹配效果,比較雜亂,且會出錯。

應用OpenCV和Python進行SIFT算法的實現詳解_第11張圖片

如果更換為cv2.drawMatchesKnn(img1,kp1,img2,kp2,good,None,flags=2),明顯優于上面的匹配,并且為預想的匹配區域,其效果為:

應用OpenCV和Python進行SIFT算法的實現詳解_第12張圖片

但就其錯誤點數量和匹配效果而言,并沒有SIFT來的理想。

基于BFMatcher的ORB實現

ORB(Oriented Fast and Rotated BRIEF),結合Fast與Brief算法,并給Fast特征點增加了方向性,使得特征點具有旋轉不變性,并提出了構造金字塔方法,解決尺度不變性,但文章中沒有具體詳述。特征提取是由FAST(Features from Accelerated Segment Test)算法發展來的,特征點描述是根據BRIEF(Binary Robust Independent Elementary Features)特征描述算法改進的。ORB特征是將FAST特征點的檢測方法與BRIEF特征描述子結合起來,并在它們原來的基礎上做了改進與優化。ORB主要解決BRIEF描述子不具備旋轉不變性的問題。實驗證明,ORB遠優于之前的SIFT與SURF算法,ORB算法的速度是sift的100倍,是surf的10倍。

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

imgname1 = 'E:/other/gakki101.jpg'
imgname2 = 'E:/other/gakki102.jpg'

orb = cv2.ORB_create()

img1 = cv2.imread(imgname1)
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY) #灰度處理圖像
kp1, des1 = orb.detectAndCompute(img1,None)#des是描述子

img2 = cv2.imread(imgname2)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
kp2, des2 = orb.detectAndCompute(img2,None)

hmerge = np.hstack((gray1, gray2)) #水平拼接
cv2.imshow("gray", hmerge) #拼接顯示為gray
cv2.waitKey(0)

img3 = cv2.drawKeypoints(img1,kp1,img1,color=(255,0,255))
img4 = cv2.drawKeypoints(img2,kp2,img2,color=(255,0,255))

hmerge = np.hstack((img3, img4)) #水平拼接
cv2.imshow("point", hmerge) #拼接顯示為gray
cv2.waitKey(0)

# BFMatcher解決匹配
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1,des2, k=2)
# 調整ratio
good = []
for m,n in matches:
  if m.distance < 0.75*n.distance:
    good.append([m])

img5 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,good,None,flags=2)
cv2.imshow("ORB", img5)
cv2.waitKey(0)
cv2.destroyAllWindows()
          

經顯示觀察到,ORB算法在特征點標記時數量較少,如圖:

應用OpenCV和Python進行SIFT算法的實現詳解_第13張圖片

在cv2.drawMatchesKnn(img1,kp1,img2,kp2,matches,None,flags=2)下的匹配效果,比較雜亂,且會出錯。

應用OpenCV和Python進行SIFT算法的實現詳解_第14張圖片

如果更換為cv2.drawMatchesKnn(img1,kp1,img2,kp2,good,None,flags=2),明顯優于上面的匹配,并且為預想的匹配區域,其效果為:

應用OpenCV和Python進行SIFT算法的實現詳解_第15張圖片

但同樣會出現在同樣的匹配方式上,效果不如SIFT的現象。
如下為使用FAST作為特征描述的關鍵代碼和提取圖像顯示:

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

img = cv2.imread('E:/other/gakki102.',0)

fast=cv2.FastFeatureDetector_create()#獲取FAST角點探測器
kp=fast.detect(img,None)#描述符
img = cv2.drawKeypoints(img,kp,img,color=(255,255,0))#畫到img上面
print ("Threshold: ", fast.getThreshold())#輸出閾值
print ("nonmaxSuppression: ", fast.getNonmaxSuppression())#是否使用非極大值抑制
print ("Total Keypoints with nonmaxSuppression: ", len(kp))#特征點個數
cv2.imshow('fast',img)
cv2.waitKey(0)
          

如圖為FAST特征提取的圖像顯示:

應用OpenCV和Python進行SIFT算法的實現詳解_第16張圖片

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 中文字幕在线看 | www亚洲成人 | 亚洲一区天堂 | 亚洲欧美日韩久久精品第一区 | 在线观看 一区二区 麻豆 | 欧美13一16sex 性| 亚洲人妖女同在线播放 | 国产综合久久久久影院 | 日韩精品一区二区三区乱码 | 色网在线免费观看 | 天天射影院 | 狠狠色噜噜狠狠狠狠网站视频 | 中国一级特黄真人毛片免 | 四虎永久免费地址在线网站 | 欧美一区二区三区免费观看视频 | 欧美一级毛片免费高清aa | 亚洲国产欧美在线观看 | 日韩孕交japanese孕交 | 亚洲无总热门 | 亚洲国产成人久久 | 免费h片在线观看网址最新 免费v片在线观看无遮挡 | 精品伊人久久 | 国产亚洲综合色就色 | 在线免费一级片 | 91精品成人免费国产片 | www.国产| 久久综合丁香 | 国产精品视频福利一区二区 | 国产一区二区精品久久 | 色综合久久综合欧美综合 | 欧美同房免姿势108费视频 | 亚洲精品美女久久久久99 | 欧美久久视频 | 四虎欧美永久在线精品免费 | 亚洲国产高清视频 | 福利资源站 | 七色永久性tv网站免费看 | 免费精品视频 | 亚洲国产成人久久一区二区三区 | 日韩国产欧美一区二区三区 | 美女性色 |