5

I am trying to convert a 1 channel image (16 bit) to a 3 channel image in OpenCV 2.3.1. I am having trouble using the merge function and get the following error:

    Mat temp, tmp2;
    Mat hud;
    tmp2 = cv_ptr->image;
    tmp2.convertTo(temp, CV_16UC1);
    temp = temp.t();
    cv::flip(temp, temp, 1);
    resize(temp, temp, Size(320, 240));
    merge(temp, 3, hud);

error: no matching function for call to ‘merge(cv::Mat&, int, cv::Mat&)’

Can anyone help me with this? Thanks in advance!

keshavdv
  • 315
  • 3
  • 5
  • 10

3 Answers3

16

If temp is the 1 channel matrix that you want to convert to 3 channels, then the following will work:

cv::Mat out;
cv::Mat in[] = {temp, temp, temp};
cv::merge(in, 3, out);

check the Documenation for more info.

Community
  • 1
  • 1
volting
  • 16,773
  • 7
  • 36
  • 54
3

Here is a solution that does not require replicating the single channel image before creating a 3-channel image from it. The memory footprint of this solution is 3 times less than the solution that uses merge (by volting above). See openCV documentation for cv::mixChannels if you want to understand why this works

// copy channel 0 from the first image to all channels of the second image
int from_to[] = { 0,0, 0,1, 0,2}; 
Mat threeChannelImage(singleChannelImage.size(), CV_8UC3);
mixChannels(&singleChannelImage, 1, & threeChannelImage, 1, from_to, 3);
RawMean
  • 8,374
  • 6
  • 55
  • 82
  • 1
    This is a clean and short solution, but it has no advantage over the solution proposed by volting, that was also short, clean and had same memory footprint. Using {temp, temp, temp} does not replicate image 3 times, but it replicate only its header. – Michael Burdinov Jan 16 '14 at 06:48
  • You see the line that says: cv::Mat in[] = {temp temp, temp}; My solution above avoids allocation of memory for in[] which is 3 times the size of the original image. Note that this is in addition to the 3-channel out array that both solutions require. – RawMean Jan 16 '14 at 19:29
  • 4
    The line you mentioned is not allocating memory. It creates 3 matrix headers (few bytes each) that share same image buffer as the image 'temp'. – Michael Burdinov Jan 16 '14 at 19:52
2

It looks like you aren't quite using merge correctly. You need to specify all of the cannels that are to be 'merged'. I think you want a three channel frame, with all the channels identical, in Python I would write this:

cv.Merge(temp, temp, temp, None, hud)

From the opencv documentation:

cvMerge: Composes a multi-channel array from several single-channel arrays or inserts a single channel into the array.

fraxel
  • 34,470
  • 11
  • 98
  • 102