OpenCV-Python快速入门系列11通道的分离、合并、交换

使用Python切片分离通道

def channel_separation1():
    image = cv.imread('images/test.png')
    if image is None:
        print("Error: Image not found or failed to load.")
        return

    cv.imshow("image", image)
    cv.imshow("image CHN0", image[:,:,0])
    cv.imshow("image CHN1", image[:,:,1])
    cv.imshow("image CHN2", image[:,:,2])
    cv.waitKey(0)
    cv.destroyAllWindows()

按照预想的应该能将R、G、B三个通道分离出来才对,但是效果却是黑白图像:

图片[1]-OpenCV-Python快速入门系列11通道的分离、合并、交换-天煜博客

r

如果直接显示单通道的图像,默认会以灰度的形式呈现,看不出来三个通道有什么区别。

使用伪彩色增强单通道的可视化效果:

def channel_separation2():
    # 读取图像
    image = cv.imread('images/test.png')
    if image is None:
        print("Error: Image not found or failed to load.")
        return

    # 显示原始图像
    cv.imshow("Original Image", image)

    # 提取 BGR 通道
    blue_channel = image[:, :, 0]  # 蓝色通道
    green_channel = image[:, :, 1]  # 绿色通道
    red_channel = image[:, :, 2]  # 红色通道

    # 将单通道转换为伪彩色图像以增强可视化
    blue_color = cv.merge([blue_channel, blue_channel * 0, blue_channel * 0])
    green_color = cv.merge([green_channel * 0, green_channel, green_channel * 0])
    red_color = cv.merge([red_channel * 0, red_channel * 0, red_channel])

    # 显示各个通道
    cv.imshow("Blue Channel", blue_color)
    cv.imshow("Green Channel", green_color)
    cv.imshow("Red Channel", red_color)

    # 等待键盘事件
    cv.waitKey(0)
    cv.destroyAllWindows()
图片[2]-OpenCV-Python快速入门系列11通道的分离、合并、交换-天煜博客

补充知识点 关于 image[:, :, 0] 的解释

在 OpenCV 的图像处理中,image[:, :, 0] 表示对彩色图像(通常是三维数组)的 切片操作,提取图像的第一个通道。

结构解析

  • image:一个三维 NumPy 数组,表示彩色图像,形状为 (height, width, channels)
    • height:图像的高度(像素数)。
    • width:图像的宽度(像素数)。
    • channels:通道数,例如 BGR 格式图像有 3 个通道。
  • 切片含义:
    • : 表示选取该维度的所有元素。
    • image[:, :, 0] 提取第一个通道(蓝色通道,BGR 格式中的 B)。
import cv2 as cv
import numpy as np

# 创建一个简单的彩色图像
image = np.zeros((3, 3, 3), dtype=np.uint8)
image[:, :, 0] = 255  # 蓝色通道全填充
image[:, :, 1] = 128  # 绿色通道全填充
image[:, :, 2] = 64   # 红色通道全填充

# 提取通道
blue = image[:, :, 0]   # 第一个通道(蓝色)
green = image[:, :, 1]  # 第二个通道(绿色)
red = image[:, :, -1]   # 最后一个通道(红色,等价于 2)

print("Blue channel:\n", blue)
print("Green channel:\n", green)
print("Red channel:\n", red)

问题:0 是否能改为 -1?

在 NumPy 中,通道索引支持 负数 表示 从末尾开始计数

  • 0 表示第一个通道(B)。
  • 1 表示第二个通道(G)。
  • 2 表示第三个通道(R)。
  • -1 表示最后一个通道,对于 BGR 格式图像,-1 等价于 2(红色通道 R)。
  • -2 表示倒数第二个通道(对于 BGR 图像,是绿色通道 G)。
  • -3 表示倒数第三个通道(对于 BGR 图像,是蓝色通道 B)。

使用OpenCV的Split函数分离通道

def channel_separation3():
    # 读取图像
    image = cv.imread('images/test.png')
    if image is None:
        print("Error: Image not found or failed to load.")
        return

    # 显示原始图像
    cv.imshow("Original Image", image)
    print(image.shape)
    mv = cv.split(image)
    print(mv[0].shape)
    cv.imshow("Original Image CHN0", mv[0])
    cv.imshow("Original Image CHN1", mv[1])
    cv.imshow("Original Image CHN2", mv[2])
    cv.waitKey(0)
    cv.destroyAllWindows()
图片[3]-OpenCV-Python快速入门系列11通道的分离、合并、交换-天煜博客

可以看出当前显示单通道也是灰色的,使用cv.merge可以转换成彩色显示。

交换通道

使用 OpenCV 的 cv.mixChannels 函数,将图像的通道顺序重新排列。

    dst = np.zeros(image.shape, dtype=np.uint8)
    cv.mixChannels([image],[dst],fromTo=[2,0,1,1,0,2])
    cv.imshow("Original Image exchange", dst)
  • 功能
    • image 的颜色通道重新排列,并存储到 dst 中。
  • 参数说明
    • 输入图像列表[image],表示来源图像。
    • 输出图像列表[dst],表示目标图像。
    • fromTo 列表
      • 每两个元素为一对,表示从来源图像的第一个通道复制到目标图像的第二个通道。
      • [2, 0, 1, 1, 0, 2] 表示:
        • 来源图像的第 2 个通道(红色,R)复制到目标图像的第 0 个通道(蓝色,B)。
        • 来源图像的第 1 个通道(绿色,G)保持不变,复制到目标图像的第 1 个通道(G)。
        • 来源图像的第 0 个通道(蓝色,B)复制到目标图像的第 2 个通道(红色,R)。
图片[4]-OpenCV-Python快速入门系列11通道的分离、合并、交换-天煜博客
© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容