This tutorial gives a deep insight of splitting
and merging function of opencv. Thus enabling us to split a color image into
their respective RGB channels:
We want to split a color image into its three
channels called "Red" ,"Green" and "Blue".
Splitting a color image into its respective RGB
channels gives us an idea about the component of color which is present in an
original image.
OpenCV provides built in function called “split()”
for this purpose.
Syntax:
C++: void split(const Mat& src, Mat*
mvbegin)
Parameters:
src – input multi-channel array.
mv – output array or vector of arrays
In the first variant of the function the number
of arrays must match src.channels(); the arrays themselves are reallocated, if
needed.
The function “merge()” does just the opposite
to that of split.
It creates one multichannel array out of
several single-channel ones.
Syntax:
C++: void merge(const Mat* mv, size_t
count, OutputArray dst)
Parameters:
mv – input array or vector of
matrices to be merged; all the matrices in mv must have the same size and
the same depth.
count – number of input matrices when
mv is a plain C array; it must be greater than zero.
dst – output array of the same size
and the same depth as mv[0].
The number of channels will be the total number
of channels in the matrix array.
The functions merge merge several
arrays to make a single multi-channel array.
Here is the code below:
#include "opencv2/objdetect/objdetect.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> using namespace cv; using namespace std; int main() { Mat image; image = imread("C:\\Users\\arjun\\Desktop\\aaa.png", CV_LOAD_IMAGE_COLOR); // Read the file if(! image.data ) // Check for invalid input { cout << "Could not open or find the image" << std::endl ; return -1; } namedWindow( "Original Image", CV_WINDOW_AUTOSIZE ); imshow( "Original Image", image ); Mat rgbchannel[3]; // The actual splitting. split(image, rgbchannel); namedWindow("Blue",CV_WINDOW_AUTOSIZE); imshow("Red", rgbchannel[0]); namedWindow("Green",CV_WINDOW_AUTOSIZE); imshow("Green", rgbchannel[1]); namedWindow("Red",CV_WINDOW_AUTOSIZE); imshow("Blue", rgbchannel[2]); waitKey(0);//Wait for a keystroke in the window return 0; }
Input:
Output:
The code for that is given below:
Input:
Output:
Output:
Note:
You might have observed that here we
get grayscale images instead of Red,Green and
Blue colours separately after splitting the colour image.
Reason:
Split function splits the
multichannel image into single channel arrays containing the identical pixel
value of the original image.
So since we have created single
channel images,opencv imshow function treats it as a grayscale image.
For a colour image, we need to create
a three channel image.
The code for that is given below:
#include "opencv2/objdetect/objdetect.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; int main() { Mat image=imread("C:\\Users\\arjun\\Desktop\\aaa.png",1); namedWindow("Original Image",1); imshow("Original Image",image); // Split the image into different channels vector<Mat> rgbChannels(3); split(src, rgbChannels); // Show individual channels Mat g, fin_img; g = Mat::zeros(Size(image.cols, image.rows), CV_8UC1); // Showing Red Channel // G and B channels are kept as zero matrix for visual perception { vector<Mat> channels; channels.push_back(g); channels.push_back(g); channels.push_back(rgbChannels[2]); /// Merge the three channels merge(channels, fin_img); namedWindow("Red",1); imshow("Red", fin_img); } // Showing Green Channel { vector<Mat> channels; channels.push_back(g); channels.push_back(rgbChannels[1]); channels.push_back(g); merge(channels, fin_img); namedWindow("Green",1); imshow("Green", fin_img); } // Showing Blue Channel { vector<Mat> channels; channels.push_back(rgbChannels[0]); channels.push_back(g); channels.push_back(g); merge(channels, fin_img); namedWindow("Blue",1); imshow("Blue", fin_img); } waitKey(0); return 0; }
Input:
Output:
Here after splitting
the image by split(image,
rgbChannels)
We get three channels of which
· Rgbchannel[0] corresponds to that of “Blue” color
image.
· Rgbchannel[1] corresponds to that of “Green”
color image
· Rgbchannel[2] corresponds to that of “Red” color
image
Since the split function splits the multi-channel image into single
channel ,if we display these channels directly we would get the gray-scale
image of RGB channels.
Thus we need to create a matrix of zeros and push that
into other channels which are not needed.
Mat::zeros(Size(image.cols,
image.rows), CV_8UC1 :
Creates a
matrix of Zeros of single channel whose dimension is same as that of the
original image.
Then we have initialized channels as the vector and
push_back always puts a new element at the end of the vector.
Here the new element is a 8 bit single channel matrix
of Zeros.
The BGR color ordering is the default order of
OpenCV.
Refer:
Thus for displaying the red channels… we need to make
the first two channels as Zeros and create a 3channel image with merge function
to get the colored image.
Similar is the case with other channels of image.