前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【计算机视觉处理4】色彩空间转换

【计算机视觉处理4】色彩空间转换

作者头像
ZackSock
发布2021-01-08 16:11:00
1.3K0
发布2021-01-08 16:11:00
举报
文章被收录于专栏:ZackSock

【计算机视觉处理4】色彩空间转换

1、图层操作

在第2篇中提到过,如果是二值图片(黑白图)或者灰度图片,一个像素需要一个8位二进制来表示。而对于彩色图像,一个像素则需要用3个8位二进制来表示。我们认为灰度图只有一个图层,而普通的彩色图像则有三个图层。

对于灰度图来说,像素强调的是白色的程度,当像素值为0时图像表现为黑色,当像素值为255时图像表现为白色。而处于中间的灰色,我们可以理解为“不够白”的颜色。

对于彩色图像,我们通常会用RGB三个颜色表示。它们分别是红、绿、蓝,我们可以通过三种颜色的调配展现出各种颜色。

那在OpenCV中要怎么操作图层呢?我们先打开一张彩色图片,查看它的通道数:

代码语言:javascript
复制
import cv2
# 读取图片
img = cv2.imread("xyql.jpg")
# 查看图片的形状
print(img.shape)

输出结果如下:

代码语言:javascript
复制
(1079, 1080, 3)

其中3就是图片的图层数。我们可以通过索引将三个通道分离出来:

代码语言:javascript
复制
import cv2
# 读取图片
img = cv2.imread('test.jpg')
# 切片提取B通道
b = img[:, :, 0]
# 切片提取G通道
g = img[:, :, 1]
# 切片提取R通道
r = img[:, :, 2]

因为在OpenCV中图片模式默认是BGR,因此我们分离的第0个通道是b,第一个和第二个分别是g和r。我们可以看看三个通道的图像:

上面分别是原始图片和BGR三个通道图片。因为拆分后的图片只有一个通道,所以显示效果都是黑白的。

可以看到原图的娜娜面色红润,所以R通道皮肤部分要比较亮(颜色偏白,像素值较高)。

除了自己索引,我们还可以调用OpenCV的内置方法分离通道,代码如下:

代码语言:javascript
复制
import cv2
# 读取图片
img = cv2.imread('test.jpg')
# 调用OpenCV内置方法进行分离通道
b, g, r = cv2.split(img)

在代码中我们调用了cv2.split(),如果我们的图片有三个通道我们需要用三个参数接收,如果有四个通道则需要用四个参数接收。

2、色彩空间

在此之前我们已经接触过几种色彩空间了,比如RGB和GRAY两种。除了RGB和GRAY外,还有XYZ、YCrCb、HSV等。不同的色彩空间删除处理不同的问题,有时候我们会将图片转换成指定的色彩空间以便进行相应的处理。

RGB(我们认为RGB和BGR是同种色彩空间)是一种方便计算机处理的色彩空间,它用三原色组成。但是对人来说RGB这种色彩空间是很难理解的,我们不会说黄色是红色+绿色,也不会说白色是红色+绿色+蓝色(对平常人来说)。

而HSV色彩空间是一种符合人类视觉感知的模型,这种色彩空间会用色调(Hue,也称为色相)、饱和度(Saturation)、亮度(Value)来表示像素。它们的解释分别如下:

摘自《OpenCV轻松入门:面向Python》,作者:李立宗。 ● 色调:色调与混合光谱中的主要光波长相关,例如“赤橙黄绿青蓝紫”分别表示不同的色调。如果从波长的角度考虑,不同波长的光表现为不同的颜色,实际上它们体现的是色调的差异。 ● 饱和度:指相对纯净度,或一种颜色混合白光的数量。纯谱色是全饱和的,像深红色(红加白)和淡紫色(紫加白)这样的彩色是欠饱和的,饱和度与所加白光的数量成反比。 ● 亮度:反映的是人眼感受到的光的明暗程度,该指标与物体的反射度有关。对于色彩来讲,如果在其中掺入的白色越多,则其亮度越高;如果在其中掺入的黑色越多,则其亮度越低。

如果遇到需要调节饱和度的场景时,我们可以选择使用HSV色彩空间。

3、色彩空间的转换

色彩空间的转换有固定的公式,这些公式都非常简单,我们来简单看其中一个。RGB到YCrCb颜色空间的转换:

其中δ的值计算如下:

当然我们不需要自己计算,在OpenCV中提供了色彩空间转换的函数cv2.cvtColor(),函数格式如下:

代码语言:javascript
复制
dst = cv2.cvtColor(src, code)

该函数接收两个参数,分别是要转换的图片和转换的模式。最后函数会给我们返回转换后的结果,这里重点关注一下code参数。

code参数我们只需要添加OpenCV中的一些常量即可,这些常量很好理解:

因为图片比较长,这里只列出一部分。命名规则大都为COLOR_XX2YY,也就是函数就是将色彩空间为XX的图片转换为YY色彩空间。其中我们最常用的就是下面几个:

代码语言:javascript
复制
# 将BGR转换成GRAY(灰度图)
cv2.COLOR_BGR2GRAY
# 将BGR转换为RGB
cv2.COLOR_BGR2RGB
# 将BGR转换为HSV
cv2.COLOR_BGR2HSV
# 将BGR转换为BGRA(png图片)
cv2.COLOR_BGR2BGRA

下面我们来实际使用一下,我们先看一段简单的代码:

代码语言:javascript
复制
import cv2
import numpy as np
from PIL import Image
# 读取图片
img = Image.open('nn.jpg')
# 将图片对象转换成ndarray对象
img = np.array(img)
# 显示图片
cv2.imshow('img', img)
cv2.waitKey()
cv2.destroyAllWindows()

下面是原图和上面代码显示的图片:

在代码中我们使用PIL模块读取图片,因为PIL默认是以RGB模式读取,因此当我们直接将它转换为ndarray数组时,OpenCV把R和B通道颠倒了,因此图片颜色异常显示。

PIL模块的安装如下:

代码语言:javascript
复制
pip install pillow

其实我们可以简单分析一下,这次的娜娜依旧面色红润,因为右边的效果图颠倒了R和B通道,因此红色部分显示效果要接近蓝色,而蓝色的衣服效果却接近红色。

想要正常显示我们需要对颜色空间进行一些简单的转换:

代码语言:javascript
复制
import cv2
import numpy as np
from PIL import Image
img = Image.open('nn.jpg')
img = np.array(img)
# 将RGB图片转换成BGR
bgr = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
cv2.imshow('img', bgr)
cv2.waitKey()
cv2.destroyAllWindows()

你们可以自己尝试运行一下,显示效果会和原图一样。其它颜色空间的转换也是一样的,这里就不再一一演示了。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-12-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 新建文件夹X 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 【计算机视觉处理4】色彩空间转换
  • 1、图层操作
  • 2、色彩空间
  • 3、色彩空间的转换
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档