Opencv-C++ Notes (9): opencv-multi-channel separation and merging

1. Introduction

In the image color model, different components are stored in different channels. If we only need a certain component of the color model, for example, we only need to process the red channel in the RGB image, we can separate the red channel from the three-channel data and then This method can reduce the memory occupied by the data and speed up the running speed of the program. At the same time, when we have processed multiple channels separately, we need to merge all the channels together to regenerate the RGB image. For the separation and mixing of multi-channel images, the split() function and merge() function are provided in OpenCV 4 to solve these requirements.
opencv knowledge points:

  • Channel separation - split() channel merge
  • merge() channel mix
  • mixChannels()

Two, multi-channel separation function split()

There are two overloaded prototypes for the multi-channel separation function split() in OpenCV 4, and these two function prototypes are given in Code Listing 3-4.

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

src: the multi-channel image to be separated.
mvbegin: the separated single-channel image, in the form of an array, and the size of the array needs to be the same as the number of channels of the image
m: the multi-channel image to be separated
mv: the separated single-channel image, in the form of a vector
This function is mainly used to convert The multi-channel image is separated into several single-channel images. The difference between the two function prototypes is that the second parameter of the former is an array of Mat type. The length of the array needs to be equal to the number of channels of the multi-channel image and be defined in advance. ; The second parameter of the second type of function prototype is input as a vector container, and the number of channels of the multi-channel image does not need to be known. Although the types of input parameters of the two function prototypes are different, the principle of channel separation is the same, which can be expressed by formula (3.4).
insert image description here

3. Multi-channel merge function merge()

In OpenCV 4, there are also two overloaded prototypes for the multi-channel merge function merge(), and two prototypes are given in Code Listing 3-5. Multi-channel merge function merge()
In OpenCV 4, there are also two overloaded prototypes for the multi-channel merge function merge(), and two prototypes are given in Code Listing 3-5.

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

mv: Array of images to be merged, where each image must have the same size and data type.
count: The length of the input image array, and its value must be greater than 0.
mv: The image vector vector to be merged, where each image must have the same size and data type.
dst: The output image after merging, which has the same size and data type as mv[0], and the number of channels is equal to the sum of the number of channels of all input images.
This function is mainly used to merge multiple images into a multi-channel image. This function also has two different function prototypes. Each function prototype corresponds to the split() function, and the two prototypes are respectively input in the form of an array. The image data and the image data in the form of vector vector, in the prototype of inputting data in the form of an array, the length of the array also needs to be input. The output of the merge function is a multi-channel image whose number of channels is the sum of the number of channels of all input images. What needs to be explained here is that not all images used for merging are single-channel, and multiple images with different numbers of channels can be combined into one image with more channels. Although the number of channels of these images can be different, it is necessary to All images have the same dimensions and data type

//函数定义
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]);
}

Here we make a demonstration to achieve the mixing of the following channels

Channel 0 → Channel 2 Channel
1 remains unchanged
Channel 2 → Channel 1

This mixing means that the color image is originally in the order of bgr, and it becomes rgb after channel mixing.

The 0-channel single-channel image becomes a 2-channel single-channel image, the
1-channel single-channel image remains unchanged, and
the 2-channel single-channel image becomes a 0-channel single-channel image

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);
}

insert image description here
insert image description here

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 );

4. Image multi-channel separation and merging routine

In order to make readers more familiar with the operation of image multi-channel separation and merging, and at the same time deepen the understanding of the functions of different channels of images, the function of multi-channel separation and merging of images is realized in code list 3-6. In the program, two function prototypes are used to separate the RGB image and the HSV image respectively. In order to verify that the merge () function can merge multiple images with different channels, the program uses two function prototypes to merge multiple images of different channels. The number of channels of the final image is 5, which cannot be displayed by the imshow() function. We use the Image Watch plug-in to view the merged results. Since the separation results of the three RGB channels are displayed in gray and the difference is not large, Figure 3-5 does not show the separated results, but only shows the merged image that is displayed in green after merging, and gives the HSV separation results at the same time. Readers of other results can run the program to view by themselves.

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;
}

insert image description here

Guess you like

Origin blog.csdn.net/jiyanghao19/article/details/131250320