OpenCvSharp从入门到实践-(05)通道

举报
天天代码码天天 发表于 2024/12/05 14:37:18 2024/12/05
【摘要】 OpenCvSharp从入门到实践-(05)通道

一副BGR图像是由B通道、G通道、R通道这3个通道构成的。本篇博客介绍如何对通道进行拆分和合并,从而达到处理图像的目的。

1、拆分通道

OpenCvSharp提供Cv2.Split函数,函数如下:

public static void Split(Mat src, out Mat[] mv)

说明

摘要:
    Copies each plane of a multi-channel array to a dedicated array

参数:
  src:
    The source multi-channel array

  mv:
    The destination array or vector of arrays; The number of arrays must match mtx.channels()
    . The arrays themselves will be reallocated if needed

1.1、实例1-拆分一副BGR图像的通道

代码如下:

Mat mat = Cv2.ImRead("test.jpg");
Cv2.ImShow("SRC", mat);

Mat[] mv;
Cv2.Split(mat, out mv);

Cv2.ImShow("B", mv[0]);
Cv2.ImShow("G", mv[1]);
Cv2.ImShow("R", mv[2]);

Cv2.WaitKey();
Cv2.DestroyAllWindows();

原图如下:

运行代码后得到的B、G、R通道图如下:

1.2、实例2-拆分一副HSV图像的通道

代码如下:

Mat mat = Cv2.ImRead("test.jpg");

Cv2.CvtColor(mat, mat, ColorConversionCodes.BGR2HSV);

Mat[] mv;
Cv2.Split(mat, out mv);

Cv2.ImShow("H", mv[0]);
Cv2.ImShow("S", mv[1]);
Cv2.ImShow("V", mv[2]);

Cv2.WaitKey();
Cv2.DestroyAllWindows();

运行代码后得到的H、S、V通道图如下:

2、合并通道

OpenCvSharp提供Cv2.Merge函数合并通道,函数如下:

public static void Merge(Mat[] mv, Mat dst)

说明

摘要:
    makes multi-channel array out of several single-channel arrays

参数:
  mv:

  dst:

2.1 实例3-合并通道的顺序不同,图像的显示效果也不通

编写程序,先拆分通道,再分别按照BGR的顺序和RGB的顺序合并通道。

代码如下:

Mat mat = Cv2.ImRead("test.jpg");

Mat[] mv;
Cv2.Split(mat, out mv);

Mat dst = new Mat();
Cv2.Merge(new Mat[] { mv[0], mv[1], mv[2] }, dst);
Cv2.ImShow("BGR", dst);

Cv2.Merge(new Mat[] { mv[2], mv[1], mv[0] }, dst);
Cv2.ImShow("RGB", dst);

Cv2.WaitKey();
Cv2.DestroyAllWindows();

运行代码后,效果如下:

实例4-合格H通道图像、S通道图像、V通道图像

代码如下:

Mat mat = Cv2.ImRead("test.jpg");

Cv2.ImShow("SRC", mat);

Cv2.CvtColor(mat, mat, ColorConversionCodes.BGR2HSV);

Mat[] mv;
Cv2.Split(mat, out mv);

Mat dst = new Mat();
Cv2.Merge(new Mat[] { mv[0], mv[1], mv[2] }, dst);
Cv2.ImShow("HSV", dst);

Cv2.WaitKey();
Cv2.DestroyAllWindows();

运行代码后,效果如下:

3、综合运用拆分通道和合并通道

在HSV色彩空间,如果保持其中两个通道的值不变,调整第3个通道的值,可以得到相应的艺术效果。

2.2、实例5-只把H通道的值调整为180

编写一个程序,首先将测试图片从BGR色彩空间转换到HSV色彩空间;然后拆分得到HSV图像中的通道;接着让S通道和V通道的值保持不变,把H通道的值调整为180;再接着合并拆分后的通道图像,把这个图像从HSV色彩空间转换到BGR色彩空间;最后显示得到的BRG图像。代码如下:

Mat mat = Cv2.ImRead("test.jpg");

Cv2.ImShow("SRC", mat);

Cv2.CvtColor(mat, mat, ColorConversionCodes.BGR2HSV);

Mat[] mv;
Cv2.Split(mat, out mv);

// 将H通道的值全部调整为180
mv[0] = new Mat(mv[0].Size(), mv[0].Type(), new Scalar(180));

Mat dst = new Mat();
Cv2.Merge(new Mat[] { mv[0], mv[1], mv[2] }, dst);

Cv2.CvtColor(dst, dst, ColorConversionCodes.HSV2BGR);

Cv2.ImShow("NEW", dst);

Cv2.WaitKey();
Cv2.DestroyAllWindows();

运行代码后,效果如下:

如果让H通道和S通道的值保持不变,只把V通道的值调整为255,代码如下:

Mat mat = Cv2.ImRead("test.jpg");
Cv2.ImShow("SRC", mat);

Cv2.CvtColor(mat, mat, ColorConversionCodes.BGR2HSV);

Mat[] mv;
Cv2.Split(mat, out mv);

// 将V通道的值全部调整为255
mv[2] = new Mat(mv[2].Size(), mv[2].Type(), new Scalar(255));

Mat dst = new Mat();
Cv2.Merge(new Mat[] { mv[0], mv[1], mv[2] }, dst);

Cv2.CvtColor(dst, dst, ColorConversionCodes.HSV2BGR);

Cv2.ImShow("NEW", dst);

Cv2.WaitKey();
Cv2.DestroyAllWindows();

效果如下:

如果让H通道和V通道的值保持不变,只把S通道的值调整为255,代码如下:

Mat mat = Cv2.ImRead("test.jpg");
Cv2.ImShow("SRC", mat);

Cv2.CvtColor(mat, mat, ColorConversionCodes.BGR2HSV);

Mat[] mv;
Cv2.Split(mat, out mv);

// 将S通道的值全部调整为255
mv[1] = new Mat(mv[1].Size(), mv[1].Type(), new Scalar(255));

Mat dst = new Mat();
Cv2.Merge(new Mat[] { mv[0], mv[1], mv[2] }, dst);

Cv2.CvtColor(dst, dst, ColorConversionCodes.HSV2BGR);

Cv2.ImShow("NEW", dst);

Cv2.WaitKey();
Cv2.DestroyAllWindows();

效果如下:

4、alpha通道

BGR色彩空间包含3个通道,即B通道、G通道、R通道,OpenCV在这个3个通道的基础上,又增加了一个A通道,即alpha通道,用于设置图像的透明度。这样,一个由B通道、G通道、R通道和A通道这4个通道构成的色彩空间就诞生了,即BGRA通道。在BGRA色彩空间中,alpha通道在区间[0,255]内取值;其中0表示透明,255表示不透明。

4.1、实例5-调整A通道的值

编写一个程序,首先将测试图片从BGR色彩空间转换到BGRA色彩空间;然后拆分得到BGRA图像中的通道;接着把BGRA图像的透明度调整为172;再接着合并拆分后的通道图像,再接着BGRA图像的透明度调整为0后,合并拆分后的通道图像;最后分别显示RGBA图像、透明度为172的RGBA图像和透明度为0的RGBA图像,代码如下:

Mat mat = Cv2.ImRead("test.jpg");

Cv2.CvtColor(mat, mat, ColorConversionCodes.BGR2BGRA);
Cv2.ImShow("BGRA", mat);

Mat[] mv;
Cv2.Split(mat, out mv);

Mat dst_bgra_172 = new Mat();
// 将透明度调整为172(半透明)
mv[3] = new Mat(mv[3].Size(), mv[3].Type(), new Scalar(172));
Cv2.Merge(new Mat[] { mv[0], mv[1], mv[2], mv[3] }, dst_bgra_172);

Mat dst_bgra_0 = new Mat();
// 将透明度调整为0(透明)
mv[3] = new Mat(mv[3].Size(), mv[3].Type(), new Scalar(0));
Cv2.Merge(new Mat[] { mv[0], mv[1], mv[2], mv[3] }, dst_bgra_0);

Cv2.ImShow("BGRA A=172", dst_bgra_172);
Cv2.ImShow("BGRA A=0", dst_bgra_0);

Cv2.WaitKey();
Cv2.DestroyAllWindows();

效果如下:

虽然在代码中调整了BGRA图像中A通道的值,但是显示图像的效果是一样的。为了显示这3幅图的不同效果,需要用方法将这3幅图像保存到磁盘上,代码如下:

Mat mat = Cv2.ImRead("test.jpg");

Cv2.CvtColor(mat, mat, ColorConversionCodes.BGR2BGRA);

Mat[] mv;
Cv2.Split(mat, out mv);

Mat dst_bgra_172 = new Mat();
// 将透明度调整为172(半透明)
mv[3] = new Mat(mv[3].Size(), mv[3].Type(), new Scalar(172));
Cv2.Merge(new Mat[] { mv[0], mv[1], mv[2], mv[3] }, dst_bgra_172);

Mat dst_bgra_0 = new Mat();
// 将透明度调整为0(透明)
mv[3] = new Mat(mv[3].Size(), mv[3].Type(), new Scalar(0));
Cv2.Merge(new Mat[] { mv[0], mv[1], mv[2], mv[3] }, dst_bgra_0);

Cv2.ImWrite("brga.png", mat);
Cv2.ImWrite("brga_0.png", dst_bgra_0);
Cv2.ImWrite("brga_172.png", dst_bgra_172);

Cv2.WaitKey();
Cv2.DestroyAllWindows();

效果如下:

说明:PNG图像是一种典型的4通道(即B通道、G通道、R通道和A通道)图像,因此被保存的3幅图像的格式为.png



【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。