Python OpenCV 霍夫(Hough Transform)直線變換檢測原理,圖像處理第 33 篇博客丨【百變AI秀】
Python OpenCV 365 天學習計劃,與橡皮擦一起進入圖像領域吧。本篇博客是這個系列的第 33 篇。
基礎知識鋪墊
霍夫變換(Hough Transform)是圖像處理領域中,從圖像中識別幾何形狀的基本方法之一。主要識別具有某些相同特征的幾何形狀,例如直線,圓形,本篇博客的目標就是從黑白圖像中識別出直線。
翻閱霍夫直線變換的原理時候,橡皮擦覺得原理部分需要先略過,否則很容易在這個地方陷進去,但是問題來了,這個原理略過了,直接應用函數,里面有些參數竟然看不懂。例如極坐標,角度掃描范圍,這種函數就屬于繞不過去的知識點了,所以本文轉移方向,死磕原理,下面的博文將語無倫次的為你展示如何學習原理知識。
霍夫變換直線檢測的基本原理
因為數學知識的貧乏,所以在學習階段會涉及到很多基礎概念的學習,一起來吧。
首先找到相對官方的資料,打開該 地址
下面是一個數學小白對原理的學習經驗。
教材說:眾所周知,一條直線在圖像二維空間可由兩個變量表示。
在笛卡爾坐標系:可由參數: (m,b) 斜率和截距表示;
在極坐標系: 可由參數: (r,θ) 極徑和極角表示。
抱歉,小白還真不知道……即使學習過,這些年也早已經還給老師了。
一開始難道要學習笛卡爾坐標系,不,你低估小白的能力了,我第一個查詢的是 θ 讀作 西塔,是一個希臘字母。
什么是笛卡爾坐標系?
這個比較簡單,直角坐標系。
斜率和截距
斜率,亦稱“角系數”,表示一條直線相對于橫坐標軸的傾斜程度。
一條直線與某平面直角坐標系橫坐標軸正半軸方向的夾角的正切值即該直線相對于該坐標系的斜率。
如果直線與 x 軸互相垂直,直角的正切直無窮大,故此直線不存在斜率。
對于一次函數 y=kx+b,k 就是該函數圖像的斜率。
在學習的時候,也學到如下內容:
截距:對 x 的截距就是 y=0 時,x 的值,對 y 的截距就是 x=0 時,y 的值,
截距就是直線與坐標軸的交點的橫(縱)坐標。x 截距為 a,y 截距 b,截距式就是:x/a+y/b=1(a≠0且b≠0)。
斜率:對于任意函數上任意一點,其斜率等于其切線與 x 軸正方向所成的角,即 k=tanα。ax+by+c=0中,k=-a/b。
需要注意的是:斜率不能不存在或等于 0,因為當斜率不存在時,直線垂直于 X 軸,沒有縱截距,當斜率等于 0 時,直線平行于 X 軸,沒有橫截距。
什么是極坐標系?
關于極坐標系,打開 百度百科 學習一下即可。
重點學到下面這個結論就行:
有序數對(θ,ρ)就稱為 P 點的極坐標,記為 P(θ,ρ);p 稱為 P 點的極徑,θ 稱為 P 點的極角。
找資料的時候,發現一個解釋的比較清楚的 博客,后續可以繼續學習使用。
繼續閱讀資料,看到如下所示的圖,這個圖也出現在了很多解釋原理的博客里面,但是圖下面寫了一句話
對于霍夫變換, 我們將用 極坐標系 來表示直線. 因此, 直線的表達式可為:
y
=
(
?
cos
?
θ
sin
?
θ
)
x
+
(
r
sin
?
θ
)
y = \left ( -\dfrac{\cos \theta}{\sin \theta} \right ) x + \left ( \dfrac{r}{\sin \theta} \right )
y=(?sinθcosθ )x+(sinθr )
在這里直接蒙掉了,怎么就表示成極坐標系了?上面這個公式依舊是笛卡爾坐標系表示直線的方式呀,只是把 k 和 b 的值給替換掉了。
y
=
?
k
x
+
b
y = -kx + b
y=?kx+b
其中
?
k
=
(
?
cos
?
θ
sin
?
θ
)
-k=\left(-\dfrac{\cos \theta}{\sin \theta} \right)
?k=(?sinθcosθ ) ,
b
=
(
r
sin
?
θ
)
b=\left ( \dfrac{r}{\sin \theta} \right )
b=(sinθr )
這還是笛卡爾坐標系呀,不是極坐標系。
為何是這樣的,具體原因可以參照下圖。
霍夫空間
繼續尋找關于霍夫變換的資料,找到一個新的概念霍夫空間。
在笛卡爾坐標系中,一條直線可以用公式
y
=
k
x
+
q
y = kx+q
y=kx+q 表示,其中 k 和 b 是參數,表示的是斜率和截距。
接下來將方程改寫為
b
=
?
k
?
x
0
+
y
0
b=-k*x_0+y_0
b=?k?x0 +y0 ,這時就建立了一個基于 k - b 的笛卡爾坐標系。
此時這個新的方程在 k - b 坐標系也有一個新的直線。
你可以在紙上畫出這兩個方程對應的線和點,如下圖所示即可。
新的 k - b 坐標系就叫做霍夫空間,這時得到一個結論,圖像空間 x - y 中的點
A
(
x
0
,
y
0
)
A(x_0,y_0)
A(x0 ,y0 ) 對應了霍夫空間 k - b 中的一條直線
b
=
?
k
?
x
0
+
y
0
b = -k*x_0+y_0
b=?k?x0 +y0 ,即圖像空間的點與霍夫空間的直線發生了對應關系。
如果在圖像空間 x - y 中在增加一個點
B
(
x
0
,
y
0
)
B(x_0,y_0)
B(x0 ,y0 ),那相應的該點在霍夫空間也會產生相同的點與線的對應關系,并且 A 點與 B 點產生的直線會在霍夫空間相交于一個點。而這個點的坐標值
(
k
0
,
b
0
)
(k_0,b_0)
(k0 ,b0 ) 就是直線 AB 的參數。
如果到這里你掌握了,這個性質就為我們解決直線檢測提供了方法,只需要把圖像空間的直線對應到霍夫空間的點,然后統計交點就可以達到目的,例如圖像空間中有 3 條直線,那對應到霍夫空間就會有 3 個峰值點。
遍歷圖像空間中的所有點,將點轉換到霍夫空間,形成大量直線,然后統計出直線交會的點,每個點的坐標都是圖像空間直線方程參數,這時就能得到圖像空間的直線了。
上述的內容沒有問題,但是存在一種情況是,當直線趨近于垂直時,斜率 k 會趨近于無窮大,這時就沒有辦法轉換了,解決辦法是使用法線來表示直線。
完善霍夫空間
上文提及的斜截式如下:
y
=
?
k
x
+
b
y = -kx + b
y=?kx+b
其中
?
k
=
(
?
cos
?
θ
sin
?
θ
)
-k=\left(-\dfrac{\cos \theta}{\sin \theta} \right)
?k=(?sinθcosθ ) ,
b
=
(
r
sin
?
θ
)
b=\left ( \dfrac{r}{\sin \theta} \right )
b=(sinθr )
通過第二個公式,可以得到下述公式:
ρ
=
x
?
cos
?
θ
+
y
?
sin
?
θ
ρ = x \cdot \cos \theta + y \cdot \sin \theta
ρ=x?cosθ+y?sinθ
此時,我們可以帶入一些數值進行轉換。
圖像空間有如下的幾個點:
點
(
1
,
0
)
(1,0)
(1,0),通過
p
=
x
cos
?
θ
+
y
sin
?
θ
p = x \cos \theta + y \sin \theta
p=xcosθ+ysinθ 轉換為
p
=
cos
?
θ
p=\cos \theta
p=cosθ;
點
(
2
,
2
)
(2,2)
(2,2),通過
p
=
x
cos
?
θ
+
y
sin
?
θ
p = x \cos \theta + y \sin \theta
p=xcosθ+ysinθ 轉換為
p
=
2
cos
?
θ
+
2
sin
?
θ
p=2\cos \theta +2\sin\theta
p=2cosθ+2sinθ;
點
(
3
,
2
)
(3,2)
(3,2),通過
p
=
x
cos
?
θ
+
y
sin
?
θ
p = x \cos \theta + y \sin \theta
p=xcosθ+ysinθ 轉換為
p
=
3
cos
?
θ
+
2
sin
?
θ
p=3\cos \theta +2\sin\theta
p=3cosθ+2sinθ。
轉換后的函數,都可以在霍夫空間 θ - ρ(橫坐標是 θ,縱坐標是 ρ)進行表示。
原理這時就比較清晰了:
一條直線能夠通過在平面 θ - r(r 就是本文中的 ρ) 尋找交于一點的曲線數量來檢測。
越多曲線交于一點也就意味著這個交點表示的直線由更多的點組成。
一般來說我們可以通過設置直線上點的閾值來定義多少條曲線交于一點我們才認為檢測到了一條直線。
相關數學知識挖坑
除了一些數學知識以外,經典的博客我們也有必要記錄一下,方便后面學習的時候,進行復盤。
https://blog.csdn.net/yuyuntan/article/details/80141392
https://blog.csdn.net/leonardohaig/article/details/87907462
本部分用于記錄本文中提及的相關數學原理,后續還要逐步埋坑。
直線方程,點斜式、截距式、斜截式、兩點式、法線式等內容;
正弦曲線。
橡皮擦的小節
今天涉及了一點點數學知識,能力限制,大家一起學習,有錯誤的地方,可以在評論區指出,不勝感激。
希望今天的 1 個小時(今天內容有點多,不一定可以看完),你有所收獲,我們下篇博客見~
今天是持續寫作的第
74
/ 100 天。
如果你有想要交流的想法、技術,歡迎在評論區留言。
博主 ID:夢想橡皮擦,希望大家
、
評論
、
。
【百變AI秀】有獎征文火熱進行中:https://bbs.huaweicloud.com/blogs/296704
AI OpenCV Python
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。