Thursday, 10 December 2015

Splitting and Merging various channels of a color image without using opencv split and merge functions.


This opencv tutorial is about splitting and merging the channels of an image without using opencv split and merge functions:

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



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 Image:
opencv-rgb-image

Output Image:
opencv red channel split image

opencv green channel split image

opencv-blue-channel-split-image

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 Image:
opencv rgb color-mix image

Output Image:
opencv red_channel merge function

opencv green_channel merge function

opencv blue_channel merge function

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.

No comments:

Post a Comment