第 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 色モードに入る
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 スレーブ(アドレス 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 ベース:
// 検出器を構築、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 章:QR コードスキャン

