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?
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.
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
Result without blue component
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With