在做视觉相关开发时,颜色空间几乎是绕不开的话题。
无论是做目标检测、颜色识别、缺陷检测,还是最简单的阈值分割,你都会很快发现:
选对颜色空间,比你调一百个参数都重要。
这篇文章我结合一段完整、可运行的 Python + OpenCV 示例代码,带你系统梳理:
-
OpenCV 中常见的颜色空间
-
各种颜色空间之间的转换方法
-
通道分离与合并的直观理解
-
为什么HSV 是工程中最常用的颜色检测空间
整篇内容偏工程实践,适合刚入门视觉、或者正在做工业视觉/机器人项目的同学。
一、为什么 OpenCV 默认是 BGR?
很多人第一次用 OpenCV 都会有个疑问:
为什么我明明是红色,显示出来却不对?
原因很简单:
-
OpenCV 默认使用的是 BGR 顺序
-
而我们日常接触最多的是 RGB
这并不是错误,而是 OpenCV 的历史设计选择。
所以在 OpenCV 中,任何颜色处理之前,你都要先搞清楚当前图像处于什么颜色空间。
二、构造一张示例图像(非常重要)
在学习颜色空间时,强烈建议你不要直接用真实图片,而是先用"可控的标准颜色"。
下面这段代码创建了一张 300 × 300 的示例图像,包含:
-
红、绿、蓝
-
黄、紫、青
-
黑、白、灰
这样你在观察转换结果时,不会被环境光、噪声干扰。
python
import cv2
import numpy as np
def create_sample_image():
img = np.zeros((300, 300, 3), dtype=np.uint8)
img[0:100, 0:100] = (0, 0, 255) # Red
img[0:100, 100:200] = (0, 255, 0) # Green
img[0:100, 200:300] = (255, 0, 0) # Blue
img[100:200, 0:100] = (0, 255, 255) # Yellow
img[100:200, 100:200] = (255, 0, 255)# Purple
img[100:200, 200:300] = (255, 255, 0)# Cyan
img[200:300, 0:100] = (255, 255, 255)# White
img[200:300, 100:200] = (128, 128, 128)# Gray
img[200:300, 200:300] = (0, 0, 0) # Black
return img
如图示

三、BGR 与 RGB 转换(最基础但最容易踩坑)
def bgr_to_rgb(img):
return cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
这个转换通常发生在:
-
OpenCV → Matplotlib
-
OpenCV → Web 前端
-
OpenCV → 其他视觉库
记住一句话:
只要颜色不对,第一件事就是检查是不是 BGR / RGB 搞反了。
如图示:

四、BGR → 灰度(图像处理的起点)
python
def bgr_to_gray(img):
return cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
灰度图在工程中非常常见:
-
边缘检测
-
二值化
-
形态学操作
-
模板匹配
很多复杂算法,第一步就是灰度化。
如图示:

五、BGR → HSV(工程中最常用)
python
def bgr_to_hsv(img):
return cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
HSV 把颜色拆成了:
-
H(色相):是什么颜色
-
S(饱和度):颜色有多纯
-
V(亮度):有多亮
这也是为什么在工业视觉里:
只要是做颜色检测,90% 的情况都在用 HSV。

六、Lab / YUV:更偏算法与显示
python
def bgr_to_lab(img):
return cv2.cvtColor(img, cv2.COLOR_BGR2Lab)
def bgr_to_yuv(img):
return cv2.cvtColor(img, cv2.COLOR_BGR2YUV)
简单说:
-
Lab:更符合人眼感知,常用于颜色差异计算
-
YUV:视频编码、亮度与色度分离
在入门阶段,了解即可,不是高频必用。
Lab如图示:

YUV如图示:

七、通道分离:真正理解"颜色"的结构
python
def split_channels(img):
channels = cv2.split(img)
colored_channels = []
for i in range(len(channels)):
channel_img = np.zeros_like(img)
channel_img[:, :, i] = channels[i]
colored_channels.append(channel_img)
return channels, colored_channels
通道分离非常重要,它能帮你理解:
-
每个通道在"贡献什么"
-
为什么某些颜色在某个通道特别明显
这是从"调参数"走向"理解算法"的关键一步。
通道分离后,我把他们的B,G,R三通道分别分离出来,如图示:



八、HSV 颜色检测(真正的工程应用)
python
def hsv_color_detection(img, lower_hsv, upper_hsv):
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, lower_hsv, upper_hsv)
result = cv2.bitwise_and(img, img, mask=mask)
return mask, result
示例:检测红色区域
python
lower_red = np.array([0, 100, 100])
upper_red = np.array([10, 255, 255])
这一步你已经站在了:
-
工业颜色分选
-
视觉定位
-
机器人抓取前处理的门口。
九、完整运行结果
程序会自动生成以下文件:
-
原始示例图像
-
各种颜色空间转换结果
-
通道分离结果
-
HSV 颜色检测掩码与效果图
非常建议你:
一张一张打开看,对比理解,而不是只跑代码。
十、写在最后
很多人一上来就想:
YOLO、SAM、深度学习
但在真实工程中你会发现:
-
颜色空间 + 阈值 + 形态学
-
已经能解决大量实际问题
把这些基础打牢,你后面做 ROS、机器人视觉、工业相机项目时,
会非常轻松。
下一篇如果你愿意,我们可以继续写:
-
HSV 参数如何在真实工业现场标定
-
OpenCV + 工业相机的完整处理流程
-
视觉结果如何喂给机械臂
一步一步来,才是工程的正确打开方式。