Thursday 5 May 2016

OpenCV C++ Code for Split and Merge -II

In the previous tutorial we split the R,G,B channels of a color image using opencv's function called split().


Refer this article:
http://opencv-code.blogspot.in/2016/12/how-to-split-color-images-merge-single-channel-images-opencv-tutorials.html


First of all why there is a need to split the channels of a color image?
As explained in the previous articles it helps us to guess the individual contribution of the respective channel in the color image.Also it has other application like object detection based on color recogntion i.e we can select a green object from the background and track it.


So the process of splitting color images without using split() function in opencv is as shown below:

// OpenCV Channel Splitting  Tutorial 
#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <iostream>
 
using namespace cv;
using namespace std;
 
int main()
{
 const float pi=3.14;
 Mat src1,src2,src3,src4,src5;
 src1 = imread("C:\\Users\\arjun\\Desktop\\opencv.png",CV_LOAD_IMAGE_COLOR);
 src2 = Mat::eye(src1.rows,src1.cols, CV_8UC1);
 src3 = Mat::eye(src1.rows,src1.cols, CV_8UC1);
 src4 = Mat::eye(src1.rows,src1.cols, CV_8UC1);
  
 if( !src1.data ) { printf("Error loading src1 \n"); return -1;}
 
for (int i=0; i<src1.cols ; i++){
for (int j=0 ; j<src1.rows ; j++)
 { 
Vec3b color1 = src1.at<Vec3b>(Point(i,j));
Scalar color2 = src2.at<uchar>(Point(i,j));
Scalar color3 = src3.at<uchar>(Point(i,j));
Scalar color4 = src4.at<uchar>(Point(i,j));
 
      color2.val[0]=color1.val[0]; //Blue channel
    
   color3.val[0]=color1.val[1];  //Green Channel
 
   color4.val[0]=color1.val[2];  //Red Channel
     
   src2.at<uchar>(Point(i,j)) = color2.val[0];
   src3.at<uchar>(Point(i,j)) = color3.val[0];
   src4.at<uchar>(Point(i,j)) = color4.val[0];
  }
 }
namedWindow("Original Image",CV_WINDOW_AUTOSIZE); 
imshow("Original Image", src1);
 
namedWindow("Red Channel Image",CV_WINDOW_AUTOSIZE); 
imshow("Red Channel Image", src4);
imwrite("C:\\Users\\arjun\\Desktop\\opencv-red.png",src4);
 
namedWindow("Green Channel Image",CV_WINDOW_AUTOSIZE); 
imshow("Green Channel Image", src3); 
imwrite("C:\\Users\\arjun\\Desktop\\opencv-green.png",src3);
 
namedWindow("Blue Channel Image",CV_WINDOW_AUTOSIZE); 
imshow("Blue Channel Image", src2); 
imwrite("C:\\Users\\arjun\\Desktop\\opencv-blue.png",src2);
 
 waitKey(0);
 return 0;
}



Input:


Output:
Red:

Green:

Blue:



Similarly the process of merging the channels in opencv again so that only individual color channels are displayed can be done as:
// OpenCV Channel Merging  Tutorial 
#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <iostream>
 
using namespace cv;
using namespace std;
 
int main()
{
 const float pi=3.14;
 Mat src1,src2,src3,src4,src5;
 src1 = imread("C:\\Users\\arjun\\Desktop\\opencv.png",CV_LOAD_IMAGE_COLOR);
 src2 = Mat::eye(src1.rows,src1.cols, CV_8UC3);
 src3 = Mat::eye(src1.rows,src1.cols, CV_8UC3);
 src4 = Mat::eye(src1.rows,src1.cols, CV_8UC3);
  
 if( !src1.data ) { printf("Error loading src1 \n"); return -1;}
 
for (int i=0; i<src1.cols ; i++){
for (int j=0 ; j<src1.rows ; j++)
 { 
Vec3b color1 = src1.at<Vec3b>(Point(i,j));
Vec3b color2 = src2.at<Vec3b>(Point(i,j));
Vec3b color3 = src3.at<Vec3b>(Point(i,j));
Vec3b color4 = src4.at<Vec3b>(Point(i,j));
 
      color2.val[0]=color1.val[0]; //Blue channel
   color2.val[1]=0;
   color2.val[2]=0;
 
   color3.val[0]=0;             //Green Channel
   color3.val[1]=color1.val[1];
   color3.val[2]=0;
 
   color4.val[0]=0;             //Red Channel
   color4.val[1]=0;
   color4.val[2]=color1.val[2];
     
   src2.at<Vec3b>(Point(i,j)) = color2;
   src3.at<Vec3b>(Point(i,j)) = color3;
   src4.at<Vec3b>(Point(i,j)) = color4;
  }
 }
namedWindow("Original Image",CV_WINDOW_AUTOSIZE); 
imshow("Original Image", src1);
 
namedWindow("Red Channel Image",CV_WINDOW_AUTOSIZE); 
imshow("Red Channel Image", src4);
imwrite("C:\\Users\\arjun\\Desktop\\opencv-red.png",src4);
 
namedWindow("Green Channel Image",CV_WINDOW_AUTOSIZE); 
imshow("Green Channel Image", src3); 
imwrite("C:\\Users\\arjun\\Desktop\\opencv-green.png",src3);
 
namedWindow("Blue Channel Image",CV_WINDOW_AUTOSIZE); 
imshow("Blue Channel Image", src2); 
imwrite("C:\\Users\\arjun\\Desktop\\opencv-blue.png",src2);
 
 waitKey(0);
 return 0;
}



Input:

Output:
Red:

Green:

Blue:



Note the difference between the two codes:
In channel splitting we have taken 8UC1 i.e a 8 bit unsigned single channel image.
In channel merging we have taken 8UC3 i.e a 8 bit unsigned three channel image.