最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python OpenCV學(xué)習(xí)之特征點(diǎn)檢測(cè)與匹配詳解

 更新時(shí)間:2022年01月17日 15:21:43   作者:一個(gè)熱愛(ài)學(xué)習(xí)的深度渣渣  
提取圖像的特征點(diǎn)是圖像領(lǐng)域中的關(guān)鍵任務(wù),不管在傳統(tǒng)還是在深度學(xué)習(xí)的領(lǐng)域中,特征代表著圖像的信息,對(duì)于分類、檢測(cè)任務(wù)都是至關(guān)重要的。這篇文章主要為大家詳細(xì)介紹了OpenCV特征點(diǎn)檢測(cè)與匹配,需要的可以參考一下

背景

提取圖像的特征點(diǎn)是圖像領(lǐng)域中的關(guān)鍵任務(wù),不管在傳統(tǒng)還是在深度學(xué)習(xí)的領(lǐng)域中,特征代表著圖像的信息,對(duì)于分類、檢測(cè)任務(wù)都是至關(guān)重要的;

特征點(diǎn)應(yīng)用的一些場(chǎng)景:

圖像搜索:以圖搜圖(電商、教育領(lǐng)域)

圖像拼接:全景拍攝(關(guān)聯(lián)圖像拼接)

拼圖游戲:游戲領(lǐng)域

一、Harris角點(diǎn)

哈里斯角點(diǎn)檢測(cè)主要有以下三種情況:

  • 光滑區(qū)域:無(wú)論向哪個(gè)方向移動(dòng),衡量系數(shù)不變;
  • 邊緣區(qū)域:垂直邊緣移動(dòng)時(shí),衡量系數(shù)變化強(qiáng)烈;
  • 角點(diǎn)區(qū)域:不管往哪個(gè)方向移動(dòng),衡量系數(shù)變化強(qiáng)烈;

函數(shù)原型:

cornerHarris(img,blockSize,ksize,k)

blockSize:檢測(cè)窗口大??;

k:權(quán)重系數(shù),一般取0.02~0.04之間;

代碼案例:

img = cv2.imread('chess.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

dst = cv2.cornerHarris(gray, 2, 3, 0.04)

img[dst > 0.01*dst.max()] = (0, 0, 255)

cv2.imshow('harris', img)
cv2.waitKey(0)

二、Shi-Tomasi角點(diǎn)檢測(cè)

說(shuō)明:是Harris角點(diǎn)檢測(cè)的改進(jìn),在Harris中需要知道k這個(gè)經(jīng)驗(yàn)值,而在Shi-Tomasi不需要;

函數(shù)原型:

goodFeaturesToTrack(img,…)

maxCorners:角點(diǎn)的最大數(shù)量,值為0表示所有;

qualityLevel:角點(diǎn)的質(zhì)量,一般在0.01~0.1之間(低于的過(guò)濾掉);

minDistance:角點(diǎn)之間最小歐式距離,忽略小于此距離的點(diǎn);

mask:感興趣區(qū)域;

useHarrisDetector:是否使用Harris算法(默認(rèn)為false)

代碼案例:

img = cv2.imread('chess.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

dst = cv2.goodFeaturesToTrack(gray, 1000, 0.01, 10)
dst = np.int0(dst) ? ? ? ? ? ?# 實(shí)際上也是np.int64
for i in dst:
? ? x, y = i.ravel() ? ? ? ? # 數(shù)組降維成一維數(shù)組(inplace的方式)
? ? cv2.circle(img, (x, y), 3, (0, 0, 255), -1)

cv2.imshow('harris', img)
cv2.waitKey(0)

本質(zhì)上和Harris角點(diǎn)檢測(cè)相同,效果會(huì)好一些,角點(diǎn)數(shù)量會(huì)多一些;

三、SIFT關(guān)鍵點(diǎn)

中文簡(jiǎn)譯:與縮放無(wú)關(guān)的特征轉(zhuǎn)換;

說(shuō)明:Harris角點(diǎn)檢測(cè)具有旋轉(zhuǎn)不變性,也就是旋轉(zhuǎn)圖像并不會(huì)影響檢測(cè)效果;但其并不具備縮放不變性,縮放大小會(huì)影響角點(diǎn)檢測(cè)的效果;SIFT具備縮放不變性的性質(zhì);

實(shí)現(xiàn)步驟:

創(chuàng)建SIFT對(duì)象 —— 進(jìn)行檢測(cè)(sift.detect) —— 繪制關(guān)鍵點(diǎn)(drawKeypoints)

代碼案例:

img = cv2.imread('chess.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

sift = cv2.xfeatures2d.SIFT_create()
kp = sift.detect(gray, None) ? ? ?# 第二個(gè)參數(shù)為mask區(qū)域
cv2.drawKeypoints(gray, kp, img)

cv2.imshow('sift', img)
cv2.waitKey(0)

四、SIFT描述子

首先需要說(shuō)明,關(guān)鍵點(diǎn)和描述子是兩個(gè)概念;

關(guān)鍵點(diǎn):位置、大小和方向;

關(guān)鍵點(diǎn)描述子:記錄了關(guān)鍵點(diǎn)周圍對(duì)其有貢獻(xiàn)的像素點(diǎn)的一組向量值,其不受仿射變換,光照變換等影響;描述子的作用就是用于特征匹配;

同時(shí)計(jì)算關(guān)鍵點(diǎn)和描述子的函數(shù)(主要使用):

detectAndCompute(img,…)

代碼案例:

img = cv2.imread('chess.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

sift = cv2.xfeatures2d.SIFT_create()
kp, dst = sift.detectAndCompute(gray, None) ? ? ?# 第二個(gè)參數(shù)為mask區(qū)域

得到的dst即為描述子的信息;

五、SURF

中譯:加速的魯棒性特征檢測(cè);

說(shuō)明:SIFT最大的缺點(diǎn)是速度慢,因此才會(huì)有SURF(速度快);

實(shí)現(xiàn)步驟與SIFT一致,代碼如下:

surf = cv2.xfeatures2d.SURF_create()
kp, dst = surf.detectAndCompute(gray, None)      # 第二個(gè)參數(shù)為mask區(qū)域
cv2.drawKeypoints(gray, kp, img)

由于安裝的opencv-contrib版本過(guò)高(有版權(quán)問(wèn)題),已經(jīng)不支持該功能了,在此就不作展示了;

六、ORB

說(shuō)明:最大的優(yōu)勢(shì)就是做到實(shí)時(shí)檢測(cè),缺點(diǎn)就是缺失了很多信息(準(zhǔn)確性下降);

主要是兩個(gè)技術(shù)的結(jié)合:FAST(特征點(diǎn)實(shí)時(shí)檢測(cè))+ BRIEE(快速描述子建立,降低特征匹配時(shí)間)

使用步驟與之前的SIFT一致,代碼如下:

img = cv2.imread('chess.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

orb = cv2.ORB_create()
kp, dst = orb.detectAndCompute(gray, None) ? ? ?# 第二個(gè)參數(shù)為mask區(qū)域
cv2.drawKeypoints(gray, kp, img)

cv2.imshow('orb', img)
cv2.waitKey(0)

可以看出,相比于SIFT以及SURF關(guān)鍵點(diǎn)變少了,但是其速度有了很大提升;

七、暴力特征匹配(BF)

匹配原理:類似于窮舉匹配機(jī)制,使用第一組中每個(gè)特征的描述子與第二組中的進(jìn)行匹配,計(jì)算相似度,返回最接近的匹配項(xiàng);

實(shí)現(xiàn)步驟:

創(chuàng)建匹配器:BFMatcher(normType,crossCheck)

進(jìn)行特征匹配:bf.match(des1,des2)

繪制匹配點(diǎn):cv2.drawMatches(img1,kp1,img2,kp2)

代碼案例:

img1 = cv2.imread('opencv_search.png')
img2 = cv2.imread('opencv_orig.png')
g1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
g2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

sift = cv2.SIFT_create()
kp1, dst1 = sift.detectAndCompute(g1, None) ? ? ?# 第二個(gè)參數(shù)為mask區(qū)域
kp2, dst2 = sift.detectAndCompute(g2, None) ? ? ?# 第二個(gè)參數(shù)為mask區(qū)域

bf = cv2.BFMatcher_create(cv2.NORM_L1)
match = bf.match(dst1, dst2)
img3 = cv2.drawMatches(img1, kp1, img2, kp2, match, None)

cv2.imshow('result', img3)
cv2.waitKey(0)

從上圖可看出,匹配的效果還是不錯(cuò)的,只有一個(gè)特征點(diǎn)匹配錯(cuò)誤;

八、FLANN特征匹配

優(yōu)點(diǎn):在進(jìn)行批量特征匹配時(shí),F(xiàn)LANN速度更快;

缺點(diǎn):由于使用的時(shí)鄰近近似值,所有精度較差;

實(shí)現(xiàn)步驟與暴力匹配法一致,代碼如下:

img1 = cv2.imread('opencv_search.png')
img2 = cv2.imread('opencv_orig.png')
g1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
g2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

sift = cv2.SIFT_create()
kp1, dst1 = sift.detectAndCompute(g1, None) ? ? ?# 第二個(gè)參數(shù)為mask區(qū)域
kp2, dst2 = sift.detectAndCompute(g2, None) ? ? ?# 第二個(gè)參數(shù)為mask區(qū)域

index_params = dict(algorithm = 1, trees = 5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params, search_params)
matchs = flann.knnMatch(dst1, dst2, k=2)

good = []
for i, (m, n) in enumerate(matchs):
? ? if m.distance < 0.7 * n.distance:
? ? ? ? good.append(m)
img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, [good], None)

cv2.imshow('result', img3)
cv2.waitKey(0)

上圖可以看出,匹配的特征點(diǎn)數(shù)量相比暴力匹配明顯變少了,但速度會(huì)快很多;

九、圖像查找

實(shí)現(xiàn)原理:特征匹配 + 單應(yīng)性矩陣;

單應(yīng)性矩陣原理介紹:

上圖中表示從兩個(gè)不同角度對(duì)原圖的拍攝,其中H為單應(yīng)性矩陣,可通過(guò)該矩陣將圖像進(jìn)行轉(zhuǎn)換;

下面使用兩個(gè)函數(shù)實(shí)現(xiàn)圖像查找的功能:

findHomography():獲得單應(yīng)性矩陣;

perspectivveTransform():仿射變換函數(shù);

代碼實(shí)現(xiàn)如下:

img1 = cv2.imread('opencv_search.png')
img2 = cv2.imread('opencv_orig.png')
g1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
g2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

sift = cv2.SIFT_create()
kp1, dst1 = sift.detectAndCompute(g1, None) ? ? ?# 第二個(gè)參數(shù)為mask區(qū)域
kp2, dst2 = sift.detectAndCompute(g2, None) ? ? ?# 第二個(gè)參數(shù)為mask區(qū)域

index_params = dict(algorithm = 1, trees = 5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params, search_params)
matchs = flann.knnMatch(dst1, dst2, k=2)

good = []
for i, (m, n) in enumerate(matchs):
? ? if m.distance < 0.7 * n.distance:
? ? ? ? good.append(m)
if len(good) >= 4:
?? ?# 獲得源和目標(biāo)點(diǎn)的數(shù)組
? ? srcPts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)
? ? dstPts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)
? ??
? ? # 獲得單應(yīng)性矩陣H
? ? H, _ = cv2.findHomography(srcPts, dstPts, cv2.RANSAC, 5.0)
? ? h, w = img1.shape[:2]
? ? pts = np.float32([[0,0], [0, h-1], [w-1, h-1], [w-1, 0]]).reshape(-1, 1, 2)
? ? # 進(jìn)行放射變換
? ? dst = cv2.perspectiveTransform(pts, H)
? ??
? ? # 繪制查找到的區(qū)域
? ? cv2.polylines(img2, [np.int32(dst)], True, (0,0,255))
else:
? ? print('good must more then 4.')
? ? exit()
? ??
img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, [good], None)

cv2.imshow('result', img3)
cv2.waitKey(0)

總結(jié)

本篇主要介紹了特征點(diǎn)檢測(cè)和匹配,其中重要的部分時(shí)SIFT算法以及FLANN算法;通過(guò)所學(xué)的知識(shí),可以簡(jiǎn)單實(shí)現(xiàn)一個(gè)圖像查找的功能,也就是找子圖的功能。甚至可以目標(biāo)識(shí)別的效果;當(dāng)然這里需要的是完全一致的,不同于深度學(xué)習(xí)中的目標(biāo)識(shí)別任務(wù)

以上就是Python OpenCV學(xué)習(xí)之特征點(diǎn)檢測(cè)與匹配詳解的詳細(xì)內(nèi)容,更多關(guān)于Python OpenCV特征點(diǎn)檢測(cè)與匹配的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • python爬蟲 貓眼電影和電影天堂數(shù)據(jù)csv和mysql存儲(chǔ)過(guò)程解析

    python爬蟲 貓眼電影和電影天堂數(shù)據(jù)csv和mysql存儲(chǔ)過(guò)程解析

    這篇文章主要介紹了python爬蟲 貓眼電影和電影天堂數(shù)據(jù)csv和mysql存儲(chǔ)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • python 實(shí)現(xiàn)將多條曲線畫在一幅圖上的方法

    python 實(shí)現(xiàn)將多條曲線畫在一幅圖上的方法

    今天小編就為大家分享一篇python 實(shí)現(xiàn)將多條曲線畫在一幅圖上的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-07-07
  • odoo字段訪問(wèn)控制的操作方法

    odoo字段訪問(wèn)控制的操作方法

    在 Odoo 中,可以通過(guò)幾種方式實(shí)現(xiàn)字段的訪問(wèn)控制?0c;包括通過(guò)模型安全規(guī)則、記錄規(guī)則和字段屬性來(lái)限制字段的訪問(wèn),這篇文章主要介紹了odoo字段訪問(wèn)控制的相關(guān)操作,感興趣的朋友跟隨小編一起看看吧
    2024-03-03
  • python寫日志文件操作類與應(yīng)用示例

    python寫日志文件操作類與應(yīng)用示例

    這篇文章主要介紹了python寫日志文件操作類與應(yīng)用,結(jié)合實(shí)例形式分析了Python日志文件操作類的定義與使用相關(guān)操作技巧,需要的朋友可以參考下
    2019-07-07
  • 利用python合并csv文件的方式實(shí)例

    利用python合并csv文件的方式實(shí)例

    由于項(xiàng)目取數(shù)需要,要將兩個(gè)不同的csv文件合并到一個(gè)文件中,所以下面這篇文章主要給大家介紹了關(guān)于利用python合并csv文件的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • Python面向?qū)ο缶幊讨惖睦^承

    Python面向?qū)ο缶幊讨惖睦^承

    這篇文章主要介紹了Python面向?qū)ο缶幊讨惖睦^承,繼承Inheritance是指代碼復(fù)用的高級(jí)抽象,繼承是面向?qū)ο笤O(shè)計(jì)的精髓之一,實(shí)現(xiàn)了以類為單位的高級(jí)抽象級(jí)別代碼復(fù)用,下面進(jìn)入文章看該內(nèi)容的下詳情
    2021-11-11
  • Python數(shù)據(jù)庫(kù)安裝及MySQL?Connector應(yīng)用教程

    Python數(shù)據(jù)庫(kù)安裝及MySQL?Connector應(yīng)用教程

    這篇文章主要為大家介紹了Python數(shù)據(jù)庫(kù)安裝及MySQL Connector應(yīng)用教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • OpenCV全景圖像拼接的實(shí)現(xiàn)示例

    OpenCV全景圖像拼接的實(shí)現(xiàn)示例

    opencv其實(shí)自己就有實(shí)現(xiàn)圖像拼接的算法,當(dāng)然效果也是相當(dāng)好的,本文主要介紹了OpenCV全景圖像拼接,感興趣的可以一起來(lái)了解一下
    2021-06-06
  • Python中使用?zipfile創(chuàng)建文件壓縮工具

    Python中使用?zipfile創(chuàng)建文件壓縮工具

    這篇文章主要介紹了Python中使用zipfile創(chuàng)建文件壓縮工具,通過(guò)使用 wxPython 模塊,我們創(chuàng)建了一個(gè)簡(jiǎn)單而實(shí)用的文件壓縮工具,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的ca參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09
  • 關(guān)于Python中的if __name__ == __main__詳情

    關(guān)于Python中的if __name__ == __main__詳情

    在學(xué)習(xí)Python的過(guò)程中發(fā)現(xiàn)即使把if __name__ == ‘__main__’ 去掉,程序還是照樣運(yùn)行。很多小伙伴只知道是這么用的,也沒(méi)有深究具體的作用。這篇文字就來(lái)介紹一下Python中的if __name__ == ‘__main__’的作用,需要的朋友參考下文
    2021-09-09

最新評(píng)論

天门市| 红安县| 呈贡县| 鄄城县| 喀什市| 清河县| 东乌| 丹寨县| 湖州市| 元江| 江山市| 安丘市| 洛川县| 玉门市| 长顺县| 澄迈县| 剑阁县| 泰宁县| 获嘉县| 安化县| 蒙山县| 宜阳县| 大港区| 莱州市| 宜春市| 罗源县| 文安县| 新疆| 新干县| 武乡县| 太保市| 子洲县| 揭阳市| 乐平市| 中牟县| 阿鲁科尔沁旗| 铜山县| 交城县| 垫江县| 阳城县| 东兰县|