在 OpenCV 中将 Mat 转换为数组/矢量 [英] Convert Mat to Array/Vector in OpenCV
问题描述
我是 OpenCV 的新手.最近,我在寻找 OpenCV 函数以将 Mat 转换为 Array 时遇到了麻烦.我研究了 OpenCV API 中可用的 .ptr 和 .at 方法,但我无法获得正确的数据.我想要从 Mat 到 Array 的直接转换(如果可用,如果不是 Vector).我需要 OpenCV 函数,因为代码必须在 Vivado HLS 中进行高级综合.请帮忙.
I am novice in OpenCV. Recently, I have troubles finding OpenCV functions to convert from Mat to Array. I researched with .ptr and .at methods available in OpenCV APIs, but I could not get proper data. I would like to have direct conversion from Mat to Array(if available, if not to Vector). I need OpenCV functions because the code has to be undergo high level synthesis in Vivado HLS. Please help.
推荐答案
如果Mat mat
的内存是连续的(它的所有数据都是连续的),可以直接把它的数据变成一维数组:
If the memory of the Mat mat
is continuous (all its data is continuous), you can directly get its data to a 1D array:
std::vector<uchar> array(mat.rows*mat.cols*mat.channels());
if (mat.isContinuous())
array = mat.data;
否则,您必须逐行获取其数据,例如到二维数组:
Otherwise, you have to get its data row by row, e.g. to a 2D array:
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
会更容易,您可以这样做:
UPDATE: It will be easier if you're using std::vector
, where you can do like this:
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
,你应该这样做:
p.s.: For cv::Mat
s 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); // <- 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数据连续性,可以总结如下:
UPDATE2: For OpenCV Mat data continuity, it can be summarized as follows:
- 由
imread()
、clone()
或构造函数创建的矩阵将始终是连续的. - 矩阵不连续的唯一时间是它从现有矩阵(即,借用的数据在大矩阵中是连续的,例如 1. 单行;2. 具有完整原始宽度的多行)借用数据时根据大垫子的投资回报率创建).
- Matrices created by
imread()
,clone()
, or a constructor will always be continuous. - The only time a matrix will not be continuous is when it borrows data (except the data borrowed is continuous in the big matrix, e.g. 1. single row; 2. multiple rows with full original width) from an existing matrix (i.e. created out of an ROI of a big mat).
请查看此代码片段进行演示.
这篇关于在 OpenCV 中将 Mat 转换为数组/矢量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!