9

I have a couple of images in Mat objects all with same dimensions I'd like to create one bix cv::Mat object to hold them all

So the dimension of the new matrix is: widthNew = widthOld x number of matrices, height remains unchanged.

I found that such a copy could be done using:

void cvCopy(const CvArr* src, CvArr* dst, const CvArr* mask=NULL)

but then, how could the mask be defined three different times for the three matrices?.

Regards, Moataz

Angie Quijano
  • 3,799
  • 3
  • 22
  • 30
Moataz Elmasry
  • 2,449
  • 4
  • 26
  • 35

3 Answers3

14

I think there is an easy way to do this. OpenCV has a not documented methods called hconcat() and vconcat(). The first one is for horizontal concatenation and the second one for vertical concatenation.

You can use them in this way:

Mat A, B;
... //In this part you initialize the Mat A and Mat B.

Mat H, V; //These are the destination matrices
hconcat(A, B, H);
vconcat(A, B, V);

I hope this can help.

Angie Quijano
  • 3,799
  • 3
  • 22
  • 30
  • The destination can be the same as one of the sources so `vconcat(out, out1, out); vconcat(out, out2, out);` worked well for me in a multithreaded context (for combining output from individual threads). – Izaan Aug 13 '17 at 14:53
6

You use an roi to define an image which is actually a region of the destination image and then copy to that. see Copy an cv::Mat inside a ROI of another one

Community
  • 1
  • 1
Martin Beckett
  • 92,791
  • 27
  • 183
  • 258
1

You probably want to take look at the source code of cvShowManyImages(), which is a function that takes several images as input and concatenates them into a single 3-channel image to be displayed:

The method used is to set the ROIs of a Single Big image and then resizing and copying the input images on to the Single Big Image.

If you create a destination image big enough to hold your other images, you won't need to resize them.

If you want to know how to convert between IplImage <-> cv::Mat, check this thread.

karlphillip
  • 89,883
  • 35
  • 240
  • 408