发布时间:2024-10-04 19:01
颜色空间也称彩色模型(又称彩色空间或彩色系统)它的用途是在某些标准下用通常可接受的方式对彩色加以说明。
RGB颜色空间是较常见的一种颜色空间,它通过红、绿、蓝3种颜色混合能够展示各种颜色,常用于显示和表示图像。了解图像的颜色空间对于分割拥有特征的图像具有重要的意义,例如提取像素中 的红色物体可以通过比较图像红色通道的像素值来实现。
RGB 颜色空间的名称是由红色(Red)、绿色(Green)、蓝色(Blue)三种颜色的英文首字母组成。RGB 颜色空间模型如下图所示。
3个通道对于颜色描述的范围都是相同的(0-255),RGB 颜色空间中的所有颜色都是通过这三种颜色通过不同比例混合得到的。如果3个颜色分量都为0则表示黑色,如果三个颜色分量都为255,则表示白色。在 RGB 颜色空间的基础上增加第四个通道 Alpha (表示颜色的透明度),就会形成 RGBA 颜色空间。
RGB 颜色空间适合于显示系统,却并不适合于图像处理。
人眼对于这三种颜色分量的敏感程度是不一样的,在单色中,人眼对红色最不敏感,蓝色最敏感,所以 RGB 颜色空间是一种均匀性较差的颜色空间。如果颜色的相似性直接用欧氏距离来度量,其结果与人眼视觉会有较大的偏差。对于某一种颜色,我们很难推测出较为精确的三个分量数值来表示。因此 RGB 颜色空间的均匀性非常差,且两种颜色之间的知觉差异色差不能表示为该颜色空间中两点间的距离,但是利用线性或非线性变换,则可以从 RGB 颜色空间推导出其他的颜色特征空间。
YUV 是通过亮度-色差来描述颜色的颜色空间,是电视信号系统常用的颜色编码方式,这3个变量分别表示的是图像的亮度(Y)、红色分量与亮度的信号差值(U)、蓝色分量与亮度的信号差值(V)。这种颜色主要用于视频和图像的传输,YUV 颜色空间的产生与电视机的发展例程密切相关。RGB 颜色空间与 YUV 颜色空间的转换关系如下。
{ Y = 0.299 R + 0.587 G + 0.114 B U = − 0.147 R − 0.289 G + 0.436 B V = 0.615 R − 0.515 G − 0.100 B { R = Y + 1.14 V G = Y − 0.39 U − 0.58 V B = Y + 2.03 U \\begin{aligned} &\\left\\{\\begin{array}{l} Y=0.299 R+0.587 G+0.114 B \\\\ U=-0.147 R-0.289 G+0.436 B \\\\ V=0.615 R-0.515 G-0.100 B \\end{array}\\right. \\\\ &\\left\\{\\begin{array}{l} R=Y+1.14 V \\\\ G=Y-0.39 U-0.58 V \\\\ B=Y+2.03 U \\end{array}\\right. \\end{aligned} ⎩⎨⎧Y=0.299R+0.587G+0.114BU=−0.147R−0.289G+0.436BV=0.615R−0.515G−0.100B⎩⎨⎧R=Y+1.14VG=Y−0.39U−0.58VB=Y+2.03U
HSV 是由色调(Hue)、饱和度(Saturation)、和亮度(Value)这三个英文单词的首字母组成的。色调是色彩的基本属性,可以表示为0° ~ 360°的圆心角;饱和度是指颜色的纯度,饱和度越高,颜色越纯越鲜艳,随着饱和度降低,色彩逐渐变灰、变暗,饱和度的取值范围是0 ~ 1 ;亮度是指颜色的明亮程度,其取值范围为0到计算机中运行的最大亮度值。
在图像处理中使用较多的是 HSV 颜色空间,它比 RGB 更接近人们对彩色的感知经验。非常直观地表达颜色的色调、鲜艳程度和明暗程度,方便进行颜色的对比。在 HSV 颜色空间下,比在 RGB 颜色空间下 更容易跟踪某种颜色的物体,常用于分割指定颜色的物体。HSV 颜色空间模型如下图所示。
Lab 颜色空间弥补了 RGB 和 CMYK 两种颜色空间的不足。它是一种设备无关的颜色模型,也是一种基于生理特征的颜色模型。Lab 颜色模型由三个要素组成,一个要素是亮度(L),a 和b是两个颜色通道。a包括的颜色是从深绿色(低亮度值)到灰色(中亮度值)再到亮粉红色(高亮度值);b是从亮蓝色(低亮度值)到灰色(中亮度值)再到黄色(高亮度值)。因此,这种颜色混合后将产生具有明亮效果的色彩。Lab 颜色空间模型如下图所示。
GRAY 颜色空间是一个关于灰度图像的颜色空间。灰度图像只有1个通道,灰度值根据图像位数由0到最大灰度值依此表示由黑到白。例如在 8UC1 格式中,由黑到白被量化成256个等级,通过0~255的整数来表示,其中255表示白色。灰度图像具有在相同尺寸和相同压缩格式下所占空间小、易于采集和便于传输等优点。常用的 RGB 颜色空间转化为 GRAY 颜色空间的公式如下。
G R A Y = 0.3 R + 0.59 G + 0.11 B GRAY=0.3R+0.59G+0.11B GRAY=0.3R+0.59G+0.11B
cv.cvtColor()函数用于将图像从一个颜色空间转换为另一个颜色空间,并将转化之后的结果通过值返回。
#函数原型:
dst = cv.cvtColor(src,
code
[, dst
[, dstCn]])
# src:待转化颜色空间的图像
# code:颜色空间转化的标志
# dst:颜色空间转化后的目标图像
# dstCn:目标图像中的通道数,默认值为0
需要注意该函数在进行转换前后的图像取值范围不能超出像素取值范围。
uint8: 0~255
uint16: 0~65535
float32: 0~1
在非线性变化的情况下需要将RGB图像归一化到适当的范围内以获得正确的结果。
cv.cvtColor()函数中常用颜色空间转换的标志如下表所示
标记 | 简记 | 作用 |
---|---|---|
cv.COLOR_BGR2BGRA | 0 | 为RGB添加alpha通道 |
cv.COLOR_BGR2RGB | 4 | 更改彩色图像通道颜色的顺序 |
cv.COLOR_BGR2GRAY | 10 | 把彩色图像转成灰度图像 |
cv.COLOR_GRAY2BGR | 8 | 把灰度图像转成彩色图像(伪彩色) |
cv.COLOR_BGR2YUV | 82 | 从RGB颜色空间转成YUV颜色空间 |
cv.COLOR_YUV2BGR | 84 | 从YUV颜色空间转成RGB颜色空间 |
cv.COLOR_BGR2HSV | 40 | 从RGB颜色空间转成HSV颜色空间 |
cv.COLOR_HSV2BGR | 54 | 从HSV颜色空间转成RGB颜色空间 |
cv.COLOR_BGR2Lab | 44 | 从RGB颜色空间转成Lab颜色空间 |
cv.COLOR_Lab2BGR | 56 | 从Lab颜色空间转成RGB颜色空间 |
示例代码: |
# -*- coding:utf-8 -*-
import cv2 as cv
import sys
import numpy as np
import matplotlib.pyplot as plt
if __name__ == \'__main__\':
# 读取图像并判断是否读取成功
img = cv.imread(\'../images/image.jpg\')
if img is None:
print(\'Failed to read image.jpg.\')
sys.exit()
else:
# 将图像进行颜色模型转换
image = img.astype(\'float32\')
image *= 1.0 / 255
HSV = cv.cvtColor(image, cv.COLOR_BGR2HSV)
YUV = cv.cvtColor(image, cv.COLOR_BGR2YUV)
Lab = cv.cvtColor(image, cv.COLOR_BGR2Lab)
GRAY = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
# 展示结果
cv.imshow(\'Origin Image\', image)
cv.imshow(\'HSV Image\', HSV)
cv.imshow(\'YUV Image\', YUV)
cv.imshow(\'Lab Image\', Lab)
# 由于计算出Lab结果会有负数值,不能通过cv.imshow()函数显示
# 因此我们可以使用cv.imwrite()函数保存下来进行查看
cv.imwrite(\'./results/Convert_color_Lab.jpg\', Lab)
cv.imshow(\'GRAY Image\', GRAY)
# 关闭窗口
cv.waitKey(0)
cv.destroyAllWindows()
运行结果如下图所示。
在图像颜色空间中,不同的分量存放在不同的通道中。如果我们只需要颜色空间中的某一个分量(例如,只需要处理 RGB 图像中的红色通道),则可以将红色通道从三通道的数据中分离出来再进行处理。这种方式可以减少数据所占用的内存,加快程序的运行速度。同时,当我们分别处理完多个通道后需要将所有通道合并在一起重新生成RGB图像。这就需要用到cv.split()函数和cv.merge()函数。
#函数原型:
mv = cv.split(m,
[, mv])
# m:待分离的多通道图像
# mv:分离后的单通道图像
该函数主要用于将多通道的图像分离成若干个单通道的图像,并将分离后的结果通过值返回。
#函数原型:
dst = cv.merge(mv,
[, dst])
# mv:需要合并的图像
# mv:合并后输出的图像
该函数主要用于将多幅图像合并成一幅多通道图像,并将合并后的结果通过值返回。其功能与cv.split()相对应,对于输入尺寸和数据类型一致的多幅图像,输出结果是一幅多通道的图像,其通道数目是所有输入图像通道数目的总和。
注意:所有输入的图像的通道数可以不相同,但是所有图像需要具有相同的尺寸和数据类型
本程序首先将RGB图像分离为 b、g、r 通道,然后分别进行通道数目相同和不同的图像矩阵合并。
# -*- coding:utf-8 -*-
import cv2 as cv
import sys
import numpy as np
if __name__ == \'__main__\':
# 读取图像并判断是否读取成功
img = cv.imread(\'../images/cat.jpg\')
if img is None:
print(\'Failed to read lena.jpg.\')
sys.exit()
# 通道分离
b, g, r = cv.split(img)
# 创建一个和图像尺寸相同的全0矩阵
zeros = np.zeros(img.shape[:2], dtype=\'uint8\')
# 将通道数目相同的图像矩阵合并
bg = cv.merge([b, g, zeros])
gr = cv.merge([zeros, g, r])
br = cv.merge([b, zeros, r])
# 将通道数目不相同的图像矩阵合并
bgr_6 = cv.merge([bg, r, zeros, zeros])
# 展示结果
cv.imshow(\'Blue\', b)
cv.imshow(\'Green\', g)
cv.imshow(\'Red\', r)
cv.imshow(\'Blue_Green\', bg)
cv.imshow(\'Green_Red\', gr)
cv.imshow(\'Blue_Red\', br)
# 关闭窗口
cv.waitKey(0)
cv.destroyAllWindows()