[英]Converting a row of cv::Mat to std::vector
我有一个相当简单的问题:如何获取一行cv::Mat
并获取std::vector
所有数据? cv::Mat
包含doubles
(对于问题,它可以是任何简单的数据类型)。
浏览OpenCV文档非常令人困惑,除非我将页面标记为Googling两次找不到文档页面,其中大部分内容并不容易导航。
我找到了cv::Mat::at(..)
来访问Matrix元素,但我记得从C OpenCV
开始,至少有3种不同的方式来访问元素,所有这些方法都用于不同的目的......可以不记得用于哪个:/
因此,虽然逐个元素复制Matrix肯定会起作用,但我正在寻找一种更有效的方法,如果可能的话,比每行的for循环更优雅一些。
应该这么简单:
m.row(row_idx).copyTo(v);
其中m
是具有CV_64F
深度的cv::Mat
,而v
是std::vector<double>
OpenCV矩阵中的数据按行主顺序排列,因此每行保证是连续的。 这意味着您可以将行中的数据解释为普通C数组。 以下示例直接来自文档 :
// 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
:
// 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()
返回的迭代器更快,因为这些涉及额外的计算以支持行之间的间隙。
从这里的文档中,你可以通过cv::Mat::row
得到一个特定的行,它将返回一个新的cv::Mat
,你可以使用cv::Mat::begin
和cv::Mat::end
进行迭代cv::Mat::end
。 因此,以下应该有效:
cv::Mat m/*= initialize */;
// ... do whatever...
cv::Mat first_row(m.row(0));
std::vector<double> v(first_row.begin<double>(), first_row.end<double>());
请注意,我不知道任何OpenCV,但谷歌搜索“OpenCV垫”直接导致基本类型文档,并据此,这应该工作正常。
矩阵迭代器是随机访问迭代器,因此可以将它们传递给任何STL算法,包括std :: sort()。
这也来自文档化,因此您实际上可以在没有副本的情况下执行此操作:
cv::Mat m/*= initialize */;
// ... do whatever...
// first row begin end
std::vector<double> v(m.begin<double>(), m.begin<double>() + m.size().width);
要访问超过第一行,我建议使用第一个代码段,因为它会更加清晰,并且似乎没有任何繁重的复制,因为数据类型似乎是引用计数的。
你也可以使用cv::Rect
m(cv::Rect(0, 0, 1, m.cols))
会给你第一排。
matrix(cv::Rect(x0, y0, len_x, len_y);
意味着你将从matrix
获得sub_matrix
,其左上角是(x0,y0)
,大小是(len_x, len_y)
。 (row,col)
我觉得这很有效,
一个例子 :
Mat Input(480, 720, CV_64F, Scalar(100));
裁剪矩阵的第一行:
Rect roi(Point(0, 0), Size(720, 1));
然后:
std::vector<std::vector<double> > vector_of_rows;
vector_of_rows.push_back(Input(roi));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.