色彩空間的世界: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用於膚色檢測)。
色彩空間轉換是圖像處理的基礎技能,掌握它能讓你更靈活地處理圖像中的顏色信息,快去動手試試吧!