I have 3 grayscale images that I created using the split function. Now I want to regenerate the color image back. I tried the following code but it did not work. The resultant image I got was still grayscale.
cv::Mat R = cv::imread("/home/r/secret_R.png",0);
cv::Mat G = cv::imread("/home/r/secret_G.png",0);
cv::Mat B = cv::imread("/home/r/secret_B.png",0);
std::vector<cv::Mat> array_to_merge;
array_to_merge.push_back(R);
array_to_merge.push_back(G);
array_to_merge.push_back(B);
cv::Mat color;
cv::merge(array_to_merge, color);
So then I tried the cvtColor function:
cv::Mat color_converted;
cv::cvtColor(color, color_converted, CV_GRAY2BGR);
cv::imwrite("/home/r/color_secret.png",color_converted);
But apparently, it only works for source images that have only a single channel. I passed it one of my grayscale images:
cv::cvtColor(R, color_converted, CV_GRAY2BGR);
But I still could not get a color image back. The resultant image was still grayscale
What am I doing wrong ? How do I get my color image back ?
I can't see anything wrong with your code. I suspect it may be the source data, or how it is being treated by the importer. After you load the images, can you print out the image metadata to see what attributes OpenCV is reading? They all must have the same dimensions and a single channel.
std::cout << "Red: " << R.size().width << " x " << R.size().height << " x " << R.channels() << std::endl;
std::cout << "Green: " << G.size().width << " x " << G.size().height << " x " << G.channels() << std::endl;
std::cout << "Blue: " << B.size().width << " x " << B.size().height << " x " << B.channels() << std::endl;
I just ran your program, just with the headers and main added. I made one small change, to merge in B,G,R order (the default). I compiled it on Mac OS X 10.8 with:
g++ -o merge merge.cpp -lopencv_core -lopencv_highgui
against OpenCV version 2.4.3.
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
int main(int argc, char* argv[])
{
cv::Mat R = cv::imread("chan_dest_red.png", 0);
cv::Mat G = cv::imread("chan_dest_green.png", 0);
cv::Mat B = cv::imread("chan_dest_blue.png", 0);
std::vector<cv::Mat> array_to_merge;
array_to_merge.push_back(B);
array_to_merge.push_back(G);
array_to_merge.push_back(R);
cv::Mat color;
cv::merge(array_to_merge, color);
imwrite("merged.png", color);
return 0;
}
I had some single channel images from another project already split into files, and I just merged those into a single colour image and it worked just fine. The source file info is as follows:
Red: 500 x 333 x 1
Green: 500 x 333 x 1
Blue: 500 x 333 x 1
One way would be to use cvtColor to create a color image from one channel, then replace the other two colors pixel-by-pixel in a loop using the at function. There is probably a way to do this more easily with the matrix operators but I'm not familiar enough with openCV to know for sure.
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