OpenCV影象處理- 角點檢測
Harris角點檢測
✏️ ⛳️
概述
✔️ Chris_Harris 和 Mike_Stephens 早在 1988 年的文章《A Combined Corner and Edge Detector》中就已經提出了焦點檢測的方法被稱為 Harris角點檢測。他把這個簡單的想法轉換成了數學形式。將視窗向各個方向 移動(u , v)然後計算所有差異的總和。表示式如下:
數學轉換後:
其中:
和
是影象在 x 和 y 方向的導數(可以用函式
cv2。Sobel()
計算得到)。
最終,根據一個用來判定視窗內是否包含角點的等式進行打分:
其中:
。
。
和
是矩陣 M 的特徵值。
我們根據這些特徵來判斷一個區域是角點,邊界還是平面: - 當
和
都小時,
也小,則為平面區域。 - 當
或者
時,R小於0,則為邊緣。 - 當
和
都很大時,且
中時,R也很大,(
和
中的最小值都大於閾值),則為角點。
如圖所示:
分佈圖
函式
✔️ OpenCV 中的函式
cv2。cornerHarris()
可以用來進行角點檢測,引數如下:
img - 輸入影象。
blockSize - 角點檢測中領域畫素的大小。
ksize - Sobel 求導中使用的視窗大小
k - Harris 角點檢測方程中的自由引數,取值引數為 [0,04,0。06]。
輸出 response
示例
import
numpy
as
np
import
cv2
as
cv
def
harris
(
image
,
opt
=
1
):
# Detector parameters
blockSize
=
2
apertureSize
=
3
k
=
0。04
# Detecting corners
gray
=
cv
。
cvtColor
(
image
,
cv
。
COLOR_BGR2GRAY
)
dst
=
cv
。
cornerHarris
(
gray
,
blockSize
,
apertureSize
,
k
)
# Normalizing
dst_norm
=
np
。
empty
(
dst
。
shape
,
dtype
=
np
。
float32
)
cv
。
normalize
(
dst
,
dst_norm
,
alpha
=
0
,
beta
=
255
,
norm_type
=
cv
。
NORM_MINMAX
)
# Drawing a circle around corners
for
i
in
range
(
dst_norm
。
shape
[
0
]):
for
j
in
range
(
dst_norm
。
shape
[
1
]):
if
int
(
dst_norm
[
i
,
j
])
>
120
:
cv
。
circle
(
image
,
(
j
,
i
),
2
,
(
0
,
255
,
0
),
2
)
# output
return
image
src
=
cv
。
imread
(
“chessboard。jpg”
)
cv
。
imshow
(
“input”
,
src
)
result
=
harris
(
src
)
cv
。
imshow
(
‘result’
,
result
)
cv
。
imwrite
(
‘result。jpg’
,
result
)
cv
。
waitKey
(
0
)
cv
。
destroyAllWindows
()
輸入
輸出
Shi-Tomas角點檢測
概述
✔️ Shi-Tomas是源於《Good Features to Track》,其中對Harris角點檢測演算法改進後的新演算法。
✔️ Shi-Tomas使用的打分函式為:
如果打分超過閾值,則認為它是一個角點,因此可以繪製如下所示的空間圖:
角點空間圖
圖中,只有當
和
都大於之最小值,才可以被認為是角點(綠色區域)
函式
✔️ OpenCV 中的函式
cv2。goodFeaturesToTrack()
可以用來進行角點檢測,引數如下:
輸入:
src單通道輸入影象,八位或者浮點數。
maxCorners表示最大返回關鍵點數目。
qualityLevel表示拒絕的關鍵點 R < qualityLevel × max response將會被直接丟棄。
minDistance 表示兩個關鍵點之間的最短距離。
mask 表示mask區域,如果有表明只對mask區域做計算。
blockSize 計算梯度與微分的視窗區域。
useHarrisDetector 表示是否使用harris角點檢測,預設是false 為shi-tomas。
k = 0。04預設值,當useHarrisDetector為ture時候起作用。
輸出:
corners是輸出的關鍵點座標集合
示例
import
numpy
as
np
import
cv2
def
process
(
image
,
opt
=
1
):
# Detecting corners
gray
=
cv2
。
cvtColor
(
image
,
cv2
。
COLOR_BGR2GRAY
)
corners
=
cv2
。
goodFeaturesToTrack
(
gray
,
35
,
0。05
,
10
)
(
len
(
corners
))
for
pt
in
corners
:
(
pt
)
b
=
np
。
random
。
random_integers
(
0
,
256
)
g
=
np
。
random
。
random_integers
(
0
,
256
)
r
=
np
。
random
。
random_integers
(
0
,
256
)
x
=
np
。
int32
(
pt
[
0
][
0
])
y
=
np
。
int32
(
pt
[
0
][
1
])
cv2
。
circle
(
image
,
(
x
,
y
),
5
,
(
int
(
b
),
int
(
g
),
int
(
r
)),
2
)
# output
return
image
src
=
cv2
。
imread
(
“blox。jpg”
)
cv2
。
imshow
(
“input”
,
src
)
result
=
process
(
src
)
cv2
。
imshow
(
‘result’
,
result
)
cv2
。
imwrite
(
‘result。jpg’
,
result
)
cv2
。
waitKey
(
0
)
cv2
。
destroyAllWindows
()
輸入
輸出
亞畫素級的角點檢測
概述
✔️ OpenCV中角點檢測的結果實際不夠精準,因為真實的計算中有些位置可能是在浮點數的空間內才最大值,這樣就需要我們透過給定的響應值,在畫素鄰域空間進行擬合,實現亞畫素級別的角點檢測。
函式:
cv2
。
cornerSubPix
(
InputArray
image
,
InputOutputArray
corners
,
Size
winSize
,
Size
zeroZone
,
TermCriteria
criteria
)
image單通道輸入影象,八位或者浮點數。
corners是輸入輸出的關鍵點座標集合。
winSize表示插值計算時候視窗大小。
zeroZone表示搜尋區域中間的dead。 region邊長的一半,有時用於避免自相關矩陣的奇異性。如果值設為(-1,-1)則表示沒有這個區域。
criteria角點精準化迭代過程的終止條件。
程式碼:
import
numpy
as
np
import
cv2
as
cv
def
process
(
image
,
opt
=
1
):
# Detecting corners
gray
=
cv
。
cvtColor
(
image
,
cv
。
COLOR_BGR2GRAY
)
corners
=
cv
。
goodFeaturesToTrack
(
gray
,
100
,
0。05
,
10
)
(
len
(
corners
))
for
pt
in
corners
:
(
pt
)
b
=
np
。
random
。
random_integers
(
0
,
256
)
g
=
np
。
random
。
random_integers
(
0
,
256
)
r
=
np
。
random
。
random_integers
(
0
,
256
)
x
=
np
。
int32
(
pt
[
0
][
0
])
y
=
np
。
int32
(
pt
[
0
][
1
])
cv
。
circle
(
image
,
(
x
,
y
),
5
,
(
int
(
b
),
int
(
g
),
int
(
r
)),
2
)
# detect sub-pixel
winSize
=
(
3
,
3
)
zeroZone
=
(
-
1
,
-
1
)
# Stop condition
criteria
=
(
cv
。
TERM_CRITERIA_EPS
+
cv
。
TermCriteria_COUNT
,
40
,
0。001
)
# Calculate the refined corner locations
corners
=
cv
。
cornerSubPix
(
gray
,
corners
,
winSize
,
zeroZone
,
criteria
)
# display
for
i
in
range
(
corners
。
shape
[
0
]):
(
“ —— Refined Corner [”
,
i
,
“] (”
,
corners
[
i
,
0
,
0
],
“,”
,
corners
[
i
,
0
,
1
],
“)”
)
return
image
src
=
cv
。
imread
(
“tyt。png”
)
cv
。
imshow
(
“input”
,
src
)
result
=
process
(
src
)
cv
。
imshow
(
‘result’
,
result
)
cv
。
imwrite
(
‘result。jpg’
,
result
)
cv
。
waitKey
(
0
)
cv
。
destroyAllWindows
()
輸入
輸出
——————————————————————可愛の分割線——————————————————————
更多Opencv教程可以 Follow github的opencv教程,
中文&English
歡迎Star
❤️❤️❤️
參考
-
OpenCv官網
下一篇:阿伐那非的副作用多久消失