Practical Python and OpenCV,3rd Edition 08
拆分和合并通道(splitting and merging channels)
彩色图像由多个通道组成:红色,绿色和蓝色成分。我们已经看到我们可以通过索引到NumPy数组来访问这些成分。但是,如果我们想将图像分割成各自的成分呢?
我们将使用cv2.split函数。如下图所示,我们有下面一个图像,

这张图片非常的蓝,编写代码,实现通道的提取
新建一个splitting_and_merging.py
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()
通常,我们会想到RGB颜色空间中的图像——首先是红色,第二个是绿色,第三个是蓝色。但是,OpenCV以反向通道顺序将RGB图像存储为NumPy阵列。 它不是以RGB顺序存储图像,而是以BGR顺序存储图像; 因此我们以相反的顺序解包元组。然后将每个通道的图像显示出来。最后我们再将各个通道的图像合并成原图。
显示图像:

红色通道非常暗。这是有道理的,因为海洋场景中的红色很少。存在的红色要么非常暗,要么没有代表,要么非常light,并且可能是波浪崩溃时白色泡沫的一部分。
绿色通道在图像中更具代表性,因为海水确实包含绿色色调。
最后,蓝色通道非常light,在某些位置接近纯白色。这是因为我们的图像中大量呈现蓝色阴影。
# 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)
显示效果:

上面代码可以看到另一种可视化图像通道的方法。为了显示通道的实际“颜色”,我们首先需要使用cv2.split拆分图像。然后,我们需要重新构建图像,但这次设置所有像素,但当前通道为零。
我们首先构造了一个零的NumPy数组,其宽度和高度与原始图像相同。然后,为了构造图像的红色通道表示,我们调用cv2.merge,但为绿色和蓝色通道指定我们的零数组。后面采取类似的方法。
用到的函数
cv2.split
cv2.merge
cv2.destroyAllWindows
更多的参考:
PPaO Chapter 6 – Image Processing
;