在 OpenCV 中将 Mat 转换为数组/向量

新手上路,请多包涵

我是 OpenCV 的新手。最近,我很难找到从 Mat 转换为 Array 的 OpenCV 函数。我研究了 OpenCV API 中可用的 .ptr 和 .at 方法,但我无法获得正确的数据。我想直接从 Mat 转换为 Array(如果可用,如果不是 Vector)。我需要 OpenCV 函数,因为代码必须在 Vivado HLS 中进行高级合成。请帮忙。

原文由 Main 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2.3k
2 个回答

如果 Mat mat 的内存是连续的(它的所有数据都是连续的),可以直接把它的数据拿到一维数组中:

 std::vector<uchar> array(mat.rows*mat.cols*mat.channels());
if (mat.isContinuous())
    array = mat.data;

否则,您必须逐行获取其数据,例如二维数组:

 uchar **array = new uchar*[mat.rows];
for (int i=0; i<mat.rows; ++i)
    array[i] = new uchar[mat.cols*mat.channels()];

for (int i=0; i<mat.rows; ++i)
    array[i] = mat.ptr<uchar>(i);


更新: 如果您使用 std::vector 会更容易,您可以这样做:

 std::vector<uchar> array;
if (mat.isContinuous()) {
  // array.assign(mat.datastart, mat.dataend); // <- has problems for sub-matrix like mat = big_mat.row(i)
  array.assign(mat.data, mat.data + mat.total()*mat.channels());
} else {
  for (int i = 0; i < mat.rows; ++i) {
    array.insert(array.end(), mat.ptr<uchar>(i), mat.ptr<uchar>(i)+mat.cols*mat.channels());
  }
}

ps:对于 cv::Mat 其他类型,比如 CV_32F ,你应该这样做:

 std::vector<float> array;
if (mat.isContinuous()) {
  // array.assign((float*)mat.datastart, (float*)mat.dataend); // <- has problems for sub-matrix like mat = big_mat.row(i)
  array.assign((float*)mat.data, (float*)mat.data + mat.total()*mat.channels());
} else {
  for (int i = 0; i < mat.rows; ++i) {
    array.insert(array.end(), mat.ptr<float>(i), mat.ptr<float>(i)+mat.cols*mat.channels());
  }
}


UPDATE2: 对于OpenCV Mat数据的连续性,可以总结如下:

  • imread()clone() 或构造函数创建的矩阵将始终是连续的。
  • 矩阵不连续的唯一情况是它从现有矩阵(即由一个大垫子的投资回报率)。

请查看 此代码片段 以进行演示。

原文由 herohuyongtao 发布,翻译遵循 CC BY-SA 4.0 许可协议

由于上面的答案不像评论中提到的那样准确,但它的“编辑队列已满”,我必须添加正确的单行。

垫(uchar,1通道)到矢量(uchar):

 std::vector<uchar> vec = (image.isContinuous() ? image : image.clone()).reshape(1, 1); // data copy here

向量(任何类型)到 Mat(相同类型):

 Mat m(vec, false); // false(by default) -- do not copy data

原文由 Vit 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题