将cv :: Mat转换为std :: vector而不复制

时间:2017-05-01 21:34:15

标签: c++ opencv vector alignment mat

我有这个功能:

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)
  4. 你可以想象,这里的表现是至关重要的,所以深层复制不是问题。

    我在this问题中尝试了代码:

    vec = res.data;
    

    但是我收到编译错误。此外,我不知道上面的代码是否会进行(低效)复制,或只是通过vec更改指向的数据。

    我怎样才能顺利完成这项工作?否则,将赞赏另一种解决方法。

1 个答案:

答案 0 :(得分: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);
  }
}