Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV: Taking a 3 channel RGB image, splitting channels and viewing an image with only R+G

Tags:

I wanted to look at only the R+G channels in an RGB image because I get better contrasts to detect an object when the Blue channel is removed. I used OpenCV to split the channels,but while merging the same after setting the blue channel to 0, my code doesn't compile.

#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream>  using namespace cv; using namespace std;  int main( int argc, char** argv ) {     if( argc != 2)     {      cout <<" Usage: display_image ImageToLoadAndDisplay" << endl;      return -1;     }      Mat image,fin_img;     image = imread(argv[1], 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( "Display window", CV_WINDOW_AUTOSIZE );// Create a window for display.                       // Show our image inside it.      // Create Windows     namedWindow("Red",1);     namedWindow("Green",1);     namedWindow("Blue",1);      // Create Matrices (make sure there is an image in input!)      Mat channel[3];     imshow( "Original Image", image );        // The actual splitting.     split(image, channel);      channel[0]=Mat::zeros(Size(image.rows, image.cols), CV_8UC1);//Set blue channel to 0      //Merging red and green channels      merge(channel,image);     imshow("R+G", image);      waitKey(0);//Wait for a keystroke in the window     return 0; } 

Could I have any feedback on where I'm going wrong? I suspect it is with setting the blue channel to 0. Is there any better way to set it to 0?Is there a way to use cvMixChannels() to do this?

like image 991
Sriharsha Avatar asked Dec 03 '13 02:12

Sriharsha


People also ask

How do I separate RGB channels in OpenCV?

In OpenCV, BGR sequence is used instead of RGB. This means the first channel is blue, the second channel is green, and the third channel is red. To split an RGB image into different channels, we need to define a matrix of 3 channels. We use 'Mat different_Channels[3]' to define a three-channel matrix.


Video Answer


2 Answers

You need to change these lines

    channel[0]=Mat::zeros(Size(image.rows, image.cols), CV_8UC1);//Set blue channel to 0      //Merging red and green channels     merge(channel,image); 

to

    channel[0]=Mat::zeros(image.rows, image.cols, CV_8UC1);//Set blue channel to 0      //Merging red and green channels     merge(channel,3,image); 

Edit

As per your comment here is the full code and result.

#include <iostream> #include "opencv2/opencv.hpp" #include <stdio.h>      using namespace cv; using namespace std;  int main( int argc, char** argv ) {     if( argc != 2)     {      cout <<" Usage: display_image ImageToLoadAndDisplay" << endl;      return -1;     }      Mat image,fin_img;     image = imread("bgr.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( "Display window", CV_WINDOW_AUTOSIZE );// Create a window for display.                       // Show our image inside it.      // Create Windows     namedWindow("Red",1);     namedWindow("Green",1);     namedWindow("Blue",1);      // Create Matrices (make sure there is an image in input!)      Mat channel[3];     imshow( "Original Image", image );       // The actual splitting.     split(image, channel);      channel[0]=Mat::zeros(image.rows, image.cols, CV_8UC1);//Set blue channel to 0      //Merging red and green channels      merge(channel,3,image);     imshow("R+G", image);     imwrite("dest.jpg",image);      waitKey(0);//Wait for a keystroke in the window     return 0; } 

Source image

enter image description here

Result without blue component

enter image description here

like image 87
Haris Avatar answered Sep 24 '22 00:09

Haris


Alright, I got to work using mixChannels():I have attached an addition to the code snippet above:

Mat gr( image.rows, image.cols, CV_8UC3);  // forming an array of matrices is a quite efficient operation, // because the matrix data is not copied, only the headers    Mat out[] = {gr}; // bgr[1] -> gr[1], // bgr[2] -> gr[2],  int from_to[] = {1,1, 2,2 }; mixChannels( &image, 1, out, 2, from_to, 2 );  imshow("R+G",gr); 

Thanks Harsha

like image 36
Sriharsha Avatar answered Sep 21 '22 00:09

Sriharsha