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
  • 4,167
  • 3
  • 25
  • 30
Moataz Elmasry
  • 2,509
  • 4
  • 27
  • 37

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
  • 4,167
  • 3
  • 25
  • 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
  • 94,801
  • 28
  • 188
  • 263
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
  • 92,053
  • 36
  • 243
  • 426