3、颜色识别基础:理解RGB565颜色空间、LAB颜色空间及其在OpenMV中的表示,学习如何通过阈值编辑器(Threshold Editor)获取目标颜色的LAB阈值

颜色识别是OpenMV目标追踪项目的基石。无论是追踪红色小球、识别蓝色路标,还是区分不同颜色的物料,第一步都是让摄像头“看懂”颜色。然而,摄像头输出的原始数据是RGB格式,而OpenMV官方推荐的阈值配置却基于LAB颜色空间。为什么不用RGB?LAB到底有什么优势?阈值编辑器里的六个数值(L Min、L Max、A Min、A Max、B Min、B Max)分别代表什么?本章将系统拆解RGB565与LAB颜色空间的数学原理、OpenMV内部的表示方式,并手把手演示如何通过阈值编辑器获取稳定可靠的目标颜色阈值。

RGB565 → LAB 颜色识别链路与阈值编辑器工作流 摄像头传感器 输出 RGB565 原始数据 RGB565 颜色空间 R:5bit G:6bit B:5bit 共 65536 种颜色 LAB 颜色空间 L:亮度 A:绿红 B:蓝黄 感知均匀,抗光照干扰 阈值编辑器 获取 LAB 阈值 步骤1:采集图像 sensor.snapshot() 步骤2:打开阈值编辑器 Tools → Threshold Editor 步骤3:框选目标区域 鼠标拖拽选择颜色区域 步骤4 微调阈值 LAB 阈值六元组示例(红色小球) thresholds = (30, 80, 25, 80, 10, 60) L: 30~80(亮度范围) A: 25~80(红绿分量) B: 10~60(蓝黄分量) A值越大越红,B值越大越黄;通过调整上下限锁定目标颜色。

3.1 RGB565颜色空间:OpenMV的原始数据格式

3.1.1 核心原理:16位色深与像素存储

OpenMV Cam的感光元件(如OV7725)输出的是RGB565格式的原始图像数据。所谓RGB565,是指每个像素用16位(2字节)二进制数表示颜色,其中红色分量占用高5位,绿色分量占用中间6位,蓝色分量占用低5位。绿色多分配1位是因为人眼对绿色最敏感,这样可以在有限位宽内获得更好的视觉感知效果。

具体来说,一个16位像素的位分布为:RRRRRGGGGGGBBBBB。红色和蓝色各有32个等级(2^5=32),绿色有64个等级(2^6=64),因此总颜色数为32×64×32=65536种。相比PC上常见的RGB888(24位,约1670万色),RGB565的色域较窄,但对于嵌入式视觉应用已经足够。

为什么OpenMV不直接使用RGB888? 主要受限于硬件带宽和存储空间。RGB565每个像素仅占2字节,320×240分辨率的帧缓冲区仅需约150KB,而RGB888则需要约225KB。对于STM32F765这类主控芯片,内存和总线带宽都有限,RGB565是性能与精度的折中方案。

3.1.2 判断方法:RGB565的局限性

虽然RGB565是OpenMV的底层格式,但在颜色识别中直接使用RGB值存在两个严重问题:

  • 光照敏感:RGB三个通道高度相关,当环境光照变化时,同一物体的RGB值会剧烈波动。例如,红色小球在强光下R值可能从200变为240,在阴影下可能降到120,导致阈值难以固定。
  • 通道耦合:RGB中改变任何一个通道的值,人眼感知到的颜色变化是非线性的。比如R从100增加到150,与从200增加到250,视觉上的颜色变化幅度完全不同。

因此,OpenMV官方推荐在LAB颜色空间中进行阈值设定,而不是直接使用RGB565的原始值。

3.2 LAB颜色空间:感知均匀的颜色模型

3.2.1 核心原理:L、A、B三个通道的物理含义

LAB颜色空间(CIELAB)由国际照明委员会(CIE)制定,旨在模拟人眼对颜色的感知方式。它将颜色分解为三个独立通道:

通道 名称 取值范围(OpenMV) 物理含义
L 亮度(Lightness) 0 ~ 100 0为纯黑,100为纯白,表示颜色的明暗程度
A 绿红分量(Green-Red) -128 ~ 127 负值偏绿,正值偏红,0为中性灰
B 蓝黄分量(Blue-Yellow) -128 ~ 127 负值偏蓝,正值偏黄,0为中性灰

LAB的核心优势在于感知均匀性:两个颜色在LAB空间中的欧氏距离,与人眼感知到的颜色差异成正比。这意味着,如果红色和橙色的LAB距离为10,那么蓝色和紫色的LAB距离也为10时,人眼会认为这两组颜色的差异程度相同。这种特性使得LAB阈值可以更稳定地描述“颜色范围”。

3.2.2 OpenMV中的LAB表示:从RGB565到LAB的转换

OpenMV的IDE在显示图像时,会自动将RGB565像素转换为LAB值供阈值编辑器使用。转换过程分为两步:首先将RGB565扩展为RGB888(8位每通道),然后通过标准公式转换到LAB空间。OpenMV内部使用整数运算加速转换,因此LAB值会有一定的量化误差,但不会影响实际识别效果。

在OpenMV的Python API中,LAB阈值以六元组形式表示:(L_min, L_max, A_min, A_max, B_min, B_max)。例如,追踪红色小球时,阈值可能为(30, 80, 25, 80, 10, 60),表示亮度在30~80之间,A值在25~80之间(偏红),B值在10~60之间(偏黄)。

经验提示:在OpenMV中,LAB的A和B通道范围被归一化到-128~127,但阈值编辑器显示时通常只显示正数部分。实际使用时,如果目标颜色偏绿(A为负),需要将A_min设为负数,例如(-50, -10)。

3.3 阈值编辑器(Threshold Editor)实操指南

3.3.1 操作流程:从图像到阈值六元组

阈值编辑器是OpenMV IDE内置的可视化工具,它允许用户通过鼠标框选图像中的目标区域,自动计算该区域的LAB范围,并生成可用的阈值。以下是标准操作流程:

  1. 连接设备并运行基础脚本:在OpenMV IDE中连接开发板,运行一个简单的图像采集脚本(如sensor.snapshot()),确保IDE的帧缓冲区显示实时画面。
  2. 打开阈值编辑器:点击IDE菜单栏的 Tools → Machine Vision → Threshold Editor,或直接点击工具栏中的“阈值编辑器”图标。
  3. 框选目标区域:在编辑器左侧的实时图像窗口中,用鼠标左键拖拽一个矩形框,框住目标颜色区域。尽量选择颜色均匀、无阴影反光的部分。
  4. 查看自动生成的阈值:编辑器右侧会立即显示该区域的LAB最小值与最大值,并自动生成六元组阈值。同时,图像中符合该阈值的像素会被高亮显示(通常为红色蒙版)。
  5. 微调阈值:拖动L、A、B三个通道的滑块,观察高亮区域的变化。目标是让目标物体完全高亮,同时背景尽量不亮。注意L通道的调整对光照变化最敏感。
  6. 复制阈值到剪贴板:点击“Copy Threshold”按钮,将六元组复制到剪贴板,然后粘贴到你的Python代码中。

3.3.2 案例拆解:红色小球阈值获取与验证

假设我们要追踪一个红色乒乓球,环境为白色桌面,室内LED照明。以下是完整的阈值获取与验证过程:

步骤 操作 观察结果 调整策略
1 框选小球中心区域 自动生成阈值 (25, 70, 30, 90, 15, 65) 初始阈值可用,但高亮区域包含部分阴影
2 缩小L通道上限 L_max从70降到55 阴影部分L值较低,降低L_max可排除阴影
3 扩大A通道下限 A_min从30升到40 增强红色纯度要求,排除偏粉色的背景反光
4 验证背景不误检 白色桌面高亮区域消失 白色LAB的A、B值接近0,与红色阈值无交集
5 最终阈值 (25, 55, 40, 90, 15, 65) 小球完全高亮,背景无干扰

在实际项目中,还需要考虑不同光照条件下的鲁棒性。建议在一天中的不同时间段(自然光变化)或开关灯的情况下,分别采集阈值,取并集作为最终阈值。例如,强光下L值偏高,弱光下L值偏低,可以将L_min设为20,L_max设为80,覆盖更宽的亮度范围。

3.3.3 常见误区与总结复盘

误区1:直接使用RGB阈值。 有些初学者会尝试用find_blobs的RGB模式,但RGB阈值对光照极其敏感,稍微改变灯光角度就会失效。务必使用LAB阈值。

误区2:阈值范围设置过窄。 如果阈值只覆盖了目标物体在特定光照下的颜色,一旦物体移动或光照变化,就会丢失目标。建议在阈值编辑器中将滑块适当放宽10%~20%。

误区3:忽略L通道的作用。 L通道代表亮度,很多人在调整阈值时只关注A和B,导致在阴影或高光区域误检。L通道的上下限应该根据环境光照动态调整。

误区4:在阈值编辑器中只框选一个点。 应该框选目标物体上多个不同亮度的区域(如高光区、阴影区、中间调),让编辑器综合计算更全面的阈值范围。

总结复盘:颜色识别的本质是在LAB空间中定义一个“颜色球体”或“颜色立方体”,将目标颜色与背景分离。RGB565是硬件层的原始格式,LAB是应用层的识别空间。阈值编辑器是连接两者的桥梁,它通过可视化交互降低了阈值调试的难度。掌握LAB三个通道的物理含义,理解光照对L通道的影响,是稳定追踪目标颜色的关键。在实际项目中,建议将阈值获取过程标准化:固定摄像头位置和角度,控制环境光照,多次采样取并集,最后在代码中加入blob.area()过滤小面积噪点,进一步提升识别稳定性。