图像基础与色彩空间:RGB、HSV、Lab 详解

做图像处理,尤其是暗部提亮和高光压缩这类活儿,第一个绕不开的就是色彩空间。说白了,就是计算机怎么“理解”颜色。

我刚开始接触这行的时候,觉得 RGB 就够了啊,红绿蓝三通道,多直观。后来做了一次低光照图像的增强项目,直接用 RGB 调亮度,结果颜色全飘了,人脸跟得了黄疸似的。嗯,从那以后我才意识到——选对色彩空间,比调参数重要得多。

RGB 色彩空间:最熟悉,但未必最合适

RGB 是硬件最爱的模型。显示器、摄像头、手机屏幕,全是 RGB 的天下。每个像素用三个值表示红、绿、蓝的强度,范围通常是 0-255。

但 RGB 有个致命问题:三个通道都携带亮度信息。你调整任何一个通道,亮度和颜色会同时变化。这就麻烦了——我只想提亮暗部,结果颜色也跟着变,后期还得花时间校色。

核心痛点:RGB 中亮度与色度高度耦合,不适合做独立的亮度调整。

HSV 色彩空间:把颜色和亮度分开

HSV 把颜色拆成三个分量:色相(Hue)、饱和度(Saturation)、明度(Value)。这下好了,明度单独一个通道,调整亮度不会影响颜色。

分量 含义 范围(OpenCV)
H 色相,决定是什么颜色 0-179
S 饱和度,决定颜色浓淡 0-255
V 明度,决定亮度 0-255

我在做肤色检测的时候经常用 HSV。因为不管光线怎么变,肤色的 H 值基本稳定在 0-20 之间。你想想看,这在 RGB 里根本做不到。

但 HSV 也有短板。它的 V 通道对亮度的感知并不线性。人眼对暗部变化敏感,对亮部变化迟钝,而 V 通道是均匀采样的。这就导致一个问题:你在 V 通道上做提亮,暗部细节可能还没出来,高光已经过曝了。

Lab 色彩空间:为什么它更适合亮度处理?

Lab 是 CIE 组织制定的色彩空间,设计目标就是接近人眼视觉感知。它有三个通道:

  • L 通道:亮度,范围 0-100,完全独立
  • a 通道:绿色到红色的分量
  • b 通道:蓝色到黄色的分量

Lab 最大的优势是什么?L 通道的亮度变化,跟人眼感受到的亮度变化是一致的。你在 L 通道上提亮 10 个单位,人眼看到的就是均匀变亮了 10%。这在 RGB 和 HSV 里都做不到。

我的经验:做暗部提亮时,我习惯先把图像转到 Lab,只处理 L 通道,a 和 b 完全不动。这样既能提亮暗部,又不会引入色偏。做完再转回 RGB,效果比在 RGB 里直接调好太多了。

另外,Lab 的色域比 RGB 大得多。RGB 只能表示显示器能显示的颜色,而 Lab 覆盖了所有人眼可见的颜色。这意味着你在 Lab 里做处理,不会丢失那些 RGB 范围之外的色彩信息。

注意:Lab 的 L 通道范围是 0-100,而 OpenCV 中存储时通常用 0-255 表示。转换时要注意数据范围,否则会出现截断。

三种色彩空间对比

特性 RGB HSV Lab
亮度与色度耦合度 高 中 低
亮度感知线性 差 一般 好
色域范围 窄 中 宽
适合亮度调整 否 勉强 是
适合颜色调整 否 是 是

实战:使用 OpenCV 进行色彩空间转换

下面我带你走一遍代码。OpenCV 默认读取的图像是 BGR 格式(不是 RGB,注意这个坑),转换函数都在 cv2.COLOR_* 下面。

import cv2
import numpy as np

# 读取图像(默认 BGR)
img = cv2.imread('photo.jpg')

# 转 HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# 转 Lab
lab = cv2.cvtColor(img, cv2.COLOR_BGR2Lab)

# 分离通道
l, a, b = cv2.split(lab)

# 对 L 通道做提亮(比如加 30)
l_enhanced = cv2.add(l, 30)

# 合并通道
lab_enhanced = cv2.merge([l_enhanced, a, b])

# 转回 BGR
result = cv2.cvtColor(lab_enhanced, cv2.COLOR_Lab2BGR)

# 保存结果
cv2.imwrite('result.jpg', result)

这段代码很简单,但有几个地方要注意:

  • cv2.add 会自动做截断,保证值不超过 255。但 Lab 的 L 通道理论范围是 0-100,直接加 30 可能会溢出。我建议先归一化再处理。
  • 转换时用 cv2.COLOR_BGR2Lab,不是 RGB2Lab。OpenCV 的默认通道顺序是 BGR。
  • 处理完一定要转回 BGR 再保存,否则颜色会乱。
避坑指南:我曾经在项目里直接用 cv2.imshow 显示 Lab 图像,结果一片漆黑。因为 imshow 默认按 BGR 解析,Lab 的三个通道值跟 BGR 完全不搭。记住:显示前一定要转回 BGR。

知识结构图:色彩空间选择逻辑

下面这张图帮你理清思路:什么时候该用哪个色彩空间。

色彩空间选择逻辑 输入图像 处理目标是什么? 亮度调整 → Lab 颜色调整 → HSV 显示/存储 → RGB 核心原则 亮度处理首选 Lab,颜色处理首选 HSV 最终输出一定要转回 RGB/BGR

总结一下我的个人习惯:

  • 做暗部提亮、高光压缩、对比度调整 → 用 Lab,只动 L 通道
  • 做颜色增强、肤色检测、色调调整 → 用 HSV,只动 H 和 S 通道
  • 做最终输出、显示、保存 → 转回 RGB/BGR

你想想看,如果一开始就选对了色彩空间,后面能省多少调参的功夫?