问题描述
我有一个相当简单的问题:如何取一行 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.
这篇关于将一行 cv::Mat 转换为 std::vector的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!