2017-05-01 62 views
0

我有這樣的功能:轉換CV ::墊到std ::向量不復制

void foo(cv::Mat &mat){ 
    float *p = mat.ptr<float>(0); 
    //modify mat values through p 
} 

而且我有這樣的代碼調用該函數:

void bar(std::vector<unsigned char> &vec){ 
    //... 
    cv::Mat res(m, n, CV_32FC1, (void *)&workspace.front()); 
} 

然而,上面的代碼有一個性能問題:vec不可能對齊。實際上,英特爾編譯器說reference *out has unaligned access。我希望這是原因。

順便說一句,因爲我發現在this的問題,cv::Mat將要對齊。因此,一個簡單的解決方法是:

  1. 創建cv::Mat res(m,n)
  2. 呼叫foo(m);
  3. vec指針分配給m.ptr<float>(0)

你可以想像,表現在這裏是至關重要的,所以深副本沒有問題。

我試過代碼this問題:

vec = res.data; 

但我得到一個編譯錯誤。此外,我不知道上面的代碼是否會執行(低效率)複製,或者只是將指向的數據更改爲vec

我該如何順利地做到這一點?否則,另一個解決方法將不勝感激。

回答

0

看看here

std::vector<uchar> array; 
if (mat.isContinuous()) { 
    array.assign(mat.datastart, mat.dataend); 
} else { 
    for (int i = 0; i < mat.rows; ++i) { 
    array.insert(array.end(), mat.ptr<uchar>(i), mat.ptr<uchar>(i)+mat.cols); 
    } 
} 

//p.s.: For cv::Mats of other types, like CV_32F, you should do like this: 

std::vector<float> array; 
if (mat.isContinuous()) { 
    array.assign((float*)mat.datastart, (float*)mat.dataend); 
} else { 
    for (int i = 0; i < mat.rows; ++i) { 
    array.insert(array.end(), (float*)mat.ptr<uchar>(i), (float*)mat.ptr<uchar>(i)+mat.cols); 
    } 
} 
+0

謝謝您的回答,但恐怕這是要幹什麼元素的深層副本,而不是引用(所以這將是低效)對?換句話說,這將是線性的。 – cplusplusuberalles

+0

對不起,我沒有注意。也許是一個普通的指針數組,我還問過一位也與開放式CV一起工作的朋友,他指出了同樣的方向。 – BlooB