上一篇介紹了 SIFT 和 ORB。
它們可以找到圖片中的特徵點,並建立 Descriptor,方便不同圖片之間進行匹配。
不過有時候我們想找的不是特徵點。
例如道路的車道線、桌子的邊緣、建築物的牆壁,甚至是交通標誌的圓形。
這些都是具有規律幾何形狀的物體。
那電腦要怎麼從一張圖片中,把這些直線或圓形找出來?
今天要介紹的,就是 Hough Transform(霍夫轉換)。
既然圖片裡已經有 Edge,那是不是沿著 Edge 一路找下去就能知道哪裡是一條直線?
欸?我們來仔細思考一下。
一條直線可能會因為光線、遮擋或雜訊而中斷,有些地方甚至只剩下一小段。
如果只是沿著邊緣往前找,很容易就判斷失敗。
所以,Hough Transform 換了一種思考方式。
它在找之前會先問一個問題:哪些 Edge,有可能屬於同一條直線?
假設圖片中有很多 Edge Pixel。
每一個 Pixel 都可能屬於很多不同的直線。
Hough Transform 會讓每一個 Edge Pixel 都去「投票」。
如果很多 Pixel 都投給同一條直線。
那就代表,這條直線很有可能真的存在。
所以可以想成,Hough Transform 是透過投票,找出最有可能存在的幾何形狀。
如果用大家熟悉的直線方程式,一條直線可以寫成:
y = mx + b
不過,這個表示方法有一個問題:
如果今天遇到垂直線,斜率就會變成無限大。
因此 Hough Transform 使用了另一種表示方法:
ρ = xcosθ + ysinθ
其中:
利用這種表示方式,任何方向的直線都可以用同樣的方法表示。
假設現在有一個 Edge Pixel。
它不知道自己屬於哪一條直線。
那就可以把所有可能的角度都試一次。
每試一個角度,就能算出一個對應的 ρ。
也就是說,一個 Pixel 其實可以對應到很多組 (ρ, θ)。
當圖片中很多 Pixel 最後都得到相同的 (ρ, θ)。
就表示,它們很可能都位於同一條直線上。
這組 (ρ, θ) 就會累積很多票數。
最後,票數最高的位置就是偵測到的直線。
在 OpenCV 中可以直接使用 cv2.HoughLinesP()。
它會回傳偵測到的線段。
今天,我們不用前面用的狗狗照片,改成使用道路圖片,方便大家觀察。
import cv2
import math
import matplotlib.pyplot as plt
img = cv2.imread("road.jpeg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 100, 200)
lines = cv2.HoughLinesP(
edges,
rho=1,
theta=math.pi / 180,
threshold=80,
minLineLength=50,
maxLineGap=10
)
result = img.copy()
if lines is not None:
for line in lines:
x1, y1, x2, y2 = line[0]
cv2.line(result, (x1, y1), (x2, y2), (0, 0, 255), 2)
接著把結果畫出來。
plt.figure(figsize=(10,4))
plt.subplot(1,2,1)
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.title("Original")
plt.axis("off")
plt.subplot(1,2,2)
plt.imshow(cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
plt.title("Hough Lines")
plt.axis("off")
plt.tight_layout()
plt.show()
結果如下:

可以看到,原本只有一張普通的道路圖片。
經過 Canny 找到邊緣之後,再利用 Hough Transform,就能把車道線邊界偵測出來。
再仔細觀察,可以看到,同一條道路可能會被偵測成多個線段。這是因為 HoughLinesP() 回傳的是線段,而不是一條無限延伸的直線,因此實際應用中通常還會再進行線段合併或篩選。
答案是,可以。
Hough Transform 並不只能找直線。
只要知道某種幾何圖形的數學表示方式,就有機會利用類似的方法進行投票。
例如 OpenCV 就提供了:
cv2.HoughCircles(...)
可以用來偵測圖片中的圓形。
像是硬幣、瓶蓋、交通標誌,甚至是人的瞳孔都是常見的應用。
今天介紹了 Hough Transform。
它和前面介紹過的方法很不一樣。
它透過「投票」的概念,把屬於同一個幾何形狀的 Edge 聚集起來,進而找出圖片中的直線或圓形。
到這邊為止,我們已經介紹了許多的數位影像處理方法。
從最基本的 Pixel、Histogram、Convolution,到 Edge、Corner、Feature,再到今天的 Hough Transform,它們至今仍然是許多電腦視覺演算法的重要基礎。
下一篇,我們將一起回顧學過的內容,並討論傳統影像處理與深度學習之間的關係,看看它們在現代的電腦視覺技術中,各自扮演著什麼樣的角色。