[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的沙龍
150會員
294內容數
本業是影像辨識軟體開發,閒暇時間進修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
2025 vocus 推出最受矚目的活動之一——《開箱你的美好生活》,我們跟著創作者一起「開箱」各種故事、景點、餐廳、超值好物⋯⋯甚至那些讓人會心一笑的生活小廢物;這次活動不僅送出了許多獎勵,也反映了「內容有價」——創作不只是分享、紀錄,也能用各種不同形式變現、帶來實際收入。
Thumbnail
2025 vocus 推出最受矚目的活動之一——《開箱你的美好生活》,我們跟著創作者一起「開箱」各種故事、景點、餐廳、超值好物⋯⋯甚至那些讓人會心一笑的生活小廢物;這次活動不僅送出了許多獎勵,也反映了「內容有價」——創作不只是分享、紀錄,也能用各種不同形式變現、帶來實際收入。
Thumbnail
嗨!歡迎來到 vocus vocus 方格子是台灣最大的內容創作與知識變現平台,並且計畫持續拓展東南亞等等國際市場。我們致力於打造讓創作者能夠自由發表、累積影響力並獲得實質收益的創作生態圈!「創作至上」是我們的核心價值,我們致力於透過平台功能與服務,賦予創作者更多的可能。 vocus 平台匯聚了
Thumbnail
嗨!歡迎來到 vocus vocus 方格子是台灣最大的內容創作與知識變現平台,並且計畫持續拓展東南亞等等國際市場。我們致力於打造讓創作者能夠自由發表、累積影響力並獲得實質收益的創作生態圈!「創作至上」是我們的核心價值,我們致力於透過平台功能與服務,賦予創作者更多的可能。 vocus 平台匯聚了
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
Thumbnail
直方圖是對圖像中像素強度分布的圖形表示。通過分析直方圖,我們可以獲得有關圖像對比度、亮度和色彩分佈的有用信息。
Thumbnail
直方圖是對圖像中像素強度分布的圖形表示。通過分析直方圖,我們可以獲得有關圖像對比度、亮度和色彩分佈的有用信息。
Thumbnail
涉及圖像處理和計算機視覺時,色彩空間轉換是一個常見操作,應用如下: 降維: 將一張彩色圖像轉換為灰度圖像可以減少數據的維度,簡化處理過程,同時在某些情況下保留重要的視覺信息。 突顯特徵: 在某些情況下,某些色彩通道可能包含冗餘或不必要的信息,通過轉換到其他色彩空間,可以更好地突顯圖像中的重要特徵
Thumbnail
涉及圖像處理和計算機視覺時,色彩空間轉換是一個常見操作,應用如下: 降維: 將一張彩色圖像轉換為灰度圖像可以減少數據的維度,簡化處理過程,同時在某些情況下保留重要的視覺信息。 突顯特徵: 在某些情況下,某些色彩通道可能包含冗餘或不必要的信息,通過轉換到其他色彩空間,可以更好地突顯圖像中的重要特徵
Thumbnail
本文介紹OpenCV中的SimpleBlobDetector用於檢測斑點或圓,以及其與霍夫轉換找圓方法的差異。透過程式範例和解析,講解檢測到的關鍵點和設定參數,並整理SimpleBlobDetector與霍夫轉換的不同。最後,探討不同的應用場景和參數調整。
Thumbnail
本文介紹OpenCV中的SimpleBlobDetector用於檢測斑點或圓,以及其與霍夫轉換找圓方法的差異。透過程式範例和解析,講解檢測到的關鍵點和設定參數,並整理SimpleBlobDetector與霍夫轉換的不同。最後,探討不同的應用場景和參數調整。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News