第 6 章:顏色辨識
本章目標:讓 NanoCam 識別畫面中物體的顏色,並獲取座標用於分揀等應用。
原理
基於 HSV(色調-飽和度-明度)色彩空間。攝影機輸出的 RGB565 影像經 esp-dl 的 ColorDetector 引擎處理,將影像縮放至 80×80 解析度並降噪後,逐像素轉換為 HSV 值,與預設的 7 種顏色閾值進行匹配。
預設顏色閾值(OpenCV 標準 H 範圍,0-180 標度)
| 顏色 | 色相(H) | 飽和度(S) | 明度(V) | 面積門檻 |
|---|---|---|---|---|
| 紅色 | 0-15 | 70-255 | 90-255 | 64 |
| 黃色 | 23-33 | 70-255 | 90-255 | 64 |
| 綠色 | 34-75 | 70-255 | 90-255 | 64 |
| 藍色 | 97-124 | 70-255 | 90-255 | 64 |
| 紫色 | 125-155 | 70-255 | 90-255 | 64 |
| 白色 | 0-180 | 0-40 | 200-255 | 80 |
| 黑色 | 0-180 | 0-255 | 0-50 | 80 |
色相使用 OpenCV 0-180 標度(對應 0-360°)。
set_bgr(false)確保函式庫原樣讀取 RGB565 數據,不交換通道。
步驟
6.1 進入顏色模式
Plain
ai_mode:3裝置會自動重啟並進入顏色偵測模式,WS2812 RGB LED(GPIO18)會顯示當前辨識到的顏色。
完整指令見串口協議手冊。
6.2 觀察辨識結果
將純色物體放在攝影機前,瀏覽器開啟 http://<IP> 會顯示:
- 彩色矩形框標註偵測到的顏色區域
- 顏色標籤文字(red/yellow/green/blue/purple/white/black)
- 框與標籤顏色與實際偵測顏色一致
顏色模式只做畫面疊加(OSD),不輸出串列日誌。需要取得座標時,請透過 I2C 暫存器讀取。
6.3 I2C 讀取偵測數據
NanoCam 作為 I2C Slave(地址 0x33,GPIO SDA=41 SCL=42),實時更新偵測框中心點座標。
| 暫存器 | 內容 | 數據類型 |
|---|---|---|
| 0x28-0x29 | 中心點 X | int16 BE |
| 0x2A-0x2B | 中心點 Y | int16 BE |
| 0x2C-0x2D | 辨識 ID | int16 BE |
程式碼
核心偵測引擎
components/modules/ai/who_color_detection.cpp — 基於 esp-dl ColorDetector:
C++
// 建構偵測器,set_bgr(false) 確保顏色通道正確
ColorDetector detector;
detector.set_bgr(false);
detector.set_detection_shape({80, 80, 1});
// 註冊 7 種顏色閾值
detector.register_color({h_lo, h_hi, s_lo, s_hi, v_lo, v_hi}, area_min, "red");
// 偵測
auto &results = detector.detect((uint16_t *)frame->buf,
{(int)frame->height, (int)frame->width, 3});
// 遍歷結果畫框+標籤
for (int ci = 0; ci < (int)results.size(); ci++) {
for (int ri = 0; ri < (int)results[ci].size(); ri++) {
color_detect_result_t &res = results[ci][ri];
draw_rect(frame, res.box[0], res.box[1], res.box[2], res.box[3], color_lcd);
fb_gfx_print(frame, lx, ly, color_lcd, color_name);
}
}效果
紅綠藍物體 → 辨識顏色 → 畫框 + 標籤 → I2C 輸出座標 → 可接舵機分揀。
下一章:第 7 章:二維條碼掃描

