将cv :: Mat转换为std :: vector而不进行复制 [英] Convert cv::Mat to std::vector without copying
问题描述
我有这个功能:
void foo(cv::Mat &mat){
float *p = mat.ptr<float>(0);
//modify mat values through p
}
我有这段代码会调用该函数:
And I have this code that calls the function:
void bar(std::vector<unsigned char> &vec){
//...
cv::Mat res(m, n, CV_32FC1, (void *)&workspace.front());
}
但是,上面的代码存在性能问题: vec
可能未对齐。实际上,英特尔编译器说引用* out具有未对齐的访问权限
。我希望这是原因。
However, the code above has a performance problem: vec
isn't probably aligned. In fact, the Intel compiler says that reference *out has unaligned access
. I hope that this is the reason.
顺便说一句,我在这个问题, cv :: Mat
将要对齐。因此,一个简单的解决方法是:
Btw, as I found out in this question, cv::Mat
is going to be aligned. So a simple workaround would be to:
- 创建
cv :: Mat res(m,n)
- 调用
foo(m);
- 分配
vec
指向m.ptr< float>(0)
的指针
- Create
cv::Mat res(m,n)
- Call
foo(m);
- Assign the
vec
pointer tom.ptr<float>(0)
正如您可以想象的那样,这里的性能至关重要,因此深层复制是毫无疑问的。
As you can imagine, performance here are crucial, so deep-copies are out of questions.
我尝试了这个问题:
vec = res.data;
但是我遇到了编译器错误。此外,我不知道上面的代码是否要进行(低效的)复制,或者只是通过 vec
更改指向的数据。
But I get a compiler error. Besides, I don't know if this code above is going to do an (inefficient) copy, or just change the pointed data by vec
.
我该如何顺利进行?否则,将意识到另一种解决方法。
How can I do this smoothly? Otherwise, another workaround would be appreciated.
推荐答案
看看此处
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);
}
}
这篇关于将cv :: Mat转换为std :: vector而不进行复制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!