将一行 cv::Mat 转换为 std::vector

2021-12-10 00:00:00 opencv 复制 vector c++

我有一个相当简单的问题:如何取一行 cv::Mat 并获取 std::vector 中的所有数据?cv::Mat 包含 doubles(就问题而言,它可以是任何简单的数据类型).

I have a fairly simple question: how to take one row of cv::Mat and get all the data in std::vector? The cv::Mat contains doubles (it can be any simple datatype for the purpose of the question).

浏览 OpenCV 文档非常令人困惑,除非我将页面添加为书签,否则我无法通过谷歌搜索两次找到文档页面,内容太多且不易导航.

Going through OpenCV documentation is just very confusing, unless I bookmark the page I can not find a documentation page twice by Googling, there's just to much of it and not easy to navigate.

我找到了 cv::Mat::at(..) 来访问 Matrix 元素,但我记得 C OpenCV 中至少有 3 个访问元素的不同方式,所有这些都用于不同的目的......不记得用于哪个:/

I have found the cv::Mat::at(..) to access the Matrix element, but I remember from C OpenCV that there were at least 3 different ways to access elements, all of them used for different purposes... Can't remember what was used for which :/

因此,虽然逐个复制 Matrix 肯定会起作用,但我正在寻找一种更高效的方法,并且如果可能的话,更优雅一些 比每行一个 for 循环.

So, while copying the Matrix element-by-element will surely work, I am looking for a way that is more efficient and, if possible, a bit more elegant than a for loop for each row.

推荐答案

OpenCV 矩阵中的数据按行优先顺序排列,从而保证每一行是连续的.这意味着您可以将一行中的数据解释为普通的 C 数组.以下示例直接来自文档:

Data in OpenCV matrices is laid out in row-major order, so that each row is guaranteed to be contiguous. That means that you can interpret the data in a row as a plain C array. The following example comes directly from the documentation:

// compute sum of positive matrix elements
// (assuming that M is double-precision matrix)
double sum=0;
for(int i = 0; i < M.rows; i++)
{
    const double* Mi = M.ptr<double>(i);
    for(int j = 0; j < M.cols; j++)
        sum += std::max(Mi[j], 0.);
}

因此最有效的方法是将普通指针传递给 std::vector:

Therefore the most efficient way is to pass the plain pointer to std::vector:

// Pointer to the i-th row
const double* p = mat.ptr<double>(i);

// Copy data to a vector.  Note that (p + mat.cols) points to the
// end of the row.
std::vector<double> vec(p, p + mat.cols);

这肯定比使用 begin()end() 返回的迭代器快,因为它们涉及额外的计算来支持行之间的间隙.

This is certainly faster than using the iterators returned by begin() and end(), since those involve extra computation to support gaps between rows.

相关文章