Ask Your Question

Most efficient way to convert std::vector<cv::Mat> to one line cv::Mat?

asked 2017-04-04 07:02:20 -0500

lovaj gravatar image

updated 2017-04-04 07:04:06 -0500

I have a std::vector<cv::Mat1f> mat, where each element is a row matrix. If you wander why, look here.

The only solution that came to my mind is:

cv::Mat1f final;
for(int i=0; i<mat.rows; i++){
    final.push_back( mat[i].row(0) );

Is there any more efficient solution for this?

edit retag flag offensive close merge delete


mat.size(), not mat.rows, right ?

berak gravatar imageberak ( 2017-04-04 08:09:48 -0500 )edit

1 answer

Sort by ยป oldest newest most voted

answered 2017-04-04 08:04:24 -0500

berak gravatar image

updated 2017-04-04 08:07:52 -0500

you could still preallocate it, and copy rows, which would shave off the cost for subsequential allocations triggered from the push_back():

Mat final(mat.size(), mat[0].cols, CV_32F);
for(size_t i=0; i<mat.size(); i++){

also look at hconcat() / vconcat(), though i doubt, that they are cheaper.

edit flag offensive delete link more


@berak thanks for your answer. Am I wrong, but this is going to be expensive? I mean, I thought that push_back was going to be just some operation involving smart pointers, while here we actually copy the data (which could be expensive). Where am I wrong?

lovaj gravatar imagelovaj ( 2017-04-04 08:22:06 -0500 )edit

I thought that push_back was going to be just some operation involving smart pointers

oh, you were wrong about that. remember, that cv::Mat has continuous data storage, (it's not a vector of pointers), so each time you call push_back(), it has todo:

  • allocate a new buffer for n+1 rows
  • copy n existing rows to new buffer
  • copy the row to the last line
  • delete the old buffer
berak gravatar imageberak ( 2017-04-04 08:31:13 -0500 )edit

Question Tools

1 follower


Asked: 2017-04-04 07:02:20 -0500

Seen: 974 times

Last updated: Apr 04 '17