OpenCV-Python系列十一:特征檢測(1)--角點檢測

角點特征常常是圖像中獨特的存在,比如你在玩拼圖游戲時,首先肯定會去找一些獨一無二的匹配項,比如人像的眼睛,嘴巴,這些特征你很容易判斷哪些碎片應該拼湊在一起,而相比之下,那些比較常見的特征你需要最后多次調(diào)整才能找到對的位置。角點特征就是這樣較獨特的存在,下圖中矩形的右上角點區(qū)域,無論你往哪個方向移動,圖像的信息都會發(fā)生變化,而邊緣則沿某一個方向移動時不會變化,至于矩形內(nèi)部區(qū)域,則無論哪個方向移動,圖像信息沒有變化[引用自官方教程]。

角點特征
那么,在OpenCV里,有哪些能幫你解決問題的呢?

本文內(nèi)容涉及以下內(nèi)容(參考OpenCV3 計算機視覺第6章)
  • Harris角點檢測
  • Shi-Tomasi角點檢測(Harris的修改版)
  • FAST角點檢測

有了特征點,怎么用呢?你可以比對不同圖像的特征信息,進行目標檢測、圖像拼接等。在OpenCV中,可以通過下面的算子來進行特征匹配

  • Brute-Force匹配法,也稱暴力匹配法
  • 基于FLANN的匹配法
1.使用Harris以及Shi-Tomasi算子獲取角點
Harris | Shi-Tomasi角點

:這里采用Shi-Tomasi僅保留最好的12個角點信息(匹配比較好),而harris輸出了全部角點,圓圈顏色深表示該處檢測到的次數(shù)多。

import cv2
import numpy as np
import time

img = cv2.imread('approx_star.png', -1)
img_copy = img.copy()

gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gaussian_img = cv2.GaussianBlur(gray_img,(3, 3),0)
# 輸入圖像必須是float32
float_img = np.float32(gaussian_img)

# Harris角點檢測
## src: 輸入圖像
## blockSize:鄰域大小
## ksize:Sobel算子中的核大小
## k :Harris檢測參數(shù),經(jīng)驗范圍:[0.04, 0.06],值越大,假角點越少,不過可能會漏檢
start_time = time.time()
dst = cv2.cornerHarris(float_img, 4, 3, 0.08)
end_time = time.time()
print('Harris Detection used :%s ms.' % ((end_time - start_time) * 1000))

dot_locs = np.where(dst > (0.01 * dst.max()))
for loc in zip(*dot_locs[::-1]):
    cv2.circle(img, loc, 5, (25, 25, 255), 1)

# Shi-Tomasi方法檢測
## src: 輸入圖像
## maxCorners:輸出的角點數(shù)目,可以幫助你找到最佳的maxCorners個角點,會將角點進行排序
## qualityLevel:檢測質(zhì)量水平系數(shù),經(jīng)驗值[0.01, 0.1]
## minDistance:最小的角點距離,小于該距離的角點會被忽視
start_time = time.time()
corners = cv2.goodFeaturesToTrack(gaussian_img, 12, 0.01, 10)
end_time = time.time()
print('goodFeaturesToTrack Detection used :%s ms.' % ((end_time - start_time) * 1000))
corners = np.int64(corners)
for corner in corners:
    x, y = corner.flatten()
    cv2.circle(img_copy, (x, y), 5, (255, 25, 255), 3)

cv2.imshow('harris_corners', img)
cv2.imshow('shi-tomasi_corners', img_copy)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 耗時情況:
# Harris Detection used :5.984783172607422 ms.
# goodFeaturesToTrack Detection used :9.972572326660156 ms.

補充
1.關(guān)于參數(shù)ksize和檢測自由設置參數(shù)k,可參考博客【cornerHarris中的ksize和k是什么意思】--https://www.jb51.cc/python/533133.html
2.官方角點檢測參考鏈接:https://docs.opencv.org/3.0-beta/modules/imgproc/doc/feature_detection.html?highlight=cv2.cornerharris#cv2.cornerHarris
3.goodFeaturesToTrack 函數(shù)參數(shù)詳解https://blog.csdn.net/guduruyu/article/details/69537083 這個函數(shù)可以輸入mask信息
4.對于有更精細檢測需求的,可以使用cornerSubPix()來檢測亞像素角點

對于FAST檢測角點的基本使用方法如下:

# 創(chuàng)建檢測器,大多數(shù)情況下閾值設置較大,太低會造成大量的假特征點
# 選擇非極大值抑制會使得特征點會少一些,避免一些假特征點
# type可選擇FAST_FEATURE_DETECTOR_TYPE_9_16,在像素周圍取16個點,當9個滿足條件,就是特征點,除此之外,可選擇7_12, 5_8
fast=cv2.FastFeatureDetector_create(threshold = 20, nonmaxSuppression=False, 
type=cv2.FAST_FEATURE_DETECTOR_TYPE_9_16)
# 返回的kp為keypoint類,你可以使用kp[0].pt獲取第一個特征點的坐標信息
# detect第二個參數(shù)為特征點,第三個參數(shù)為mask
kp = fast.detect(gray_img, None)
# 耗時情況
# FAST Detection used :0.9963512420654297 ms.??

參考博客
1.OPENCV圖像特征點檢測與FAST算法https://www.cnblogs.com/dengxiaojun/p/5302778.html講解該函數(shù)的算法及參數(shù)
2.KeyPoint類參考博客:https://blog.csdn.net/leonardohaig/article/details/81289648

2.特征點匹配

你可以用特征點用在兩幅圖的信息比對上,這一點在圖像拼接中尤為重要,至于說用特征進行目標檢測,比如《OpenCV3 計算機視覺》中有將特征信息作為紋身信息的比對.不過,當你的環(huán)境特征信息量比較多(比如風景)的時候,匹配出錯的概率非常大.
ORB算法特征匹配
# ORB特征點匹配
import cv2
import numpy as np
import time

# 特征圖像
img = cv2.imread('fuji_features1.png',-1)
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 待匹配圖像
img1 = cv2.imread('fuji_feature.jpg',-1)
gray_img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)

start_time = time.time()
orb = cv2.ORB_create()
kp1, des1 = orb.detectAndCompute(gray_img, None)
kp2, des2 = orb.detectAndCompute(gray_img1, None)

bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck = True)

matches = bf.match(des1, des2)
end_time = time.time()
print('ORB Detect Features and BFMatch used :%s ms.' % ((end_time - start_time) * 1000))

# good_matches = []
# for m, n in matches:
#     if m.distance < 0.75 * n.distance:
#         good_matches.append([m])
# 按照特征點距離進行排序,距離越小約好
# 參考博客:https://blog.csdn.net/u013000248/article/details/85325136
matches = sorted(matches, key = lambda x : x.distance)
img2 = cv2.drawMatches(img, kp1, img1, kp2, matches[:40], np.array([]), flags = 2)

cv2.imshow('ORB_corners', img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
2.1 ORB 特征 + FLANN匹配

需要注意一下,ORB 進行特征提取的descriptor格式需要轉(zhuǎn)換下,否則是無法進行FLANN匹配

FLANN_INDEX_KDTREE = 1
indexParams = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
searchParams = dict(check = 50)

flann = cv2.FlannBasedMatcher(indexParams, searchParams)
# 轉(zhuǎn)為np.float32
matches = flann.knnMatch(np.float32(des1), np.float32(des2), k = 2)

相關(guān)博客:
角點特征檢測之三(FLANN匹配)https://blog.csdn.net/wsp_1138886114/article/details/90578810

關(guān)于opencv-python的特征檢測及匹配部分相關(guān)內(nèi)容非常多,由于目前暫未涉及相關(guān)應用,如果你的應用中涉及相關(guān)內(nèi)容,有問題的話請在評論區(qū)留言.Have Fun With OpenCV-Python, 下期見。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容