4. 颜色模型与色彩空间:RGB与HSV模型对比
做色标传感器这些年,我踩过最大的坑就是——直接用RGB值做颜色识别。你想想看,一个红色标签,在强光下变成粉红,在阴影里变成暗红,RGB三个数全变了。这怎么玩?
今天我们就来聊聊颜色模型这件事。说白了,就是计算机怎么"看"颜色,以及我们怎么让它"看"得更准。
4.1 RGB模型:最直观,但最不实用
RGB大家都熟。红绿蓝三原色,每个通道0-255,组合出1600万种颜色。显示器、摄像头都用它。但做色标检测时,RGB有个致命问题——它对光照太敏感了。
我在一个包装线项目里遇到过这事。检测一个蓝色标签,白天良品率98%,到了傍晚车间开灯,直接掉到70%。查了半天,就是RGB值随环境光乱飘。
- 光照敏感:亮度一变,三个通道全变
- 颜色不直观:你说"深红色",RGB里对应什么?没人能直接说出来
- 通道耦合:调亮度会影响色相,调色相会影响亮度
举个例子。一个纯红色物体,RGB大约是(200, 30, 20)。光照减半后,变成(100, 15, 10)。你看,三个数都变了,但人眼一看还是红色。机器就懵了。
4.2 HSV模型:为视觉检测而生
HSV是什么?Hue(色相)、Saturation(饱和度)、Value(明度)。
这玩意儿的设计思路,说白了就是模仿人眼看颜色的方式。人眼先看"这是什么颜色"(色相),再看"颜色浓不浓"(饱和度),最后看"亮不亮"(明度)。
为什么HSV更适合色标检测?我直接说结论:
- 色相H对光照不敏感:红色标签,不管亮还是暗,H值基本不变
- 可以单独调参:想忽略阴影?把V的阈值放宽就行。想忽略反光?把S的阈值调一下
- 阈值设置直观:H在0-180之间(OpenCV里),红色大概在0-10和170-180,绿色在45-75,蓝色在100-130
4.3 色彩空间转换原理
摄像头出来的是RGB,我们要用HSV,中间就得转。这个转换其实是个数学公式,但咱们不用背,OpenCV一行代码搞定。
import cv2
import numpy as np
# 读取图像(BGR格式,OpenCV默认)
img = cv2.imread('label.jpg')
# 转换到HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# 定义红色的HSV范围
lower_red1 = np.array([0, 50, 50])
upper_red1 = np.array([10, 255, 255])
lower_red2 = np.array([170, 50, 50])
upper_red2 = np.array([180, 255, 255])
# 创建掩码
mask1 = cv2.inRange(hsv, lower_red1, upper_red1)
mask2 = cv2.inRange(hsv, lower_red2, upper_red2)
mask = cv2.bitwise_or(mask1, mask2)
# 显示结果
cv2.imshow('Red Detection', mask)
cv2.waitKey(0)
这里有个坑,我当年就栽过——OpenCV里H的范围是0-180,不是0-360。为什么?因为8位图像存不下360,所以除以2了。红色在0-180里对应0-10和170-180,而不是0-20和340-360。
4.4 知识体系总览
下面这张图,是我做色标检测时脑子里一直挂着的框架。你看一遍,后面调参心里就有底了。
4.5 实战中的选择建议
说了这么多,到底什么时候用RGB,什么时候用HSV?我直接给结论:
| 场景 | 推荐模型 | 原因 |
|---|---|---|
| 色标检测(标签、色卡) | HSV | 光照变化大,颜色纯度高 |
| 颜色分类(分拣水果) | HSV | 需要区分相近色,H通道最稳定 |
| 图像显示/存储 | RGB | 显示器、图片格式都用RGB |
| 颜色校准(实验室环境) | RGB或Lab | 光照可控,Lab更精确 |
嗯,关于颜色模型就聊到这儿。记住一句话:做色标检测,先转HSV,再调H阈值。这个习惯养成了,后面调参能省一半时间。
公众号:蓝海资料掘金营,微信deep3321