OpenCV笔记之六(4)——图像处理之颜色通道拆分、合并及颜色空间

5.通道拆分与合并

我们都知道,一张彩色图像一般由R、G、B三个通道组成,通过对NumPy数组的索引我们可以轻易地获取到这些通道的值,那该如何对颜色通道进行拆分来分别提取这三个分量呢?opencv中提供了split函数专门为此服务。

此外,对于三个单独的R、G、B颜色通道,我们可以借助merge函数来对它们进行合并来合成一张RGB彩色图像。

Practical Python and OpenCV, 3rd Edition 的随书代码中给出了一份简单的示例。

a.源代码呈现

splitting_and_merging.py

# USAGE
# python splitting_and_merging.py --image ../images/wave.png

# Import the necessary packages
import numpy as np
import argparse
import cv2

# Construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required = True,
	help = "Path to the image")
args = vars(ap.parse_args())

# Load the image and grab each channel: Red, Green, and Blue
# NOTE: OpenCV stores an image as NumPy array with its
# channels in reverse order! When we call cv2.split, we are
# actually getting the channels as Blue, Green, Red!
image = cv2.imread(args["image"])
(B, G, R) = cv2.split(image)

# Show each channel individually
cv2.imshow("Red", R)
cv2.imshow("Green", G)
cv2.imshow("Blue", B)
cv2.waitKey(0)

# Merge the image back together again
merged = cv2.merge([B, G, R])
cv2.imshow("Merged", merged)
cv2.waitKey(0)
cv2.destroyAllWindows()

# Now, let's visualize each channel in color
zeros = np.zeros(image.shape[:2], dtype = "uint8")
cv2.imshow("Red", cv2.merge([zeros, zeros, R]))
cv2.imshow("Green", cv2.merge([zeros, G, zeros]))
cv2.imshow("Blue", cv2.merge([B, zeros, zeros]))
cv2.waitKey(0)
b.代码分析

通道拆分

Line 20-26

借助cv2.split函数将图像的颜色通道分别拆分为B、G、R三个通道并分别显示。【由于是单通道,以灰度图形式呈现】

运行结果如下表所示。

OpenCV笔记之六(4)——图像处理之颜色通道拆分、合并及颜色空间_第1张图片 OpenCV笔记之六(4)——图像处理之颜色通道拆分、合并及颜色空间_第2张图片 OpenCV笔记之六(4)——图像处理之颜色通道拆分、合并及颜色空间_第3张图片
Red Green Blue

通过单通道的图片显示,不难发现,相较于绿色和蓝色通道,红色通道显示的图片整体偏暗。这也不难解释,海浪几乎不存在红色,而相对来说更多呈现的是青蓝色,因此蓝色通道的图片是最亮的。

通道合并

Line 29-31

借助cv2.merge函数重新将该3个通道进行合并,检验是否呈现为原先的彩色RGB图片。

OpenCV笔记之六(4)——图像处理之颜色通道拆分、合并及颜色空间_第4张图片

Line 32

清除所有已显示的图像,以便下一步工作。

接下来我们借助merge函数来呈现单色图片,这将让我们更深刻地理解颜色通道的概念。

Line 35-39

为了呈现单色图片,则只需将其他的颜色通道都置0。例如:若想要显示为红色图片,则我们只需关注R通道像素的亮度值,而忽略其他颜色通道的像素值。

首先,建立一个图像大小的全零矩阵,并分别将该矩阵分给G通道和B通道,并由merge函数与R通道合并。则绿色和蓝色完全不显示,只呈现红色图像。若要显示为绿色和蓝色图像则同理。

运行代码后的结果如下表所示。

OpenCV笔记之六(4)——图像处理之颜色通道拆分、合并及颜色空间_第5张图片 OpenCV笔记之六(4)——图像处理之颜色通道拆分、合并及颜色空间_第6张图片 OpenCV笔记之六(4)——图像处理之颜色通道拆分、合并及颜色空间_第7张图片
Red Green Blue

6.颜色空间

(1)彩色图像处理

彩色光源的质量通常 由3 个基本量描述:辐射度 【光源流出总能量,通常以瓦特(W)为单位】、照度【观察者从光源感知到的能量度量,以流明(lm)为单位】 和亮度。

而区分颜色通常有3个特征:亮度、色调和饱和度。

亮度是一个主观描述的概念,实际无法度量。

色调是与混合光波中主波长相关的属性。平日里我们常说的红色、黄色就是指色调。

饱和度指的其实就是色彩的纯度。色彩中白光的比例越高,色彩饱和度越低,色彩显得越黯淡;反之则较鲜艳。纯光谱的颜色就是完全饱和的。

通常我们将色调和饱和度一起称为色度。因此一种颜色可以简单地用亮度和色度来描述。

(2)颜色空间

为了方便准确地指定某种具体的颜色,我们引入了颜色空间。常见的颜色空间有RGB、CMY、HSV、HSI、L*a*b*等。

通常为人所知的是由红、绿、蓝三原色组成的RGB颜色空间。

OpenCV笔记之六(4)——图像处理之颜色通道拆分、合并及颜色空间_第8张图片

如图所示,RGB色彩空间是基于笛卡尔坐标系的,RGB主值位于三个角。每个像素的位数称为像素深度,RGB空间中红、绿、蓝图像分别是一个8位图像(表示每种原色可以分为2^8 = 256个等级),因此每个RGB彩色像素的深度为24位,即总共可以表示2^24 = 16777216种颜色。

RGB颜色空间非常易于理解,但是不适合人类解释。例如:它不能给出每个主色的百分比来指示一个物体的颜色。而先前提到,人类观察一个彩色物体,通常通过色度、饱和度和亮度来描述。

而HSI【色调(H)、饱和度(S)、强度(I)】和HSV【色调(H)、饱和度(S)、值(V)】颜色空间则能够很直观地表现出某一种颜色或颜色区间,但是通常对人类视觉不那么友好。

L*a*b*颜色空间则试图模仿人类看到和解释颜色的方法。这意味着L*a*b*颜色空间中任意两种颜色之间的欧几里得距离具有实际的感知意义,这使得L*a*b*颜色空间比RGB或HSV更不直观但更容易理解。但由于感知意义属性的增加,我们经常在计算机视觉中使用它。例如,我们可以应用L*a*b*空间和k均值聚类算法来寻找图像中的主色调。我们还可以借此对颜色进行量化,从而减少图像中的色彩总数。

接下来看一下书上的示例,来了解如何利用opencv对颜色空间进行转换。

(3)源码实例
a.源代码呈现

colorspaces.py

# USAGE
# python colorspaces.py --image ../images/beach.png

# Import the necessary packages
import numpy as np
import argparse
import cv2

# Construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required = True,
	help = "Path to the image")
args = vars(ap.parse_args())

# Load the image and show it
image = cv2.imread(args["image"])
cv2.imshow("Original", image)

# Convert the image to grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow("Gray", gray)

# Convert the image to the HSV (Hue, Saturation, Value)
# color spaces
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
cv2.imshow("HSV", hsv)

# Convert the image to the L*a*b* color spaces
lab = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)
cv2.imshow("L*a*b*", lab)
cv2.waitKey(0)
b.代码分析

Line 20-21

将RGB彩色图像转换为灰度图。一幅灰度图的像素深度是8位。0表示最暗的黑色,255表示最亮的白色。

Line 25-26

将RGB彩色图像转换为HSV图像。

Line 29-30

将RGB彩色图像转换为L*a*b*图像。

c.运行结果

OpenCV笔记之六(4)——图像处理之颜色通道拆分、合并及颜色空间_第9张图片

你可能感兴趣的:(#,OpenCV,学习笔记,opencv)