圖像處理之霍夫變換(Hough Transform)

霍夫變換,就是一個可以讓機器自己學會找直線的算法。

  1. 基本原理

一條直線可由兩個點A=(X1,Y1)和B=(X2,Y2)確定(笛卡爾座標)

公式:y=kx+q

也可以寫成關於(k,q)的函數表達式(霍夫空間):

對應的變換可以通過圖形直觀表示:

變換後的空間成爲霍夫空間。即:笛卡爾座標系中一條直線,對應霍夫空間的一個點。

反過來同樣成立(霍夫空間的一條直線,對應笛卡爾座標系的一個點):

再來看看A、B兩個點,對應霍夫空間的情形:

三個點共線的情況:

可以看出如果笛卡爾座標系的點共線,這些點在霍夫空間對應的直線交於一點:這也是必然,共線只有一種取值可能。

如果不止一條直線呢?再看看多個點的情況(有兩條直線):

其實(3,2)與(4,1)也可以組成直線,只不過它有兩個點確定,而圖中A、B兩點是由三條直線匯成,這也是霍夫變換的後處理的基本方式:選擇由儘可能多直線匯成的點。

霍夫空間:選擇由三條交匯直線確定的點(中間圖),對應的笛卡爾座標系的直線(右圖):

到這裏問題似乎解決了,已經完成了霍夫變換的求解,但是如果像下圖這種情況呢?

k=∞是不方便表示的,而且q怎麼取值呢,這樣不是辦法。因此考慮將笛卡爾座標系換爲:極座標表示。

在極座標系下,其實是一樣的:極座標的點→霍夫空間的直線,只不過霍夫空間不再是[k,q]的參數,而是[ρ,θ]的參數,給出對比圖:

霍夫變換的算法步驟:

編程思路

1.  讀取一幅待處理二值圖像,最好背景爲黑色;

2.  取得源像素數據;

3.  根據直線的霍夫變換公式完成霍夫變換,預覽霍夫空間結果;

4.  尋找最大霍夫值,設置閾值,反變換到圖像RGB值空間(程序難點之一);

5.  越界處理,顯示霍夫變換處理以後的圖像;

Opencv-python code解釋:

1.檢測線

cv2.HoughLines(image, rho, theta, threshold[, lines[, srn[, stn]]])

image是輸入的圖像

rho是以像素爲單位的累加器的距離分辨率

theta是在弧度內的蓄能器的角度分辨率

threshold其實是閾值,當累加器超過一定的範圍纔看作是直線

 

cv2.HoughLinesP(image, rho, theta, threshold[, lines[, minLineLength[, maxLineGap]]])

其他的參數和上一個函數一樣

minLineLength是線的最短長度(比這個短的都忽略了)

maxLinegap兩條直線的最大間隔,小於這個間隔的看成一條直線。

下面左圖爲原始圖像,右圖爲HoughLines和HoughLinesP後的圖像,從圖中可以看到檢測到草叢中間的一條小路:

 

2.檢測圈

cv2.HoughCircles(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]])

image是輸入圖象

method僅有一個cv2.HOUGH_GRADIENT

dp累加器分辨率與圖像分辨率的反比。例如,如果dp=1,累加器與輸入圖像具有相同的分辨率。如果dp=2,則累加器的寬度和高度爲原來的一半。

minDist檢測圓的中心之間的最小距離。如果參數太小,可能會錯誤地檢測到多個相鄰的圓。如果太大,可能會漏掉一些圓。

param1第一個method-specific參數。在CV_HOUGH_GRADIENT的情況下,它是兩個傳遞到Canny()邊緣檢測器的更高閾值(下一個是兩倍小)。

param2第二個method-specific參數。在CV_HOUGH_GRADIENT的情況下,它是檢測階段圓形中心的累加器閾值。它越小,就會發現更多的假圓。圓形,對應於較大的累加器值,將首先返回。

minradius圓的最小半徑

maxradius圓的最大半徑

下面左圖爲原始圖像,右圖爲HoughLines和HoughLinesP後的圖像,從圖中可以看到檢測到了蒙古包:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章