Opencv-C++笔记 (9) : opencv-多通道分离和合并

这篇具有很好参考价值的文章主要介绍了Opencv-C++笔记 (9) : opencv-多通道分离和合并。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、概论

在图像颜色模型中不同的分量存放在不同的通道中,如果我们只需要颜色模型的某一个分量,例如只需要处理RGB图像中的红色通道,可以将红色通道从三通道的数据中分离出来再进行处理,这种方式可以减少数据所占据的内存,加快程序的运行速度。同时,当我们分别处理完多个通道后,需要将所有通道合并在一起重新生成RGB图像。针对图像多通道的分离与混合,OpenCV 4中提供了split()函数和merge()函数用于解决这些需求。
opencv知识点:

  • 通道分离 - split() 通道合并
  • merge() 通道混合
  • mixChannels()

二、多通道分离函数split()

OpenCV 4中针对多通道分离函数split()有两种重载原型,在代码清单3-4中给出了这两种函数原型。

void cv::split(const Mat & src,
                 Mat * mvbegin
                 )
void cv::split(InputArray m,
                 OutputArrayOfArrays mv
                 )

src:待分离的多通道图像。
mvbegin:分离后的单通道图像,为数组形式,数组大小需要与图像的通道数相同
m:待分离的多通道图像
mv:分离后的单通道图像,为向量vector形式
该函数主要是用于将多通道的图像分离成若干单通道的图像,两个函数原型中不同之处在于前者第二个参数输入的是Mat类型的数组,其数组的长度需要与多通道图像的通道数相等并且提前定义;第二种函数原型的第二个参数输入的是一个vector容器,不需要知道多通道图像的通道数。两个函数原型虽然输入参数的类型不同,但是通道分离的原理是相同的,可以用公式(3.4)表示。
Opencv-C++笔记 (9) : opencv-多通道分离和合并

三、多通道合并函数merge()

OpenCV 4中针对多通道合并函数merge()也有两种重载原型,在代码清单3-5中给出了两种原型。多通道合并函数merge()
OpenCV 4中针对多通道合并函数merge()也有两种重载原型,在代码清单3-5中给出了两种原型。

void cv::merge(const Mat * mv,
                  size_t  count,
                  OutputArray dst
                 ) 
void cv::merge(InputArrayOfArrays mv,
                  OutputArray dst
                 )

mv:需要合并的图像数组,其中每个图像必须拥有相同的尺寸和数据类型。
count:输入的图像数组的长度,其数值必须大于0.
mv:需要合并的图像向量vector,其中每个图像必须拥有相同的尺寸和数据类型。
dst:合并后输出的图像,与mv[0]具有相同的尺寸和数据类型,通道数等于所有输入图像的通道数总和。
该函数主要是用于将多个图像合并成一个多通道图像,该函数也具有两种不同的函数原型,每一种函数原型都是与split()函数相对应,两种原型分别输入数组形式的图像数据和向量vector形式的图像数据,在输入数组形式数据的原型中,还需要输入数组的长度。合并函数的输出结果是一个多通道的图像,其通道数目是所有输入图像通道数目的总和。这里需要说明的是,用于合并的图像并非都是单通道的,也可以是多个通道数目不相同的图像合并成一个通道更多的图像,虽然这些图像的通道数目可以不相同,但是需要所有图像具有相同的尺寸和数据类型

//函数定义
void channels_demo(Mat& image);

//函数实现—
void QuickDemo::channels_demo(Mat& image) {

	Mat mvt[3];
	/*
	第一种方式
		通过创建图像数组,存储每个单通道图像
	*/
	split(image, mvt);

	imshow("蓝色单通道", mvt[0]);
	imshow("绿色单通道", mvt[1]);
	imshow("蓝色单通道", mvt[2]);
}
void QuickDemo::channels_demo(Mat& image) {

	std::vector<Mat> mvt;
	/*
	第二种方式
		通过创建动态数组,存储每个单通道图像
	*/
	split(image, mvt);

	imshow("蓝色单通道", mvt[0]);
	imshow("绿色单通道", mvt[1]);
	imshow("红色单通道", mvt[2]);
}

这里我们进行一个演示,实现如下通道的混合

0通道→2通道
1通道不变
2通道→1通道

这个混合的意思是,彩色图像本来是bgr的顺序,经过通道混合就变成了rgb。

0通道的单通道图像,变成了2通道的单通道图像
1通道不变
2通道的单通道图像,变成了0通道的单通道图像

void QuickDemo::channels_demo(Mat& image) {

	Mat dst = Mat::zeros(image.size(), image.type());

	int from_to[] = { 0,2,1,1,2,0 };

	mixChannels(&image, 1, &dst, 1, from_to, 3);
	
	imshow("通道混合",dst);
}

Opencv-C++笔记 (9) : opencv-多通道分离和合并
Opencv-C++笔记 (9) : opencv-多通道分离和合并

Mat bgra( 100, 100, CV_8UC4, Scalar(255,0,0,255) );
Mat bgr( bgra.rows, bgra.cols, CV_8UC3 );
Mat alpha( bgra.rows, bgra.cols, CV_8UC1 );
// forming an array of matrices is a quite efficient operation,
// because the matrix data is not copied, only the headers
Mat out[] = { bgr, alpha };
// bgra[0] -> bgr[2], bgra[1] -> bgr[1],
// bgra[2] -> bgr[0], bgra[3] -> alpha[0]
int from_to[] = { 0,2, 1,1, 2,0, 3,3 };
mixChannels( &bgra, 1, out, 2, from_to, 4 );

四、图像多通道分离与合并例程

为了使读者更加熟悉图像多通道分离与合并的操作,同时加深对图像不同通道作用的理解,在代码清单3-6中实现了图像的多通道分离与合并的功能。程序中用两种函数原型分别分离了RGB图像和HSV图像,为了验证merge ()函数可以合并多个通道不相同的图像,程序中分别用两种函数原型合并了多个不同通道的图像,合并后图像的通道数为5,不能通过imshow()函数显示,我们用Image Watch插件查看了合并的结果。由于RGB三个通道分离结果显示时都是灰色且相差不大,因此图3-5没有给出其分离后的结果,只给出合并后显示为绿色的合并图像,同时给出HSV分离结果,其他结果读者可以自行运行程序查看。

void QuickDemo::channels_demo(Mat& image) {

	Mat mvt[3];
	
	split(image, mvt);

	imshow("蓝色单通道", mvt[0]);
	imshow("绿色单通道", mvt[1]);
	imshow("红色单通道", mvt[2]);

	Mat dst;
	
	merge(mvt,3,dst);
	/*
	这里的3指,共有3个单通道图像
	*/
	imshow("分离再合并",dst);

}
void QuickDemo::channels_demo(Mat& image) {

	std::vector<Mat> mvt;

	split(image, mvt);

	imshow("蓝色单通道", mvt[0]);
	imshow("绿色单通道", mvt[1]);
	imshow("红色单通道", mvt[2]);

	Mat dst;

	merge(mvt, dst);

	imshow("分离再合并",dst);

}
#include<iostream>
#include<vector>
#include<string>
#include <opencv2/opencv.hpp>
#include "opencv/highgui.h"

using namespace std;
using namespace cv;

int main(int argc,char** argv) {
    cout<<"OpenCv Version: "<<CV_VERSION<<endl;
    Mat img=imread("/home/wyh/Documents/C++demo/699342568.jpg");
    if(img.empty()){
        cout<<"请确认输入图片的名称是否正确"<<endl;
        return -1;
    }
    Mat HSV,dst;
    resize(img,dst,Size(img.cols*0.5,img.rows*0.5));
    cvtColor(dst,HSV,COLOR_BGR2HSV);
    Mat imgs0,imgs1,imgs2;//用于存放数组类型的结果
    Mat imgv0,imgv1,imgv2;//用于存放vector类型的结果
    Mat result0,result1,result2;//多通道合并的结果

    //输入数组参数的多通道分离与合并
    Mat imgs[3];
    split(dst,imgs);
    imgs0=imgs[0];
    imgs1=imgs[1];
    imgs2=imgs[2];
    imshow("RGB-R通道",imgs0);//显示分离后R通道的像素值
    imshow("RGB-G通道",imgs1);//显示分离后G通道的像素值
    imshow("RGB-B通道",imgs2);//显示分离后B通道的像素值
    imgs[2]=dst;//将数组中的图像通道数变成不统一
    merge(imgs,3,result0);//合并图像

    Mat zero=Mat::zeros(dst.rows,dst.cols,CV_8UC1);
    imgs[0]=zero;
    imgs[2]=zero;
    merge(imgs,3,result1);//用于还原G通道的真实情况,合并结果为绿色
    imshow("result1",result1);//显示合并结果

    //输入vector参数的多通道分离与合并
    vector<Mat>imgv;
    split(HSV,imgv);
    imgv0=imgv.at(0);
    imgv1=imgv.at(1);
    imgv2=imgv.at(2);
    imshow("HSV-H通道",imgv0);//显示分离后H通道的像素值
    imshow("HSV-S通道",imgv1);//显示分离后S通道的像素值
    imshow("HSV-V通道",imgv2);//显示分离后V通道的像素值
    imgv.push_back(HSV);//将vector中的图像通道数变成不统一
    merge(imgv,result2);//合并图像
    waitKey(0);
    return 0;
}

Opencv-C++笔记 (9) : opencv-多通道分离和合并文章来源地址https://www.toymoban.com/news/detail-491109.html

到了这里,关于Opencv-C++笔记 (9) : opencv-多通道分离和合并的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Opencv-C++笔记 (12) : opencv-仿射变化

    介绍完图像的缩放和翻转后,接下来将要介绍图像的旋转,但是在OpenCV 4中并没有专门用于图像旋转的函数,而是通过图像的仿射变换实现图像的旋转。实现图像的旋转首先需要确定旋转角度和旋转中心,之后确定旋转矩阵,最终通过仿射变换实现图像旋转。 针对这个流程,

    2024年02月11日
    浏览(50)
  • Opencv-C++笔记 (2) : opencv的矩阵操作

    OpenCV中的矩阵操作非常重要,本文总结了矩阵的创建、初始化以及基本矩阵操作,给出了示例代码,主要内容包括: 建立矩阵必须要指定矩阵存储的数据类型,图像处理中常用的几种数据类型如下: 包括数据位深度8位、32位,数据类型U:uchar、F:float型以及通道数C1:单通道、

    2024年02月11日
    浏览(49)
  • Opencv-C++笔记 (5) : opencv-形态学

    形态学运算是针对二值图像依据数学形态学(Mathematical Morphology)的集合论方法发展起来的图像处理方法。数学形态学起源于岩相学对岩石结构的定量描述工作,近年来在数字图像处理和机器视觉领域中得到了广泛的应用,形成了一种独特的数字图像分析方法和理论。 结构元素

    2024年02月09日
    浏览(53)
  • Opencv-C++笔记 (10) : opencv-图像像素计算

    我们可以将数字图像理解成一定尺寸的矩阵,矩阵中每个元素的大小表示了图像中每个像素的亮暗程度,因此统计矩阵中的最大值,就是寻找图像中灰度值最大的像素,计算平均值就是计算图像像素平均灰度,可以用来表示图像整体的亮暗程度。因此针对矩阵数据的统计工作

    2024年02月09日
    浏览(41)
  • Opencv-C++笔记 (6) : opencv-图片和视频操作

    filename:需要读取图像的文件名称,包含图像地址、名称和图像文件扩展名 flags:读取图像形式的标志,如将彩色图像按照灰度图读取,默认参数是按照彩色图像格式读取,可 选参数在表2-3给出。 函数用于读取指定的图像并将其返回给一个Mat类变量,如果图像文件不存在、破

    2024年02月09日
    浏览(48)
  • Opencv-C++笔记 (18) : 轮廓和凸包

    轮廓发现是基于图像边缘提取的基础寻找对象轮廓的方法。 所以边缘提取的阈值选定会影响最终轮廓发现结果 轮廓查找步骤: 输入图像转为灰度图像cvtColor 使用Canny进行边缘提取或者threshold阈值操作,得到二值图像 使用findContours寻找轮廓 使用drawContours绘制轮廓 在二值图像

    2024年02月11日
    浏览(42)
  • Opencv-C++笔记 (7) : opencv-文件操作XML和YMAL文件

    除了图像数据之外,有时程序中的尺寸较小的Mat类矩阵、字符串、数组等 数据也需要进行保存,这些数据通常保存成XML文件或者YAML文件。本小节中将介绍如何利用OpenCV 4中的函数将数据保存成XML文件或者YAML文件以及如何读取这两种文件中的数据。 XML是一种元标记语言,所谓

    2024年02月09日
    浏览(73)
  • Opencv-C++笔记 (3) : opencv的库介绍以及和C++对接转换

    calib3d 主要包含相机标定,立体视觉的功能:物体姿势估计,三维重建,摄像头标定 core,包含库的基本结构和操作,比如数据结构,绘图函数,数组操作等函数 dnn,深度学习模块,包含构建网络,加载序列化的模型,但是不支持训练,只能推理 features2d,处理图像特征点,特

    2024年02月09日
    浏览(46)
  • OpenCV - 图片增加透明通道,图片合并透明通道

    一般人像抠图相关的AI模型会输出一个Mask图,这个Mask图就是我们需要的可以将人物抠出来的Alpha通道信息,我们需要将这个Mask图附加到原始图片上,从BGR图片转成BGRA图片或者从RGB图片转成RGBA图片。 如果使用OpenCV进行图像处理,在为图像增加透明通道时会使用到 cv::split 和

    2024年02月16日
    浏览(39)
  • Opencv-C++笔记 (15) : 像素重映射 与 图像扭曲

    重映射,就是把一幅图像中某位置的像素放置到另一图像指定位置的过程。即: 在重映射过程中,图像的大小也可以同时发生改变。此时像素与像素之间的关系就不是一一对应关系,因此在重映射过程中,可能会涉及到像素值的插值计算。 头文件 quick_opencv.h:声明类与公共

    2024年02月13日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包