色彩空間的世界:Python OpenCV帶你入門與實戰

一、什麼是色彩空間?

在我們的日常中,看到的顏色其實是由不同的「色彩表示方式」編碼的。就像我們用不同的語言描述同一個東西,色彩空間就是計算機用來表示顏色的「語言」。

最常見的色彩空間有三種:
- RGB:我們最熟悉的,由紅(Red)、綠(Green)、藍(Blue)三個通道組成。每個通道用0-255的數值表示亮度,比如純紅色是(255, 0, 0)。
- BGR:OpenCV讀取圖像時默認使用的是BGR,而不是RGB!順序是藍(Blue)、綠(Green)、紅(Red)。比如圖像中紅色的像素在BGR中是(0, 0, 255),而不是RGB的(255, 0, 0)——這點非常關鍵,初學者容易搞混。
- HSV:對人眼更友好的色彩空間,由色相(Hue)、飽和度(Saturation)、明度(Value)三個部分組成:
- 色相(H):顏色的種類(如紅、綠、藍),範圍0-179(OpenCV中)。
- 飽和度(S):顏色的鮮豔程度,0-255,數值越大顏色越純。
- 明度(V):顏色的亮度,0-255,數值越大越亮。

二、爲什麼要轉換色彩空間?

不同的色彩空間有不同的「用途」:
- RGB:適合顯示和屏幕顯示,因爲它直接對應屏幕的紅綠藍像素髮光。
- HSV:適合顏色分割與識別!比如要從圖像中提取紅色區域,用HSV更容易,因爲「色相」只和顏色種類有關,不管亮度多高(比如深紅和亮紅在HSV中H值相近)。
- BGR:OpenCV的「原生語言」,所有圖像數據默認是BGR格式,處理圖像時需注意轉換。

三、OpenCV色彩空間轉換的基礎操作

Python中OpenCV的cv2.cvtColor()函數是實現色彩空間轉換的核心工具,語法如下:

import cv2
img = cv2.imread('your_image.jpg')  # 讀取圖像(默認BGR格式)
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)  # 轉換爲HSV

參數解析
- img:輸入圖像(必須是NumPy數組)。
- cv2.COLOR_BGR2HSV:轉換代碼,格式爲COLOR_原空間2目標空間
- 常見轉換代碼:
- COLOR_BGR2RGB:BGR轉RGB(注意OpenCV讀入的是BGR,若想轉爲Python的RGB顯示,需用此轉換)。
- COLOR_BGR2GRAY:轉爲灰度圖。
- COLOR_RGB2HSV:RGB轉HSV(但OpenCV讀取圖像是BGR,所以實際用COLOR_BGR2HSV更常見)。

四、實戰案例:用HSV識別並提取紅色物體

下面我們用靜態圖像或攝像頭即時處理,來提取圖像中的紅色物體。步驟如下:

步驟1:讀取圖像並轉換爲HSV

import cv2
import numpy as np

# 讀取圖像(替換爲你的圖像路徑)
img = cv2.imread('red_object.jpg')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)  # 轉爲HSV

步驟2:定義紅色在HSV中的範圍
紅色在HSV中分爲兩個區間(因爲色相H在0-179中,紅色接近0和179):
- 低亮度紅色:H≈0-10,S≈50-255,V≈50-255
- 高亮度紅色:H≈160-179,S≈50-255,V≈50-255

cv2.inRange()創建掩碼(Mask),只保留紅色區域:

# 定義紅色範圍(低紅和高紅)
lower_red1 = np.array([0, 50, 50])
upper_red1 = np.array([10, 255, 255])
lower_red2 = np.array([160, 50, 50])
upper_red2 = np.array([179, 255, 255])

# 合併兩個紅色區間
lower_red = np.vstack((lower_red1, lower_red2))
upper_red = np.vstack((upper_red1, upper_red2))

# 創建紅色掩碼(1爲紅色區域,0爲其他)
mask = cv2.inRange(hsv, lower_red, upper_red)

步驟3:應用掩碼,提取紅色區域

# 用掩碼覆蓋原圖,只保留紅色區域
result = cv2.bitwise_and(img, img, mask=mask)

# 顯示結果
cv2.imshow('Original', img)
cv2.imshow('Red Mask', mask)
cv2.imshow('Red Extracted', result)
cv2.waitKey(0)  # 按任意鍵退出
cv2.destroyAllWindows()

五、進階:用攝像頭即時檢測紅色物體

如果想即時捕捉攝像頭畫面中的紅色物體,只需將cv2.imread()換成cv2.VideoCapture(0)(0爲攝像頭索引):

cap = cv2.VideoCapture(0)  # 打開攝像頭

while True:
    ret, frame = cap.read()  # 讀取一幀
    if not ret:
        break
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)  # 轉爲HSV
    mask = cv2.inRange(hsv, lower_red, upper_red)  # 紅色掩碼
    result = cv2.bitwise_and(frame, frame, mask=mask)  # 提取紅色
    cv2.imshow('Real-time Red Detection', result)

    if cv2.waitKey(1) & 0xFF == ord('q'):  # 按q退出
        break

cap.release()
cv2.destroyAllWindows()

六、總結與擴展

  • 關鍵點:色彩空間轉換的核心是cv2.cvtColor(),HSV適合顏色分割,BGR是OpenCV默認格式。
  • 注意事項:不同光線條件下,顏色範圍需微調(比如燈光下紅色可能更亮,V值要提高)。
  • 擴展方向:嘗試識別其他顏色(如藍色、綠色),只需調整HSV範圍;學習更多色彩空間(如YCrCb用於膚色檢測)。

色彩空間轉換是圖像處理的基礎技能,掌握它能讓你更靈活地處理圖像中的顏色信息,快去動手試試吧!

小夜