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

目录

1、拆分通道

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

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

2、合并通道

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

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

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

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

4、alpha通道

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


一副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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/220006.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一文介绍接口测试中的请求和响应

在测试工作中,我们经常要对web应用或者app进行接口测试,接口测试过程中最重要的就是掌握一个接口中的请求和响应。本文主要是为大家介绍一下接口中的请求和响应到底是什么,在前后端交互中主要起什么作用。 一:介绍一下HTTP 我们…

一文带你了解Java中synchronized原理

🌈🌈🌈今天给大家分享的是Java中 synchronized 的基本原理 清风的CSDN博客 🛩️🛩️🛩️希望我的文章能对你有所帮助,有不足的地方还请各位看官多多指教,大家一起学习交流&#xff…

2023 年 O 基础学习 SwiftUI

关于 SwiftUI SwiftUI 于2019年6月3日在苹果的全球开发者大会(WWDC)上首次亮相。在这次活动中,苹果正式宣布了 SwiftUI,并将其列为 iOS 13 和 macOS Catalina 的一部分。 SwiftUI 是一种用于构建用户界面的 UI 框架。SwiftUI 的设…

Servlet基础知识

Servlet是Java提供的一门动态的web资源开发技术 Servlet是JavaEE规范之一&#xff0c;其实就是一个接口&#xff0c;将来我们需要定义Servlet类实现Servlet接口&#xff0c;并由web服务器运行Servelt Servlet快速入门 创建web项目&#xff0c;导入Servlet依赖坐标 <depe…

百度Apollo新版本Beta技术沙龙参会体验

在自动驾驶领域&#xff0c;百度的Apollo一直是业界开源的标杆。其持续升级和创新的开源项目为整个自动驾驶行业树立了典范&#xff0c;不仅推动了技术的发展&#xff0c;也为广大的社区开发者们提供了学习和参考的范本。最近百度发布了Apollo新的Beta版本&#xff0c; 新版本B…

【PID学习笔记 6 】控制系统的性能指标之二

写在前面 上文介绍了控制系统的稳态与动态、过渡过程、阶跃响应以及阶跃信号作用下过渡过程的四种形式。本文紧接上文&#xff0c;首先总结过渡过程的分类&#xff0c;然后介绍控制系统的性能评价&#xff0c;最后重点介绍控制系统性能指标中的单项指标。 一、过渡过程的分类…

四.多表查询

多表查询 1.一个案例引发的多表连接1.1案例说明1.2 笛卡尔积&#xff08;或交叉连接&#xff09;的理解1.3案例分析与问题解决 2.多表查询分类讲解分类1&#xff1a;等值连接vs非等值连接分类2&#xff1a;自连接vs非自连接分类3&#xff1a;内连接vs外连接 3.SQL99语法实现多表…

读书笔记-《数据结构与算法》-摘要2[冒泡排序]

冒泡排序 核心&#xff1a;冒泡&#xff0c;持续比较相邻元素&#xff0c;大的挪到后面&#xff0c;因此大的会逐步往后挪&#xff0c;故称之为冒泡。 public class BubbleSort {public static void main(String[] args) {int unsortedArray[] new int[]{6, 5, 3, 1, 8, 7, 2…

旋转设备状态监测与预测性维护:提高设备可靠性的关键

在工业领域的各个行业中&#xff0c;旋转设备都扮演着重要的角色。为了确保设备的可靠运行和预防潜在的故障&#xff0c;旋转设备状态监测及预测性维护变得至关重要。本文将介绍一些常见的旋转设备状态监测方法&#xff0c;并探讨如何利用这些方法来实施预测性维护&#xff0c;…

Java的第二十一章:网络通信

网络程序设计基础 网络程序设计编写的是与其他计算机进行通信的程序。Java 已经将网络程序所需要的元素封装成不同的类&#xff0c;用户只要创建这些类的对象&#xff0c;使用相应的方法&#xff0c;即使不具备有关的网络支持&#xff0c;也可以编写出高质量的网络通信程序。 …

周周爱学习之快速排序

快速排序&#xff0c;顾名思义&#xff0c;快速排序是一种速度非常快的一种排序算法 平均时间复杂度为O(),最坏时间复杂度为O()数据量较大时&#xff0c;优势非常明显属于不稳定排序 1.算法描述 每一轮排序选择一个基准点&#xff08;pivot&#xff09;进行分区 让小于基准点…

supervisord + nginx + Daphne + django4.0 最新asgi服务器部署实验

由于需要用到channel&#xff0c;最近在研究通过asgi部署django。 先吐槽一下官方文档&#xff0c;这个地方讲的非常简单。然后中文互联网环境能找到的都是3.0试用的说明&#xff0c;这玩意是不是真的没人用啊&#xff1f;还是说Django已经脱离时代了。。。 简单研究了一下&am…

洗地机好用吗?口碑好的洗地机有哪些?

自从洗地机开始引入市场以来&#xff0c;它一直受到人们的关注。它在解放家庭清洁劳动力和提供快速方便的清洁方面表现出色&#xff0c;超越了多年来传统的拖把清洁方式。越来越多的人选择使用洗地机来完成家庭清洁任务。如果你也对洗地机产生了浓厚的兴趣&#xff0c;并想购买…

【MATLAB源码-第93期】基于matlab的白鲸优化算法(BWO)和鲸鱼优化算法(WOA)机器人栅格路径规划对比。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 白鲸优化算法&#xff08;BWO&#xff09; 白鲸优化算法是受到白鲸捕食和迁徙行为启发的一种算法。其主要特点和步骤包括&#xff1a; 1. 搜索食物&#xff08;全局搜索&#xff09;&#xff1a;算法模仿白鲸寻找食物的行为。…

【模型报错记录】‘PromptForGeneration‘ object has no attribute ‘can_generate‘

通过这个连接中的方法解决&#xff1a; “PromptForGeneration”对象没有属性“can_generate” 期刊 #277 thunlp/OpenPrompt GitHub的 问题描述&#xff1a;在使用model.generate() 的时候报错&#xff1a;PromptForGeneration object has no attribute can_generate 解决方法…

Java中子类都继承父类的什么?

1.构造方法 构造方法不可以被继承的&#xff0c;为什么呢&#xff1f;应为名称的定义&#xff0c;构造方法是一类名称与类名一致&#xff0c;无返回值和类型修饰的一种。所以如果子类继承父类的构造方法的话&#xff0c;那么就违背了构造方法的规定。 2.成员属性 成员属性是…

C# Demo--汉字转拼音

1.Nuget安装NPOI及Pinyin4net 2.Demo 代码部分 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using NPOI.SS.UserModel; using NPOI.HSSF.UserModel; using NPOI.XSSF.UserModel; using System.IO;…

【Linux】基础IO--重定向理解Linux下一切皆文件缓冲区

文章目录 一、重定向1.什么是重定向2.dup2 系统调用3.理解输入重定向、输出重定向和追加重定向4.简易shell完整实现 二、理解linux下一切皆文件三、缓冲区1.为什么要有缓冲区2.缓冲区的刷新策略3.缓冲区的位置4.实现一个简易的C语言缓冲区5.内核缓冲区 一、重定向 1.什么是重定…

【5】PyQt按钮

QPushButton 常见的按钮实现类包括:QPushButton、QRadioButton和QCheckBox QPushButton是最普通的按钮控件&#xff0c;可以响应一些用户的事件 from PyQt5.QtWidgets import QApplication, QWidget, QPushButton import sysdef func():print("按下按钮啦&#xff0c;火…

YOLOv8优化策略:简单高效的模块-现代反向残差移动模块 (iRMB) | | ICCV2023 EMO

🚀🚀🚀本文改进:设计了一种面向移动端应用的简单而高效的现代反向残差移动模块 (Inverted Residual Mobile Block, iRMB),它吸收了类似 CNN 的效率来模拟短距离依赖和类似 Transformer 的动态建模能力来学习长距离交互,引入YOLOV8 🚀🚀🚀YOLOv8改进专栏:http:…