Ben
Ben

Reputation: 4666

Copying a GpuMat row to a std::vector

How can I transfer cv::gpu::GpuMat rows to std::vector with as little as possible copy operations?

The fastest way I can think of is:

GpuMat fooGpu(numRows, numCols, CV_32FC1);
Mat foo = fooGpu;

Mat fooRow = foo.row(i);

std::vector<float> vec;
vec.resize(numCols);

memcpy(&vec[0], fooRow.data, sizeof(float)*numCols);

But I'm not even sure if this works, because the fooRow content would have to be aligned...

Is there another (better) way to do it?

Upvotes: 1

Views: 1988

Answers (2)

Andrey Kamaev
Andrey Kamaev

Reputation: 30122

Here is the method that does not produce any unnecessary copying:

GpuMat fooGpu(numRows, numCols, CV_32FC1);
std::vector<float> vec;
vec.resize(numCols);
fooGpu.row(i).download(Mat(vec).reshape(1/*channels*/, 1/*rows*/));

Upvotes: 3

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361442

I think std::copy is better:

std::vector<float> vec;
vec.resize(numCols); 
std::copy(fooRow.data, fooRow.data + numCols, vec.begin());

Note that the second argument is : fooRow.data + numCols, as opposed to fooRow.data + sizeof(float)* numCols.

Also, in your code vec.resize(numRows); doesn't seem to be correct. It should be :

 vec.resize(numCols);

Because fooRow is ONE row, and hasnumCols number of values in it.

Upvotes: 1

Related Questions