[Python][OpenCV]自動判斷紅綠燈燈號

更新 發佈閱讀 8 分鐘

交通紅綠燈辨識是一個經典的影像處理應用案例,無論是機器人導航、車輛輔助駕駛,甚至影像監控系統,都少不了這個功能。

今天我們要用 OpenCVNumPy,搭配 HSV 色彩空間,快速實作一個 高穩定度的紅綠燈判斷系統


結果圖

raw-image

1. 為什麼要用 HSV 而不是 RGB

傳統 RGB 判斷顏色的缺點:

  • 光線強度改變時,RGB 數值波動大
  • 同樣的紅燈,白天和夜晚拍攝,RGB 值差異極大
  • 需要人工設定多個條件,程式複雜

HSV 的優勢:

  • H (Hue 色相):直接代表顏色的種類(紅、綠、藍…)
  • S (Saturation 飽和度):顏色的純度
  • V (Value 亮度):顏色的明暗度

因此,用 HSV 只需要判斷色相 (H) 就能輕鬆穩定地抓到紅燈或綠燈。


2. 安裝必要套件

在開始前,先安裝以下套件:

pip install opencv-python numpy matplotlib

3. 完整程式碼

以下是完整、可直接執行的紅綠燈偵測程式:

import cv2
import numpy as np
import matplotlib.pyplot as plt

def detect_traffic_light_hsv(img):
# Step 1. 轉換色彩空間 BGRHSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# Step 2. 定義紅色範圍 (紅色分兩段範圍)
lower_red1, upper_red1 = np.array([0, 70, 50]), np.array([10, 255, 255])
lower_red2, upper_red2 = np.array([170, 70, 50]), np.array([180, 255, 255])

# Step 3. 定義綠色範圍
lower_green, upper_green = np.array([40, 100, 100]), np.array([90, 255, 255])

# Step 4. 建立紅色與綠色的遮罩
mask_red = cv2.inRange(hsv, lower_red1, upper_red1) | cv2.inRange(hsv, lower_red2, upper_red2)
mask_green = cv2.inRange(hsv, lower_green, upper_green)

# Step 5. 計算紅色與綠色的比例
red_rate = np.sum(mask_red > 0) / mask_red.size
green_rate = np.sum(mask_green > 0) / mask_green.size

# Step 6. 視覺化結果
fig, axes = plt.subplots(1, 3, figsize=(20, 6))
axes[0].set_title(f"Red Mask: {red_rate:.2%}")
axes[0].imshow(mask_red, cmap='gray')
axes[0].axis("off")

axes[1].set_title(f"Green Mask: {green_rate:.2%}")
axes[1].imshow(mask_green, cmap='gray')
axes[1].axis("off")

axes[2].set_title("Original Image")
axes[2].imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
axes[2].axis("off")

plt.show()

# Step 7. 判斷結果
if red_rate > green_rate and red_rate > 0.01:
return "🔴 紅燈"
elif green_rate > red_rate and green_rate > 0.01:
return "🟢 綠燈"
else:
return "⚪ 未偵測到紅或綠燈"

4. 程式邏輯解析

(1) 轉換到 HSV 色彩空間

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

OpenCV 讀入影像是 BGR,要先轉成 HSV


(2) 設定顏色範圍

lower_red1, upper_red1 = np.array([0, 70, 50]), np.array([10, 255, 255])
lower_red2, upper_red2 = np.array([170, 70, 50]), np.array([180, 255, 255])
lower_green, upper_green = np.array([40, 70, 50]), np.array([90, 255, 255])
  • 紅色因為 Hue 角度是 0° 或 180° 附近,需要分成兩段判斷。
  • 綠色大約落在 40°~90° 的範圍。

(3) 計算紅/綠像素比例

red_rate = np.sum(mask_red > 0) / mask_red.size
green_rate = np.sum(mask_green > 0) / mask_green.size

統計有多少像素落在紅色或綠色的範圍,比例越高,代表該顏色燈號越亮。


(4) 簡單判斷邏輯

if red_rate > green_rate and red_rate > 0.01:
return "🔴 紅燈"
elif green_rate > red_rate and green_rate > 0.01:
return "🟢 綠燈"
else:
return "⚪ 未偵測到紅或綠燈"

設定 0.01 當作亮度比例的下限,避免雜訊造成誤判。


5. 如何測試

假設有一張紅綠燈照片 traffic_light.jpg

img = cv2.imread("traffic_light.jpg")
result = detect_traffic_light_hsv(img)
print(result)

執行後,終端輸出:

🟢 綠燈

同時彈出視覺化視窗:

  • 左圖 → 紅色遮罩
  • 中圖 → 綠色遮罩
  • 右圖 → 原圖

6. 進階技巧

(1) 限制 ROI (Region of Interest)

若紅綠燈位置固定,可以只分析該區域:

roi = img[50:200, 100:300]
detect_traffic_light_hsv(roi)

(2) 加入模糊處理降低雜訊

blur = cv2.GaussianBlur(img, (5, 5), 0)

讓燈光更集中,提升辨識穩定性。




留言
avatar-img
留言分享你的想法!
avatar-img
螃蟹_crab的沙龍
154會員
300內容數
本業是影像辨識軟體開發,閒暇時間進修AI相關內容,將學習到的內容寫成文章分享。 興趣是攝影,踏青,探索未知領域。 人生就是不斷的挑戰及自我認清,希望老了躺在床上不會後悔自己什麼都沒做。
螃蟹_crab的沙龍的其他內容
2025/05/02
拍攝時鏡頭有時候有粉塵或毛髮不管什麼的異物,拍攝完回家檢查圖片才發現有異物真的會氣死。 框選異物 修復後 這篇教學文章將介紹如何使用 PyQt5 和 OpenCV 來製作一款圖片異物修復工具。這個工具允許使用者載入圖片、框選異物區域,並使用 OpenCV 的 inpaint 方法來修復圖片,
Thumbnail
2025/05/02
拍攝時鏡頭有時候有粉塵或毛髮不管什麼的異物,拍攝完回家檢查圖片才發現有異物真的會氣死。 框選異物 修復後 這篇教學文章將介紹如何使用 PyQt5 和 OpenCV 來製作一款圖片異物修復工具。這個工具允許使用者載入圖片、框選異物區域,並使用 OpenCV 的 inpaint 方法來修復圖片,
Thumbnail
2025/03/24
在影像處理或機器學習的應用中,我們常常需要將影片逐幀擷取出來,進一步進行辨識或分析。 本篇教學將示範如何使用 Python + OpenCV 來: ✅ 讀取 MP4 影片 測試影片可由下方超連結下載,從file-examples.com下載 file-examples.com 是一個 免費提
Thumbnail
2025/03/24
在影像處理或機器學習的應用中,我們常常需要將影片逐幀擷取出來,進一步進行辨識或分析。 本篇教學將示範如何使用 Python + OpenCV 來: ✅ 讀取 MP4 影片 測試影片可由下方超連結下載,從file-examples.com下載 file-examples.com 是一個 免費提
Thumbnail
2024/10/11
本文將指導你如何修改現有的 OpenCV 程式碼,使其利用 CUDA 加速進行深度神經網絡(DNN)推理,如超分辨率圖像放大任務。這將顯著提升運行速度,特別是在高分辨率圖像處理中。 在CMake上這選項要開,才可支援DNN模組。 CMake編譯OpenCV教學文 連結 [OpenCV][Py
Thumbnail
2024/10/11
本文將指導你如何修改現有的 OpenCV 程式碼,使其利用 CUDA 加速進行深度神經網絡(DNN)推理,如超分辨率圖像放大任務。這將顯著提升運行速度,特別是在高分辨率圖像處理中。 在CMake上這選項要開,才可支援DNN模組。 CMake編譯OpenCV教學文 連結 [OpenCV][Py
Thumbnail
看更多
你可能也想看
Thumbnail
還在煩惱平凡日常該如何增添一點小驚喜嗎?全家便利商店這次聯手超萌的馬來貘,推出黑白配色的馬來貘雪糕,不僅外觀吸睛,層次豐富的雙層口味更是讓人一口接一口!本文將帶你探索馬來貘雪糕的多種創意吃法,從簡單的豆漿燕麥碗、藍莓果昔,到大人系的奇亞籽布丁下午茶,讓可愛的馬來貘陪你度過每一餐,增添生活中的小確幸!
Thumbnail
還在煩惱平凡日常該如何增添一點小驚喜嗎?全家便利商店這次聯手超萌的馬來貘,推出黑白配色的馬來貘雪糕,不僅外觀吸睛,層次豐富的雙層口味更是讓人一口接一口!本文將帶你探索馬來貘雪糕的多種創意吃法,從簡單的豆漿燕麥碗、藍莓果昔,到大人系的奇亞籽布丁下午茶,讓可愛的馬來貘陪你度過每一餐,增添生活中的小確幸!
Thumbnail
本文將說明如何去辨識出圖片文字​位置及高寬。
Thumbnail
本文將說明如何去辨識出圖片文字​位置及高寬。
Thumbnail
在某些特殊情況下,需要將圖片進行黑白反轉,例如Tesseract(OCR辨識引擎)就有建議黑底白字的狀況下辨識率較高。 本文將使用 NumPy 進行影像黑白反轉,並顯示反轉前後的影像。
Thumbnail
在某些特殊情況下,需要將圖片進行黑白反轉,例如Tesseract(OCR辨識引擎)就有建議黑底白字的狀況下辨識率較高。 本文將使用 NumPy 進行影像黑白反轉,並顯示反轉前後的影像。
Thumbnail
在影像辨識中,若遇到物件與背景難以分辨的狀況下,先做一下色彩分析,知道了色彩強度階層上的像素數,有助於了解後續需要做什麼處理,比較好分割出辨識物。 若想辨識的物件與背景的RGB值過於接近,也比較好說明此狀況,為什麼較難分割出物件。 成果呈現 第一張圖:左邊為原圖,右邊為分析結果的圖,用其他顏
Thumbnail
在影像辨識中,若遇到物件與背景難以分辨的狀況下,先做一下色彩分析,知道了色彩強度階層上的像素數,有助於了解後續需要做什麼處理,比較好分割出辨識物。 若想辨識的物件與背景的RGB值過於接近,也比較好說明此狀況,為什麼較難分割出物件。 成果呈現 第一張圖:左邊為原圖,右邊為分析結果的圖,用其他顏
Thumbnail
上一篇提到利用cv2.inRangex,建立遮罩來過濾出紅球。這次我們稍微更動一下程式碼,將紅球變顏色。 [OpenCV][Python]利用cv2.inRange搭配cv2.bitwise_and過濾紅球 結果圖 將紅球改變顏色成藍球
Thumbnail
上一篇提到利用cv2.inRangex,建立遮罩來過濾出紅球。這次我們稍微更動一下程式碼,將紅球變顏色。 [OpenCV][Python]利用cv2.inRange搭配cv2.bitwise_and過濾紅球 結果圖 將紅球改變顏色成藍球
Thumbnail
用小畫家隨意畫三個圈分別用紅藍綠,我們利用cv2.inRange與搭配cv2.bitwise_and,將紅球過濾出來吧。 程式範例 因為OpenCV中cv2.imread讀取圖檔預設讀取是為[B,G,R]的格式,所以設置紅色範圍要注意設定在R的範圍內。
Thumbnail
用小畫家隨意畫三個圈分別用紅藍綠,我們利用cv2.inRange與搭配cv2.bitwise_and,將紅球過濾出來吧。 程式範例 因為OpenCV中cv2.imread讀取圖檔預設讀取是為[B,G,R]的格式,所以設置紅色範圍要注意設定在R的範圍內。
Thumbnail
介紹OpenCV中的cv2.matchTemplate和cv2.minMaxLoc函數的使用方法和參數,提供程式範例以及相關特徵匹配的詳細介紹,讓讀者對此有更深入的瞭解。
Thumbnail
介紹OpenCV中的cv2.matchTemplate和cv2.minMaxLoc函數的使用方法和參數,提供程式範例以及相關特徵匹配的詳細介紹,讓讀者對此有更深入的瞭解。
Thumbnail
觀看本文將可以學習到如何利用Numpy求得物件的邊緣點,及算出物件的寬跟高。 有詳細的程式邏輯說明,及各函式用法說明。 綠點及紅點則是採樣到的邊界點,比較粗的點是偵測到的最大值 完整程式碼 import cv2 import numpy as np import matplotl
Thumbnail
觀看本文將可以學習到如何利用Numpy求得物件的邊緣點,及算出物件的寬跟高。 有詳細的程式邏輯說明,及各函式用法說明。 綠點及紅點則是採樣到的邊界點,比較粗的點是偵測到的最大值 完整程式碼 import cv2 import numpy as np import matplotl
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News