OpenCV4通道的分离split(),通道的合并merge(),通道的混合mixChannels()

news2024/9/21 18:48:14

文章目录

    • 1、通道的分离函数 split()
      • 函数原型:
        • (1)函数原型一:用 Mat型数组 `Mat mvbegin[3]`存储分离后的图像;
          • 输入参数:
        • (2)函数原型二:用 vector容器 `vector <Mat>` 存储分离后的图像;
          • 输入参数:
        • (3)示例:
          • 运行结果:
    • 2、通道合并函数 merge()
      • 函数原型:
        • (1)函数原型一:输入是,Mat型数组形式的图像数据 `Mat mvbegin[3]`
          • 输入参数:
        • (2)函数原型二:输入是,vector容器形式的图像数据 `vector <Mat>`
          • 输入参数:
        • (3)示例一:先用split()将图像三通道分离,用 Mat型数组 `Mat mvbegin[3]`存储分离后的图像,然后再将三通道图像用merge()合并,对应函数原型一;
          • 运行结果:
        • (4)示例二:先用split()将图像三通道分离,用 vector容器 `vector <Mat>` 存储分离后的图像,然后再将三通道图像用merge()合并,对应函数原型二;
          • 运行结果:
    • 3、通道的混合mixChannels()
        • (1)函数原型一:
          • 输入参数:
        • (2)函数原型二:
          • 输入参数:
        • (3)示例一:颜色通道交换 青色(255, 255, 0) 黄色(0, 255, 255)
          • 示例代码:
          • 运行结果:
        • (4)示例二:图像分割
          • 示例代码:
          • 运行结果:
        • (5)示例三:HSV通道获取
            • 示例代码:
            • 运行结果:

opencv中默认imread函数加载图像文件,加载进来的是三通道彩色图像,色彩空间是RGB色彩空间,通道顺序是BGR(蓝色、绿色、红色),对于三通道的图像OpenCV中提供了三个API函数用以实现通道分离split(),合并merge(),混合mixChannels();

RGB图像,在opencv的Mat中,像素数据,存储结构以及通道分离,操作关系图如下:

在这里插入图片描述

1、通道的分离函数 split()

函数原型:

两种函数原型的用法相同,用于将多通道的图像分离成若干单通道的图像,两个函数原型的不同之处在于,分离后的Mat型单通道图像,用Mat型数组存储,Mat mvbegin[3];还是用vector容器存储, vector <Mat> mv

OpenCV 4 中split()函数有2种重载原型:

(1)函数原型一:用 Mat型数组 Mat mvbegin[3]存储分离后的图像;

void split( const Mat &src, Mat *mvbegin )

输入参数:
  • src:待分离的图像,Mat型多通道矩阵;
  • mvbegin:分离后的Mat型单通道图像,用Mat型数组存储,Mat mvbegin[3],定义数组大小时需要知道原图像的通道数,数组大小=原图像通道数;
  • 分离后的图像存储在,Mat型数组 Mat mvbegin[3] 中,数组内的3个元素,大小均为 image.rows X image.cols 的Mat型矩阵,依次存放着原图像B、G、R分量的数据,取数组内的元素只能通过 [] 取值,不能通过 at() 取值;

(2)函数原型二:用 vector容器 vector <Mat> 存储分离后的图像;

void split( InputArray m, OutputArrayOfArrays mv )

输入参数:
  • m:待分离的图像,Mat型多通道矩阵;
  • mv:分离后的Mat型单通道图像,用vector容器存储,vector <Mat> mv,不需要知道原图像的通道数;
  • 分离后的图像存储在,vector容器 vector <Mat> mv 中,mv容器内有3个元素,每个元素的大小均为 image.rows X image.cols 的Mat型矩阵,依次存放着原图像B、G、R分量的数据,每个元素可以通过 []取值,也可以通过 at() 取值;

(3)示例:

#include <opencv2\opencv.hpp>
#include <iostream>
#include <demo.h>

using namespace cv;
using namespace std;

int main() {
	// 读取图像,BGR存储在Mat矩阵里
	Mat src = cv::imread("C:\\cpp\\image\\suzy1.jpg");
	if (src.empty()) {
		printf("could not load image..../n");
		return -1;
	}
	namedWindow("src", WINDOW_AUTOSIZE);
	imshow("src", src);

	// 用Mat型数组,存储分离后的图像,只能用 [] 访问
	// Mat mvbegin[3];
	// split(src, mvbegin);
	// imshow("B", mvbegin[0]);
	// imshow("G", mvbegin[1]);
	// imshow("R", mvbegin[2]); 

	// 用vector容器,存储分离后的图像,用 [] 访问
	// vector<Mat> mv;
	// split(src, mv);
	// imshow("B", mv[0]);
	// imshow("G", mv[1]);
	// imshow("R", mv[2]);

	// 用vector容器,存储分离后的图像,用 at() 访问
	vector<Mat> mv;
	split(src, mv);
	imshow("B", mv.at(0));
	imshow("G", mv.at(1));
	imshow("R", mv.at(2));

	waitKey();
	destroyAllWindows();
	return 0;
}
运行结果:

在这里插入图片描述

2、通道合并函数 merge()

  • 两种函数原型的用法相同,用于将多个图像(单通道或多通道图像)合并成一个多通道图像,两个函数原型的不同之处在于,输入是Mat型数组形式的图像数据 Mat mvbegin[3],还是一个vector容器形式的图像数据 vector <Mat>,这里和 split()函数原型相对应;
  • 合并函数输出的是一个多通道图像,其通道数是所有输入图像通道数的总和,用于合并的图像并非都是单通道的,也可以是多个通道的图像,输入图像的通道数目可以不相同,但是需要所有图像都具有相同的尺寸和数据类型;

函数原型:

(1)函数原型一:输入是,Mat型数组形式的图像数据 Mat mvbegin[3]

void merge( const Mat *mvbegin, size_tcount, OutputArray dst )

输入参数:
  • mvbegin:需要合并的单通道或多通道图像,输入的是一个,Mat型数组形式的图像数据 mvbegin[3]
  • size_tcount:输入图像数组的长度,其数值必须大于0;
  • dst:合并后的图像;

(2)函数原型二:输入是,vector容器形式的图像数据 vector <Mat>

void merge( InputArrayOfArrays mv, OutputArray dst )

输入参数:
  • mv:需要合并的单通道或多通道图像,输入的是一个,vector容器形式的图像数据 vector <Mat>,其中每个图像必须拥有相同的尺寸和数据类型;
  • dst:合并后的图像,与 mv[0]具有相同的尺寸和数据类型,通道数等于所有输入图像的通道数总和;

(3)示例一:先用split()将图像三通道分离,用 Mat型数组 Mat mvbegin[3]存储分离后的图像,然后再将三通道图像用merge()合并,对应函数原型一;

#include <opencv2\opencv.hpp>
#include <iostream>
#include <demo.h>

using namespace cv;
using namespace std;

int main() {
	// 读取图像,BGR存储在Mat矩阵里
	Mat src = cv::imread("C:\\cpp\\image\\suzy1.jpg");
	if (src.empty()) {
		printf("could not load image..../n");
		return -1;
	}
	namedWindow("src", WINDOW_AUTOSIZE);
	imshow("src", src);


	// 通道分离,用Mat型数组存储分离后的图像
	Mat mvbegin[3];
	split(src, mvbegin);
	Mat BlueChannel = mvbegin[0];
	Mat GreenChannel = mvbegin[1];
	Mat RedChannel = mvbegin[2];

	// 将R通道全部置0
	Mat r = mvbegin[2].clone();
	r.setTo(0);

	// 需要合并的Mat型数组 
	Mat newChannel[3] = { BlueChannel , GreenChannel , r };

	// 合并通道
	Mat dst;
	merge(newChannel, 3, dst);
	// 显示
	imshow("Merged", dst);

	waitKey();
	destroyAllWindows();
	return 0;
}
运行结果:

在这里插入图片描述

(4)示例二:先用split()将图像三通道分离,用 vector容器 vector <Mat> 存储分离后的图像,然后再将三通道图像用merge()合并,对应函数原型二;

#include <opencv2\opencv.hpp>
#include <iostream>
#include <demo.h>

using namespace cv;
using namespace std;

int main() {
	// 读取图像,BGR存储在Mat矩阵里
	Mat src = cv::imread("C:\\cpp\\image\\suzy1.jpg");
	if (src.empty()) {
		printf("could not load image..../n");
		return -1;
	}
	namedWindow("src", WINDOW_AUTOSIZE);
	imshow("src", src);


	// 通道分离
	vector<Mat> mv;
	split(src, mv);
	Mat BlueChannel = mv.at(0);
	Mat GreenChannel = mv.at(1);
	Mat RedChannel = mv.at(2);

	// 将B通道全部置0
	Mat b = mv.at(0).clone();
	b.setTo(0);

	vector<Mat> newChannel;
	newChannel.push_back(b);
	newChannel.push_back(GreenChannel);
	newChannel.push_back(RedChannel);

	//通道合并
	Mat mergedImage;
	merge(newChannel, mergedImage);
	// 显示
	imshow("Merged", mergedImage);

	waitKey();
	destroyAllWindows();
	return 0;
}
运行结果:

在这里插入图片描述

3、通道的混合mixChannels()

函数原型:

(1)函数原型一:

void cv::mixChannels	(
	InputArrayOfArrays		src,
	InputOutputArrayOfArrays 	dst,
	const std::vector< int > 	&fromTo 
)
输入参数:
  • src:输入矩阵,所有矩阵的大小和深度必须相同;
  • dst:输出矩阵,大小和深度必须与 src[0]相同;
  • fromTo:索引对,表示输入矩阵的第几个通道,复制到,输出矩阵的第几个通道;举例说明:
    { 0, 2, 1, 1, 2, 0 } 表示:
    src颜色通道0 复制到 dst颜色通道2
    src颜色通道1 复制到 dst颜色通道1
    src颜色通道2 复制到 dst颜色通道0
    在这里插入图片描述

(2)函数原型二:

在这个函数原型中:

  • 如果输入矩阵和输出矩阵都是1,那么就跟第一种函数原型一致了;
  • 如果不为1,就可以实现多个矩阵的合并,或者一个矩阵拆分为多个矩阵,或者其他功能;
void cv::mixChannels
(
	const Mat 	*src,
	size_t 		nsrcs,
	Mat		*dst,
	size_t	        ndsts,
	const int       *fromTo,
	size_t 		npairs 
)
输入参数:
  • src:输入矩阵,所有矩阵的大小和深度必须相同;
  • ndsts:矩阵的数量;
  • dst:输出矩阵,大小和深度必须与 src[0]相同;
  • fromTo:索引对,表示输入矩阵的第几个通道,复制到,输出矩阵的第几个通道;
  • ndsts:矩阵的数量;
  • npairs:fromTo中索引对的数目;

(3)示例一:颜色通道交换 青色(255, 255, 0) 黄色(0, 255, 255)

原图的青色(255, 255, 0),通过指定通道复制到输出图像中变成了黄色(0, 255, 255);

通道对应关系:

索引对 from_to[] = { 0, 2, 1, 1, 2, 0, 3, 3 } 的含义:

  • bg的0通道,复制到,out[]的2通道,即bgr的0通道;
  • bgra的1通道,复制到,out[]的1通道,即bgr的1通道;
  • bgra的2通道,复制到,out[]的0通道,即bgr的2通道;
  • bgra的3通道,复制到,out[]的3通道,即bgr的alpha通道;
    在这里插入图片描述
示例代码:
#include <opencv2\opencv.hpp>
#include <iostream>
#include <demo.h>

using namespace cv;
using namespace std;

int main() {
	// 读取图像,BGR存储在Mat矩阵里
	Mat src = cv::imread("C:\\cpp\\image\\suzy1.jpg");
	if (src.empty()) {
		printf("could not load image..../n");
		return -1;
	}
	namedWindow("src", WINDOW_AUTOSIZE);
	imshow("src", src);

	Mat bgra(200, 200, CV_8UC4, Scalar(255, 255, 0, 255));
	Mat bgr(bgra.rows, bgra.cols, CV_8UC3);
	Mat alpha(bgra.rows, bgra.cols, CV_8UC1);

	Mat out[] = { bgr, alpha };

	int from_to[] = { 0, 2, 1, 1, 2, 0, 3, 3 };
	mixChannels(&bgra, 1, out, 2, from_to, 4);

	imshow("bgra", bgra);
	imshow("bgr", bgr);

	waitKey();
	destroyAllWindows();
	return 0;
}
运行结果:

在这里插入图片描述

(4)示例二:图像分割

将一个4通道矩阵(BGRA图像)分割成一个3通道矩阵(BGR图像)和一个单通道矩阵(alpha通道图像);

通道对应关系:索引对,int fromTo[] = { 0, 2, 1, 1, 2, 0, 3, 3 }

  • bgra的0通道,复制到,bgr的2通道;
  • bgra的1通道,复制到,bgr的1通道;
  • bgra的2通道,复制到,bgr的0通道;
  • bgra的3通道,复制到,alpha的0通道;
示例代码:
#include <opencv2\opencv.hpp>
#include <iostream>
#include <demo.h>

using namespace cv;
using namespace std;

int main() {

	Mat bgra( 200, 200, CV_8UC4, Scalar(255, 0, 0, 255) );
	Mat bgr( bgra.rows, bgra.cols, CV_8UC3 );
	Mat alpha( bgra.rows, bgra.cols, CV_8UC1 );

	Mat out[] = { bgr,alpha };
	// 通道对应关系
	int fromTo[] = { 0, 2, 1, 1, 2, 0, 3, 3 };

	mixChannels(&bgra, 1, out, 2, fromTo, 4);
	imshow("bgra", bgra);
	imshow("bgr", bgr);
	imshow("alpha", alpha);

	waitKey();
	destroyAllWindows();
	return 0;
}
运行结果:

在这里插入图片描述

(5)示例三:HSV通道获取

利用mixChannels()函数通过,复制指定通道,可以看到HSV颜色空间下的三个通道的具体情况;

HSV颜色空间:

  • Hue(色相):代表色彩,取 0 到 360 度的数值来衡量(红-黄-绿-青-蓝-洋红);
  • Saturation(饱和度、色度):指色彩的深浅,饱和度代表灰色与色调的比例,并以 0% (灰色) 到 100% (完全饱和) 来衡量,S=0时只有灰度;
  • Value(色调):色彩的明亮程度,V=1,它包含RGB模型中的R=1,G=1,B=1 三个面,所代表的颜色较亮;
示例代码:
#include <opencv2\opencv.hpp>
#include <iostream>
#include <demo.h>

using namespace cv;
using namespace std;

int main() {
	// 读取图像,BGR存储在Mat矩阵里
	Mat src = cv::imread("C:\\cpp\\image\\suzy1.jpg");
	if (src.empty()) {
		printf("could not load image..../n");
		return -1;
	}
	namedWindow("src", WINDOW_AUTOSIZE);
	imshow("src", src);

	Mat hsv, dst;
	cvtColor(src, hsv, COLOR_BGR2HSV);
	dst.create( hsv.size(), hsv.depth() );

	//分离Hue,色相通道
	int ch[] = { 0, 0 };
	mixChannels(&hsv, 1, &dst, 1, ch, 1);
	imshow("H channel", dst);

	//分离Saturation,饱和度通道
	int ch1[] = { 1, 0 };
	mixChannels(&hsv, 1, &dst, 1, ch1, 1);
	imshow("S channel", dst);

	//分离Value,色调通道
	int ch2[] = { 2, 0 };
	mixChannels(&hsv, 1, &dst, 1, ch2, 1);
	imshow("V channel", dst);

	waitKey();
	destroyAllWindows();
	return 0;
}
运行结果:

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

科技中心PMO的建设与实践︱德邦证券PMO专家张鉴庭

德邦证券科技中心PMO专家张鉴庭先生受邀为由PMO评论主办的2023第十二届中国PMO大会演讲嘉宾&#xff0c;演讲议题&#xff1a;科技中心PMO的建设与实践。大会将于8月12-13日在北京举办&#xff0c;敬请关注&#xff01; 议题简要&#xff1a; 在数字化转型的背景下&#xff0c…

jvm对象创建和内存分配优化

一、创建对象过程 1、类加载检测 虚拟机遇到一条new指令时&#xff0c;首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用&#xff0c;并且检查这个符号引用代表的类是否是否已被加载、解析和初始化过。如果没有&#xff0c;那必须先执行相应的类加载过程。 …

ModaHub魔搭社区:向量数据库Milvus Lite的优势和适配场景

目录 Milvus Lite 的优势 Milvus Lite 的适配场景 如何安装、部署和使用 Milvus Lite? 总结 想要体验世界上最快的向量数据库&#xff1f;缺少专业的工程师团队作为支撑&#xff1f;Milvus 安装环境受限&#xff1f; 别担心&#xff0c;轻量版 Milvus 来啦&#xff01; …

火爆全网,python自动化测试 parametrize参数化+allure测试报告(详细)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 pytest的参数化&a…

1763_gcc编译c语言makefile自动生成工具的Perl实现_Linux

全部学习汇总&#xff1a; GreyZhang/g_makefile: Learn makefile from all kinds of tutorials on the web. Happy hacking and lets find an common way so we may dont need to touch makefile code any more! (github.com) 其实&#xff0c;调试完这个之后觉得之前Windows上…

开源:老朋友,新棋局

在软件开发领域&#xff0c;开源已经成为一股强大的力量&#xff0c;为企业带来了巨大的好处。我深知开源的价值和影响力。其中之一就是降低开发成本。传统的软件开发往往需要庞大的开发团队和昂贵的授权费用&#xff0c;但开源软件将这一切变得通俗易懂。 避免了重复造轮子&a…

ROS-Moveit!配置

文章目录 1. SW2URDF2.Moveit下载及初始化3.自碰撞矩阵 Self-Collisions4.虚拟关节 Virtual Joints&#xff08;不配置&#xff09;5.规划组 Planning Groups添加机械臂规划组添加夹爪规划组 6.机器人姿态 Robot Pose7.末端执行器 End Effectors8.作者信息 Author Information9…

(秋招)面激光slam必备知识--scan context

scan context是一个描述场景的描述符&#xff0c;它之前不是用在slam上面的&#xff0c;但是有人将它用到激光slam上面&#xff0c;发现还可以&#xff0c;于是这个scan context就用来进行激光slam的位置识别(做闭环用的)。 ​ 编辑切换为居中 添加图片注释&#xff0c;不超过…

Python基础综合案例-数据可视化(地图)

今天给大家带来的是Python综合实战开发的数据可视化操作 通过python实现对数据的分析、可视化 数据来源:线上公布数据&#xff0c;需要可私信 前期准备工作&#xff1a;Python可视化准备工作 前期模块安装等前期基础的准备工作大家可以看我之前的文章讲解&#xff0c;有问题可…

< 每日算法 - JavaScript解析:一文解决 “ 买卖股票 ” 系列算法题 >

每日算法 - JavaScript解析&#xff1a;一文解决 “ 买卖股票 ” 系列算法题 一、基础题目> 题目> 解题思路定义操作定义状态动态规划值所需变量完整代码 二、添加条件&#xff1a;当交易次数为 ∞ 时> 题目> 解决思路 三、添加条件&#xff1a;当交易次数为 K nu…

小机器人在现实世界中学会快速驾驶

小机器人在现实世界中学会快速驾驶 —强化学习加上预训练让机器人赛车手加速前进— Without a lifetime of experience to build on like humans have (and totally take for granted), robots that want to learn a new skill often have to start from scratch. Reinforceme…

【案例教程】GIS在地质灾害危险性评估与灾后重建中的实践技术应用及python机器学习灾害易发性评价模型建立与优化

地质灾害是指全球地壳自然地质演化过程中&#xff0c;由于地球内动力、外动力或者人为地质动力作用下导致的自然地质和人类的自然灾害突发事件。由于降水、地震等自然作用下&#xff0c;地质灾害在世界范围内频繁发生。我国除滑坡灾害外&#xff0c;还包括崩塌、泥石流、地面沉…

AI对话宝-智能AI在线问答写作

AI对话宝的工作原理是基于自然语言处理技术。当用户与其进行交互时&#xff0c;AI对话宝会根据用户的输入&#xff0c;通过算法和模型来理解用户的意图&#xff0c;并给出相应的回答&#xff0c;并且系统还可以不断学习并优化其回答&#xff0c;从而提高其交互的效率和准确性。…

批量提取目录下的所有文件名称放至Excel表格中,方便快捷,快来试试吧

批量提取目录下的所有文件名称放至Excel表格中&#xff0c;方便快捷&#xff0c;快来试试吧 Sina Visitor Systemhttps://weibo.com/tv/show/1034:4920955869265935?fromold_pc_videoshow

binwalk-解包工具

一、binwalk介绍 二、安装binwalk # 1. 安装依赖和binwalk ​git clone https://github.com/ReFirmLabs/binwalk.git cd binwalk sudo python ./setup.py uninstall # 如果您有以前安装的 Binwalk 版本&#xff0c;建议您在升级之前将其卸载 sudo ./deps.sh # 安装依赖项 sud…

C语言学习(三十五)---动态内存练习题与柔性数组

经过前面的内容&#xff0c;我们已经对动态内存的知识已经有了相当多了了解&#xff0c;今天我们再做几道有关动态内存的练习题&#xff0c;然后再介绍一下柔性数组&#xff0c;好了&#xff0c;话不多说&#xff0c;开整&#xff01;&#xff01;&#xff01; 动态内存练习题…

上海亚商投顾:沪指失守3200点 两市成交不足8000亿

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 市场情绪 沪指今日延续调整&#xff0c;失守3200点关口&#xff0c;深成指、创业板指盘中均跌超1%。AI概念股集体下挫&#…

你会做接口测试吗?接口测试面试题盲扫(附答案)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 为什么要做接口测…

【跑实验06】如何数据集中加入图像尺寸?如何把tuple格式的坐标按顺序写成四列数据?如何把某一列放到最后?

文章目录 一、如何数据集中加入图像尺寸&#xff1f;二、如何把tuple格式的坐标按顺序写成四列数据&#xff1f;三、如何把某一列放到最后&#xff1f; 一、如何数据集中加入图像尺寸&#xff1f; 部分核心代码如下&#xff1a; image_files [filename for filename in os.l…

Windows | \\wsl.localhost无法访问

Windows | \\wsl.localhost无法访问 在地址栏输入&#xff1a;\\wsl.localhost或者\\wsl.localhost\