1.圖像特征
圖像特征就是指有意義的圖像區(qū)域,具有獨特性,易于識別性,比如角點、斑點以及高密度區(qū)。而為什么角點具有重要的特征呢?
看下圖:
觀察ABD三張圖片,我們不容易得知圖像的位置,而CEF三張圖我們特別容易找到它們在原圖中對應的位置,這是因為ABD比較平滑,我們不易找出他們的特點,而CEF三張圖有很明顯的輪廓特征,有很多邊緣特征即角點,因此一幅圖像中的角點非常重要。
想讓計算機具有識別圖片的功能,首先要讓他們學會提取圖片的特征,提取圖像的角點。
角點的特征
- 在特征中最重要的是角點
- 是灰度梯度最大值所對應的像素
- 兩條線的交點
- 極值點(一階導數(shù)最大值但是二階導數(shù)為0)
2. 哈里斯檢測
原理:
圖1方塊上下左右移動都沒有變化,說明圖1不是角點;圖2上下沒有變化,左右移動有變化,說明圖2是邊緣;圖3上下左右移動都有變化,說明圖3是角點。
cornerHarris()
dst = cv2.cornerHarris(img, blockSize, ksize, k)
img :需要檢測的圖像,最好為灰度圖
blockSize:檢測窗口的大小,一般取2
ksiez:Sobel卷積核,一般取3
k:權(quán)重系數(shù),經(jīng)驗值,一般取0.02~0.04之間
返回值:dst不是圖像,是點的集合
缺點:k是個經(jīng)驗值需要自己調(diào)節(jié)
import cv2
import numpy as np
# 讀取圖片,并轉(zhuǎn)為灰度圖
img = cv2.imread('./image/chess.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Harris角點檢測
dst = cv2.cornerHarris(gray, 2, 3, 0.02)
# 表示img中dst值大于0.01*dst.max()的像素點索引出來,然后將這些像素點的值賦為 [0,0,255]。
img[dst > 0.01*dst.max()] = [0, 0, 255]
cv2.imshow('img', img)
cv2.waitKey(0)
3.Shi-Tomasi角點檢測
Shi-Tomasi是Harris角點檢測的改進,因為Harris角點檢測的穩(wěn)定性與k有關,而k是個經(jīng)驗值,與人的主觀因素有關。Shi-Tomasi避免了這個問題。
goodFeaturesToTrack()
dst = cv2.goodFeaturesToTrack(img, maxCorners, qualityLevel, minDistance)
img:需要檢測的圖像,最好為灰度圖
maxCorners:角點的最大數(shù)量,值為0表示無限制
qualityLevel:小于1.0的正數(shù),一般在0.01-1.0之間
minDistance:角之間最小歐式距離,忽略小于此距離的點
mask:感興趣的區(qū)域,不填默認全部圖像
blockSize:檢測窗口大小
useHarrisDetector:是否使用Harris算法,True/False
k:默認是0.04
import cv2
import numpy as np
# 讀取圖片,并轉(zhuǎn)為灰度圖
img = cv2.imread('./image/chess.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Harris角點檢測
# dst = cv2.cornerHarris(gray, 2, 3, 0.02)
maxCorners = 100
ql = 0.01
minDistance = 10
# ShiTomasi角點檢測
corners = cv2.goodFeaturesToTrack(gray, maxCorners, ql, minDistance)
# corners為float32類型,需要轉(zhuǎn)化為整型
corners = np.int0(corners)
# 表示img中dst值大于0.01*dst.max()的像素點索引出來,然后將這些像素點的值賦為 [0,0,255]。
# img[dst > 0.01*dst.max()] = [0, 0, 255]
for i in corners:
x, y = i.ravel() # 將迭代的數(shù)組,轉(zhuǎn)化成一維的
cv2.circle(img, (x, y), 3, (0, 0, 255), -1)
cv2.imshow('img', img)
cv2.waitKey(0)
4.Scale-Invariant Feature Transform(SIFT)
該算法是與縮放無關的特征檢測,比如說,以前是角點,但是在圖放大或縮小后,由于圖片比例的變化,原來是角,放大之后,可能就不是角;原來是角,縮小之后可能就是角。而該算法正好解決了這個問題。
SIFT能夠計算關鍵點和描述子,關鍵點:位置、大小和方向;關鍵點描述子:記錄了關鍵點周圍對其有貢獻的像素點的一組向量值,其不受仿射變換、光照變換的影響。
SIFT語法
- 首先創(chuàng)建SIFT對象
- 進行檢測,kp =sift.detect(img,…)
- 繪制關鍵點,drawKeypoints(gray, kp, img)
- 從灰度圖gray中檢測的,關鍵點kp,在原圖img中畫
創(chuàng)建SIFT對象
sift = cv2.xfeatures2d.SIFT_create(什么也不寫)
kp = sift.detect(img, mask)
img:是檢測圖片,盡量用灰度圖
mask:掩碼,指明對圖中哪部分進行檢測,一般填None(全圖)
import cv2
import numpy as np
# 讀取圖片,并轉(zhuǎn)為灰度圖
img = cv2.imread('./image/chess.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 創(chuàng)建sift對象
sift = cv2.xfeatures2d.SIFT_create()
# 關鍵點檢測
kp = sift.detect(gray, None)
# 使用關鍵點畫圖
cv2.drawKeypoints(gray, kp, img)
cv2.imshow('img', img)
cv2.waitKey(0)
此接口一下能算出關鍵點和描述子
kp, des = sift.detectAndCompute(img, mask)
img:是檢測圖片,盡量用灰度圖
mask:掩碼,指明對圖中哪部分進行檢測,一般填None(全圖)
import cv2
import numpy as np
# 讀取圖片,并轉(zhuǎn)為灰度圖
img = cv2.imread('./image/chess.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 創(chuàng)建sift對象
sift = cv2.xfeatures2d.SIFT_create()
# kp = sift.detect(gray, None)
kp, des = sift.detectAndCompute(gray, None)
cv2.drawKeypoints(gray, kp, img)
cv2.imshow('img', img)
cv2.waitKey(0)
SIFT缺點:速度慢
5.SURF
由于SIFT速度較慢,因此又產(chǎn)生了SURF算法,該算法速度優(yōu)于SIFT。
- 首先創(chuàng)建SURF對象
- 進行檢測,kp, des =surf.detectAndCompute(img, mask)
- 繪制關鍵點,drawKeypoints(gray, kp, img)
- 從灰度圖gray中檢測的,關鍵點kp,在原圖img中畫
創(chuàng)建surf對象
surf = cv2. xfeatures2d.SURF_create()
kp, des = surf.detectAndCompute(img, mask)
img:是檢測圖片,盡量用灰度圖
mask:掩碼,指明對圖中哪部分進行檢測,一般填None(全圖)
kp:檢測出的關鍵字
des:是描述子,用來特征匹配使用的
import cv2
import numpy as np
# 讀取圖片,并轉(zhuǎn)為灰度圖
img = cv2.imread('./image/chess.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# # 創(chuàng)建sift對象
# sift = cv2.xfeatures2d.SIFT_create()
# 創(chuàng)建surf對象
surf = cv2.xfeatures2d.SURF_create()
# 計算關鍵點和描述子
kp, des = surf.detectAndCompute(gray, None)
cv2.drawKeypoints(gray, kp, img)
cv2.imshow('img', img)
cv2.waitKey(0)
注意:此算法由于付費的緣由,需要使用3.4.2.17版本的opencv庫
6.ORB(Oriented FAST and Rotated BRIEF)
其中FAST用于特征檢測,BRIEF是對已檢測到的特征點進行描述,它加快了特征描述符的建立速度,同時也極大降低了特征匹配的時間。
ORB的優(yōu)勢在于:速度快,可用于實時監(jiān)測;免費。
先建立ORB對象
orb = cv2.ORB_create()
計算特征點與描述子
kp, des = orb.detectAndCompute(img, mask)
使用kp畫出特征點
cv2.drawKeypoints(gray, kp, img)
img:是檢測圖片,盡量用灰度圖
mask:掩碼,指明對圖中哪部分進行檢測,一般填None(全圖)
import cv2
import numpy as np
# 讀取圖片,并轉(zhuǎn)為灰度圖
img = cv2.imread('./image/chess.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 創(chuàng)建orb對象
orb = cv2.ORB_create()
# 對ORB進行檢測
kp, des = orb.detectAndCompute(gray, None)
cv2.drawKeypoints(gray, kp, img)
cv2.imshow('img', img)
cv2.waitKey(0)
檢測出的特征點越來越少,因此在提升檢測速度的同時,精度也在丟失。
7.特征匹配
根據(jù)特征點的描述子進行匹配,特征匹配方法有:
- BF(Brute-Force),暴力特征匹配方法
- FLANN 最快臨近區(qū)特征匹配方法
7.1 暴力特征匹配
它使用第一組中的每個特征點的描述子與第二組中的所有特征點的描述子進行匹配,計算他們之間的差距,然后將最接近的一個匹配返回
- 創(chuàng)建匹配器,bf = cv2.BFMatcher(normType, crossCheck)
- 進行特征匹配,match = bf. match(des1, des2)
- 繪制匹配點, cv2.drawMatches(img1, kp1, img2, kp2,…)
創(chuàng)建匹配器
bf = cv2.BFMatcher(normType, crossCheck)
normType:NORM_L1(SIFT),NORM_L2(SURF), HAMMING1(ORB)
crossCheck:是否進行交叉匹配,默認為false
描述子進行匹配
match = bf.match(dst1, dst2)
dst1:要搜索的圖的描述子
dst2:從庫里能匹配的描述子
畫相同的地方
img3 = cv2.drawMatchers(img1, kp1, img2, kp2, match, None)
img1, kp1:要搜索的圖,和特征點
img2, kp2:從庫里匹配的圖和特征點
match:匹配好的描述子
import cv2
import numpy as np
# 讀取圖片,并轉(zhuǎn)為灰度圖
img1 = cv2.imread('./image/opencv_search.png')
img2 = cv2.imread('./image/opencv_orig.png')
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
# 創(chuàng)建orb對象
orb = cv2.ORB_create()
# 對ORB進行檢測
kp1, dst1 = orb.detectAndCompute(gray1, None)
kp2, dst2 = orb.detectAndCompute(gray2, None)
# 創(chuàng)建匹配器
bf = cv2.BFMatcher(cv2.NORM_HAMMING)
# 描述子進行匹配
match = bf.match(dst1, dst2)
img3 = cv2.drawMatches(img1, kp1, img2, kp2, match, None)
cv2.imshow('img3', img3)
7.2 FLANN
- 進行批量特征匹配時,F(xiàn)LANN速度更快
- 由于它使用的是臨近近似值,所以精度較差
創(chuàng)建匹配器
flann = cv2.FlannBasedMatcher()
進行特征匹配
match = flann.match()
繪制匹配點
img3 = cv2.drawMatches()文章來源:http://www.zghlxwxcb.cn/news/detail-777337.html
import cv2
import numpy as np
# 讀取圖片,并轉(zhuǎn)為灰度圖
img1 = cv2.imread('./image/opencv_search.png')
img2 = cv2.imread('./image/opencv_orig.png')
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
# 創(chuàng)建orb對象
orb = cv2.ORB_create()
# 對ORB進行檢測
kp1, dst1 = orb.detectAndCompute(gray1, None)
kp2, dst2 = orb.detectAndCompute(gray2, None)
# 判斷描述子的數(shù)據(jù)類型,若不符合,則進行數(shù)據(jù)替換
if dst1.dtype != 'float32':
dst1 = dst1.astype('float32')
if dst2.dtype != 'float32':
dst2 = dst2.astype('float32')
# 創(chuàng)建匹配器(FLANN)
flann = cv2.FlannBasedMatcher()
# 描述子進行匹配計算
matches = flann.match(dst1, dst2)
img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches, None)
cv2.imshow('img3', img3)
文章來源地址http://www.zghlxwxcb.cn/news/detail-777337.html
到了這里,關于OpenCV(圖像處理)-基于Python-特征檢測-特征點匹配的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!