2011-09-20 158 views
1

如何使用尽可能少的复制操作将cv :: gpu :: GpuMat行转移到std :: vector?将GpuMat行复制到std :: vector

我能想到的最快方法是:

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); 

但我什至不知道,如果这个工程,因为fooRow内容都必须对齐......

是否有另(更好)的方式来做到这一点?

回答

3

这里是不会产生任何不必要的复制方法:

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

谢谢!这正是我一直在寻找的:) – Ben

+0

不,对不起。我测试了它,它不起作用。 Mat(vec)使用vec作为初始值,但似乎并未指向vec的数据,因为下载后,vec仍然充满了零。 Mat m; fooGpu.row(i).download(m); vec = m; 的作品,但这又涉及复制。 – Ben

+0

我很确定'Mat(vec)'共享矢量数据,但矢量必须分配给正确的长度('vec.resize(numCols);'是必须的)。如果这个代码不起作用,那么这是一个OpenCV错误,应该在OpenCV错误跟踪器上报告。 –

1

我觉得std::copy更好:

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

注意,第二个参数是:fooRow.data + numCols,而不是fooRow.data + sizeof(float)* numCols。您的代码vec.resize(numRows);似乎不正确。它应该是:

vec.resize(numCols); 

因为fooRow是一列,并拥有numCols数它的值。

+0

随着'back_inserter'调整大小可能不需要和resizings分摊到O(1)无论如何,但我认为一个储备不会是一个坏主意,因为你知道大小。尽管在过早优化的代码中使用干净的代码是一个好主意,但我们不应该给我们比我们更多的东西。 –

+0

@Christian:非常好的一点。取消注释该行。 – Nawaz

+0

你说得对,当然你的代码看起来更好。但我仍然怀疑我是否可以直接访问GpuMat数据。如果不是,我可以假设fooRow数据是一致的吗? – Ben

相关问题