🧪 新教程持续更新中 · 从机械臂到传感器,跟着教程从零搭建
跳到主要内容

第 6 章:颜色识别

淘宝店铺

本章目标:让 NanoCam 识别画面中物体的颜色,并获取坐标用于分拣等应用。

原理

基于 HSV(色调-饱和度-明度)色彩空间。摄像头输出的 RGB565 图像经 esp-dl 的 ColorDetector 引擎处理,将图像缩放到 80×80 分辨率降噪后,逐像素转换为 HSV 值,与预设的 7 种颜色阈值进行匹配。

预设颜色阈值(OpenCV 标准 H 范围,0-180 标度)

颜色色相(H)饱和度(S)明度(V)面积门槛
红色0-1570-25590-25564
黄色23-3370-25590-25564
绿色34-7570-25590-25564
蓝色97-12470-25590-25564
紫色125-15570-25590-25564
白色0-1800-40200-25580
黑色0-1800-2550-5080

色相使用 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中心点 Xint16 BE
0x2A-0x2B中心点 Yint16 BE
0x2C-0x2D识别 IDint16 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 章:二维码扫描