Like Share Discussion Bookmark Smile

J.J. Huang   2026-02-05   Python OpenCV 05.特徵與進階篇   瀏覽次數:次   DMCA.com Protection Status

Python | OpenCV 直線與圓形偵測 (霍夫變換)

📚 前言

在前一篇我們學會了 邊緣檢測與輪廓分析
這一篇要介紹 霍夫變換 (Hough Transform),它是一種常見的幾何特徵偵測方法,能有效找出圖片中的 直線圓形
這些技巧廣泛應用於車道線偵測、圓形物件辨識、工業檢測等場景。

🎨 範例圖片


圖:範例圖片 lines.png — 含有多條直線


圖:範例圖片 circles.png — 含有多個圓形


圖:範例圖片 suzuka.png — 賽車道場景 (來源:GameApps)


圖:範例圖片 cans.png — 罐頭俯瞰圖 (來源:Techbang)

🔎 霍夫變換原理

原理說明

  • 直線霍夫變換:將圖片中的每個邊緣點轉換到參數空間 (ρ, θ),找出符合直線方程的點群。
  • 圓形霍夫變換:利用邊緣點與圓心半徑的關係,在參數空間中找出可能的圓形。
  • OpenCV 提供了 cv2.HoughLines()cv2.HoughCircles() 兩個函式。

🧠 函式與參數說明

📌 cv2.HoughLines()

1
cv2.HoughLines(image, rho, theta, threshold)
  • image:邊緣檢測後的二值化圖片 (通常用 Canny)。
  • rho:距離解析度,單位像素,常用值 = 1。
  • theta:角度解析度,單位弧度,常用值 = np.pi/180 (即 1 度)。
  • threshold:累加器閾值,至少多少個點支持才能判定為直線。

📌 cv2.HoughCircles()

1
cv2.HoughCircles(image, method, dp, minDist, param1, param2, minRadius, maxRadius)
  • image:灰階圖片,建議先模糊處理。
  • method:偵測方法,常用 cv2.HOUGH_GRADIENT
  • dp:累加器解析度與圖片解析度的反比。dp=1 表示相同解析度。
  • minDist:不同圓心之間的最小距離。
  • param1:Canny 邊緣檢測的高閾值。
  • param2:累加器閾值,數值越小偵測越敏感。
  • minRadius:最小半徑。
  • maxRadius:最大半徑。

💻 範例程式 — 直線偵測

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import cv2
import numpy as np

img = cv2.imread("lines.png")
cv2.imshow("Original", img)

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

edges = cv2.Canny(gray, 50, 150)
lines = cv2.HoughLines(edges, 1, np.pi/180, 100)

for line in lines:
rho, theta = line[0]
a = np.cos(theta)
b = np.sin(theta)
x0 = a * rho
y0 = b * rho
x1 = int(x0 + 1000 * (-b))
y1 = int(y0 + 1000 * (a))
x2 = int(x0 - 1000 * (-b))
y2 = int(y0 - 1000 * (a))
cv2.line(img, (x1,y1), (x2,y2), (0,0,255), 2)

cv2.imshow("Detected Lines", img)
cv2.waitKey(0)
cv2.destroyAllWindows()


圖:程式碼執行結果 — 偵測並標註圖片中的直線

💻 範例程式 — 圓形偵測

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import cv2
import numpy as np

img = cv2.imread("circles.png")
cv2.imshow("Original", img)

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.medianBlur(gray, 5)

circles = cv2.HoughCircles(
gray, cv2.HOUGH_GRADIENT, dp=1, minDist=50,
param1=100, param2=30, minRadius=20, maxRadius=100
)

if circles is not None:
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
cv2.circle(img, (i[0], i[1]), i[2], (0,255,0), 2)
cv2.circle(img, (i[0], i[1]), 2, (0,0,255), 3)

cv2.imshow("Detected Circles", img)
cv2.waitKey(0)
cv2.destroyAllWindows()


圖:程式碼執行結果 — 偵測並標註圖片中的圓形

💻 範例程式 — 實際應用:賽車道直線偵測

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import cv2
import numpy as np

img = cv2.imread("suzuka.png") # 賽車道圖片
cv2.imshow("Original", img)

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 邊緣檢測
edges = cv2.Canny(gray, 100, 200)

# 霍夫直線偵測
lines = cv2.HoughLines(edges, 1, np.pi/180, 120)

if lines is not None:
for line in lines:
rho, theta = line[0]
a = np.cos(theta)
b = np.sin(theta)
x0 = a * rho
y0 = b * rho
x1 = int(x0 + 1000 * (-b))
y1 = int(y0 + 1000 * (a))
x2 = int(x0 - 1000 * (-b))
y2 = int(y0 - 1000 * (a))
cv2.line(img, (x1,y1), (x2,y2), (0,0,255), 2)

cv2.imshow("Suzuka Circuit - Lines", img)
cv2.waitKey(0)
cv2.destroyAllWindows()


圖:程式碼執行結果 — 偵測並標註賽車道中的直線

💻 範例程式 — 實際應用:罐頭圓形偵測

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import cv2
import numpy as np

img = cv2.imread("cans.png") # 罐頭俯瞰圖
cv2.imshow("Original", img)

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.medianBlur(gray, 5)

# 霍夫圓形偵測
circles = cv2.HoughCircles(
gray, cv2.HOUGH_GRADIENT, dp=1, minDist=100,
param1=100, param2=50, minRadius=90, maxRadius=110
)

if circles is not None:
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
cv2.circle(img, (i[0], i[1]), i[2], (0,255,0), 2) # 畫圓
cv2.circle(img, (i[0], i[1]), 2, (0,0,255), 3) # 畫圓心

cv2.imshow("Cans - Circles", img)
cv2.waitKey(0)
cv2.destroyAllWindows()


圖:程式碼執行結果 — 偵測並標註罐頭的大圓形

⚠️ 注意事項

  • 直線偵測threshold 數值需依圖片調整,太小會產生雜訊,太大可能漏掉直線。
  • 圓形偵測param1param2 控制靈敏度,需依圖片特性調整。
  • 前處理:建議先做邊緣檢測或模糊處理,提升偵測效果。

📊 應用場景

  • 車道線偵測:利用直線霍夫變換偵測道路標線。
  • 工業檢測:偵測零件上的圓孔或直線結構。
  • 醫學圖片:偵測血管或圓形結構。
  • 日常應用:找出圖片中的幾何形狀,輔助後續分析。

🎯 結語

本篇我們學會了 霍夫變換 的直線與圓形偵測方法,並理解了 cv2.HoughLines() 與 cv2.HoughCircles() 的用法,成功在圖片中標註幾何特徵。
這些技巧在電腦視覺應用中非常常見,例如車道線偵測、工業檢測與醫學圖片分析。

📖 如在學習過程中遇到疑問,或是想了解更多相關主題,建議回顧一下 Python | OpenCV 系列導讀,掌握完整的章節目錄,方便快速找到你需要的內容。

註:以上參考了
OpenCV Tutorials
OpenCV-Python Tutorials