Merging three grayscale [R, G, B] images into a single color image in opencv

21,566

Solution 1

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

Solution 2

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.

Share:
21,566
Chani
Author by

Chani

Air of mystery

Updated on April 05, 2020

Comments

  • Chani
    Chani about 4 years

    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 ?