一、色彩空间
色彩空间是坐标系统定义的色彩范围,常见类型包括 RGB、CMYK、HSV、HSL 等。其核心是通过三色刺激值(红、绿、蓝三种主要颜色)建立颜色叠加模型,利用异谱同色原理实现颜色匹配。
我们可以在终端中使用 pip 安装 OpenCV 模块。默认是从国外的主站上下载,因此,我们可能会遇到网络不好的情况导致下载失败。我们可以在 pip 指令后通过 -i 指定国内镜像源下载。
pip install opencv-python -i https://mirrors.aliyun.com/pypi/simple
国内常用的 pip 下载源列表:
- 阿里云 https://mirrors.aliyun.com/pypi/simple
- 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple
- 清华大学 https://pypi.tuna.tsinghua.edu.cn/simple
- 中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple
1.1、GRAY色彩空间
GRAY(灰度图像)通常指 8 位灰度图,其具有 256 个灰度级,像素值范围是 [0, 255]。当图像有 RGB 色彩空间转换为 GRAY 色彩空间时,其处理方式如下:
上述是标准的转换方式,也是 OpenCV 中使用的转换方式。有时,也可以采用简化形式完成转换:
1.2、XYZ色彩空间
XYZ 色彩空间是设备独立的颜色空间,包含了所有人类能够察觉的颜色,不同于 RGB 颜色空间仅表示监视器所能显示的颜色范围。它基于人类颜色视觉的直接测定,充当许多其他色彩空间的定义基础。
将 RGB 色彩空间转换转换为 XYZ 色彩空间,其转换形式如下:
将 XYZ 色彩空间转换为 RGB 色彩空间,其转换格式如下:
1.3、YCrCb色彩空间
人眼视觉系统对颜色的敏感度要低于对亮度的敏感度。在传统的 RGB 色彩空间内,RGB 三原色具有相同的重要性,但是忽略了亮度信息。在 YCrCb 色彩空间中,Y 代表 光源的亮度,色彩信息保存在 Cr 和 Cb 中。其中,Cr 表示 红色分量信息,Cb 表示 蓝色分量信息。亮度给出了颜色亮或暗的程度信息,该信息可以通过照明中强度成分的加权和来计算。在 RGB 光源中,绿色分量的影响最大,蓝色分量的影响最小。
从 RGB 色彩空间到 YCrCb 色彩空间的转换公式如下:
其中,delta 的取值如下:
从 YCrCb 色彩空间到 RGB 色彩空间的转换公式如下:
1.4、HSV色彩空间
RGB 是从硬件的角度提出的颜色模型,在与人眼匹配的过程中可能存在一定的差异,HSV 色彩空间是一种面向视觉感知的颜色模型。HSV 色彩空间从心理学和视觉的角度出发,指出人眼的色彩知觉主要包含三要素:色调(也称为 色相)、饱和度 和 亮度。
- 色调:是指 光的颜色,与混合光谱中主要光波长有关。
- 饱和度:是指 色彩的相对纯净度,或一种颜色混合白光的数量。
- 亮度:是指人眼感受到的 光的明暗程度,该指标与物体的反射度有关。
在具体实现上,我们将物理空间的颜色分布在圆周上,不同的角度代表不同的颜色。因此,通过调整色调值就能选取不同的颜色,色调的取值区间为 [0, 369]。色调取不同的值时,所代表的颜色如下,两个角度之间的角度值对应两个颜色之间的过渡色。
| 色调值 | 颜色 |
|---|---|
| 0 | 红色 |
| 60 | 黄色 |
| 120 | 绿色 |
| 180 | 青色 |
| 240 | 蓝色 |
| 300 | 品红色 |
饱和度 为一比例值,范围是 [0, 1],具体为所选颜色的纯度值和该颜色最大纯度值之间的比值。饱和度的值为 0 时,只有灰色。
亮度 表示色彩的明亮程度,取值范围也是 [0, 1]。
在从 RGB 色彩空间转换到 HSV 色彩空间之前,需要先将 RGB 色彩空间的值转换到 [0, 1] 之前,然后在进行处理,具体处理方法如下:
计算结果可能存在 H < 0 的情况,如果出现这种情况,则需要对 H 进行进一步计算。
由上述公式计算可知:
1.5、HSL色彩空间
HLS 色彩空间包含的三要素是 色调、光亮/明亮 和 饱和度。
- 色调:表示人眼所能感知的颜色。在 HSL 模型中,所有的颜色分布在一个平面的色调环上,整个色调环为 360 度的圆心角,不同的角度代表不同的颜色。
- 光亮度/明度:用来控制色彩的明暗变化,它的取值范围也是 [0, 1]。
- 饱和度:使用 [0, 1] 的值描述相同色调、相同光亮度/明度下的色彩纯度变化。饱和度的值越大,表示颜色的纯度越高,颜色越鲜艳。反之,饱和度的值越小,色彩的纯度越低。
1.6、RGBA色彩空间
在 RGB 色彩空间三个通道的基础上,还可以加上一个 A 通道,也叫 Alpha 通道,表示 透明度。Alpha 通道的赋值范围是 [0, 1],或者 [0, 255],表示从透明到不透明。
二、类型转换函数
在 OpenCV 内,我们使用 cv2.cvtColor() 函数实现色彩空间的变化。该函数能够实现多个色彩空间之间的转换,其语法格式如下:
cvtColor(src: cv2.typing.MatLike, code: int, dst: cv2.typing.MatLike | None = ..., dstCn: int = ..., hint: AlgorithmHint = ...) -> cv2.typing.MatLike: ...
其中,src 参数是 原始输入图像,可以是 8 位无符号图像、16 位无符号图像,或者单精度浮点数等。code 参数是 色彩空间转换码,它是一个枚举值。dst 参数是 目标图像。dstCn 是 目标图像的通道数,如果参数为默认的 0,则通道数自动通过原始输入图像和 code 得到。
import sys
import cv2if __name__ == '__main__':cv2.namedWindow("window") # 1.创建窗口# OpenCV读取的图像默认是是BGR的色彩空间image = cv2.imread("assets/images/1.png") # 2.读取图像if image is None:print("加载图片失败")sys.exit(0)color_spaces = [cv2.COLOR_BGR2RGB, cv2.COLOR_BGR2RGBA, cv2.COLOR_BGR2GRAY, cv2.COLOR_BGR2HSV, cv2.COLOR_BGR2YUV]cv2.createTrackbar("color space", "window", 0, 4, lambda x: None) # 3.创建一个滑动条while True:index = cv2.getTrackbarPos("color space", "window") # 4.获取滑动条的位置corvert_image = cv2.cvtColor(image, color_spaces[index]) # 5.根据滑动条的位置转换图像的颜色空间cv2.imshow("window", corvert_image) # 6.显示图像key = cv2.waitKey(1) # 7.等待用户按键if key == ord('q'):breakcv2.destroyAllWindows() # 8.销毁所有窗口sys.exit(0) # 9.退出程序