RGB颜色空间的拆分 - 使用 OpenCV split 以及数组

RGB颜色空间的拆分 - 使用 OpenCV split 以及数组

生成 RGB 图形

RGB 彩色图像矩阵原则上是依照像素的方式储存,以下示例会以红绿蓝(Red, Green, Blue)三原色分别画出三个圆形。要特别注意的是,pyplot 显示图片的格式为 RGB(A) 所以要进行颜色空间转换 cv2.cvtColor(image,cv2.COLOR_RGB2BGRA)

参考代码

from matplotlib import pyplot as plt
import cv2
import numpy as np
# 生成一个 640*480 的 BGR 三个通道的彩色图片,底色全为0
canvas = np.zeros((480, 640, 3), dtype='uint8')
image_path='../data/diy.jpg'
# 圆半径为 90 pixel
radius = 90
# 配色为 BGR
blue = (255, 0, 0)
green = (0, 255, 0)
red = (0, 0, 255)
# 圆边厚度为 10 pixel
thickness = 10
# 画出 红绿蓝三个图片
image = cv2.circle(canvas, (320, 200), radius, red, thickness)
image = cv2.circle(canvas, (220, 300), radius, green, thickness)
image = cv2.circle(canvas, (420, 300), radius, blue, thickness)
# 因为 pyplot 显示图片的格式为 RGB(A) 所以要进行颜色空间转换
toGBR = cv2.cvtColor(image,cv2.COLOR_RGB2BGRA)
# the image in the BGR 8-bit format
cv2.imwrite(image_path,canvas)
plt.figure(figsize=(8,12))
plt.subplot(211), plt.title('BGR format')
plt.imshow(image) # image 为 BGR 8-bit 格式,而 plt 以 RGB 方式显示,所以颜色会不对
plt.subplot(212), plt.title('RGB(A) format')
plt.imshow(toGBR) # toGBR 为 RGB(A) 格式,这才是正确的配色
plt.show()

在这里插入图片描述
图 1. 显示 BGR 与 RGB(A) 格式的差异,右手边的图形配色才是正确的

分割 RGB 通道,以灰度显示

将彩色图片依照BGR通道来分割,以下示例将上面生成的 diy.jpg 图片的每一个通道单独显示一张图片,从显示的顺序可以发现,通道依序是红(0)、绿(1)、蓝(2)。

参考代码

from matplotlib import pyplot as plt
import cv2
#IMREAD_COLOR 会将图片以 BGR 8-bit 格式读入
img1 = cv2.imread('../data/diy.jpg',cv2.IMREAD_COLOR)
# 将图片依 BGR 分割成三个通道
channels = cv2.split(img1)
# color in BGR
titles=['Blue', 'Green', 'Red']
figure, plots = plt.subplots(ncols=3, nrows=1,figsize=(12,6))
for i, subplot in zip(range(3), plots):
    subplot.imshow(channels[i],'gray')
    subplot.set_axis_off()
    subplot.set_title(titles[i])
plt.show()

在这里插入图片描述
图 2. 拆分 BGR 的颜色空间

分割 RGB 通道,以彩色显示

处理步骤为:

  1. 加载彩色图像,以 BGR 8-bit 格式读入(opencv)
  2. 分割独立的颜色通道(opencv)
  3. 创建空白图片(np)
  4. 将特定通道的颜色给予空白图片
  5. 转换成 plt 的颜色空间(opencv)
  6. 使用 plt 显示结果(matplotlib)

参考代码

from matplotlib import pyplot as plt
import numpy as np
import cv2
#加载彩色图像
img = cv2.imread('../data/diy.jpg',cv2.IMREAD_COLOR)
# 分割独立的颜色通道
channels = cv2.split(img)
# color in BGR
titles=['Blue', 'Green', 'Red']
figure, plots = plt.subplots(ncols=3, nrows=1,figsize=(12,6))
for i, subplot in zip(range(3), plots):
    # 创建空白图片
    temp = np.zeros(img.shape, dtype='uint8')
    # 将特定通道的颜色给予空白图片
    temp[:,:,i] = channels[i] # img[:,:,i]
    # 转换成 plt 的颜色空间
    toGBR = cv2.cvtColor(temp,cv2.COLOR_RGB2BGRA)
    subplot.imshow(toGBR)
    subplot.set_title(titles[i])
    subplot.set_axis_off()
plt.show()

在这里插入图片描述
图 3. 以彩色显示各自的 RGB 通道

如果是针对白底的图片,这样的显示方式通常都达不到想要的效果,如底下代码所示,因为白底会导致整个单一通道的显示呈现单一通道的底色,这样反而不容易凸显出目标物。此外,人类眼中的红蓝绿,常常是混合的结果,所以,如果要单独找出红蓝绿颜色,通常是使用 HSV 的颜色空间。

from matplotlib import pyplot as plt
import numpy as np
import cv2
#加载彩色图像
img = cv2.imread('../data/b.png',cv2.IMREAD_COLOR)
channels = cv2.split(img)
# color in BGR
titles=['Blue', 'Green', 'Red']
figure, plots = plt.subplots(ncols=4, nrows=1,figsize=(12,4))
for i, subplot in zip(range(4), plots):
    if i < 3:
        temp = np.zeros(img.shape, dtype='uint8')
        temp[:,:,i] = channels[i] # img[:,:,i]
        toGBR = cv2.cvtColor(temp,cv2.COLOR_RGB2BGRA)
        subplot.imshow(toGBR)
        subplot.set_title(titles[i])
        subplot.set_axis_off()
    else:
        toGBR = cv2.cvtColor(img,cv2.COLOR_RGB2BGRA)
        subplot.imshow(toGBR)
        subplot.set_title('Origin')
        subplot.set_axis_off()
plt.show()

在这里插入图片描述
图 4. 以彩色显示各自的 RGB 通道

参考资料

  • OpenCV API, https://docs.opencv.org/
  • Getting Started with Images, https://docs.opencv.org/4.x/db/deb/tutorial_display_image.html
  • matplotlib.pyplot.subplot, https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.subplot.html#matplotlib.pyplot.subplot
  • matplotlib.pyplot.imshow, https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.imshow.html

猜你喜欢

转载自blog.csdn.net/m0_50614038/article/details/129899226