Increase the number of rows for a Mat without touching original data

So let's say we have the following code:

// Let's assume imageData represents an image I get as a parameter
unsigned char* imageData;

// Let's also assume that the image represented by imageData is of the exact same size as the parameters we pass to create the mat called x. This means the mat is perfectly filled up.
Mat x(height, width, imageData);


What I want to achieve is to "increase" the numbers of rows in the mat "x", without touching the original data. I tried the resize function but I noticed it stretches the data. So the result is still a mat that is completely filled up. What I want after increasing the number of rows is that the original "height" number of rows still has the imageData untouched, and the newly added rows is empty. I'm experimenting with this due to efficiency. What I have right now is I simply use push_back to append new data to the original Mat to resize it. So I have my original Mat x, then I append a 2nd Mat y (which has the same number of columns as x) to it.

The data I insert into my 2nd Mat y is individually done per cell using the at function, so I was thinking if it was more efficient if I can somehow just increase the number of rows in the original Mat x and use the "at" function on x directly instead of using a temporary Mat y in order to use push_back.

I have also tried this:

// imageData represents an image that has a lower height than the Mat it's being passed to. I assume the bottom set of rows would just be empty, but when I tried to access it near the bottom part I'm getting segmentation fault errors for some reason
Mat x(height * 1.5, width, imageData);

edit retag close merge delete

Have you tried to rotate the mat, push_back and then inverse rotation? I think it is faster... (not sure, verify)

( 2015-06-24 04:24:44 -0500 )edit

Hello thanks for the reply, though I'm confused how rotation would help? I already push_back the 2nd Mat to the original one. What I'm looking for is a way to make it faster (and make my code cleaner), and I have a hunch that it might become so if I can simply increase the size of the original Mat, then insert the new data directly to it without needing a 2nd, temporary Mat. That way, the new data is copied only once, compared to my current method where it's first copied into a temporary Mat, then again copied (via push_back) into the original one.

( 2015-06-24 04:31:49 -0500 )edit

Ahhhh, I never thought of doing a push_back with zeros. I'll test it out and see if it has any significant speed improvements. Thanks!

( 2015-06-24 04:54:07 -0500 )edit

Sort by » oldest newest most voted

Sorry, misread. So you want to increase the number of rows with empty pixels? That is black ones? If so, you can do a x.push_back(cv::Mat::zeros(nRows, x.cols, x.type())).

more

2

hehe, that'll crash ;) (due to this bug )

rather: x.push_back(cv::Mat(nRows, x.cols, x.type(), Scalar::all(0)))

( 2015-06-24 10:05:02 -0500 )edit
1

I did not test it... :D

( 2015-06-24 10:47:01 -0500 )edit

You can take a look at copyMakeBorder. This is probably what you want.

void copyMakeBorder(InputArray src, OutputArray dst, int top, int bottom, int left, int right, int borderType, const Scalar& value=Scalar() )

You just want to increase the number of rows right! So just keep the left and right as 0. The number of rows you want to add either in top or bottom where you want specify them. Since you want those values to be empty, use borderType as BORDER_CONSTANT and fill the value with scalar::all(0). That's it

For assistance, on how to use this api take a look at the tutorial here.

more

I understood that he is searching for a no-copying thing...

( 2015-06-24 09:43:10 -0500 )edit

Thanks for the reply as well, this is certainly something interesting to try out and see which one's faster. Thanks!

( 2015-06-24 20:14:15 -0500 )edit

Stats

Seen: 210 times

Last updated: Jun 25 '15