2011-09-20 35 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

相關問題