将一行cv::Mat转换为std::vector
Converting a row of cv::Mat to std::vector
我有一个相当简单的问题:如何获取cv::Mat
的一行并获取std::vector
中的所有数据?cv::Mat
包含doubles
(就问题而言,它可以是任何简单的数据类型)。
浏览OpenCV文档是非常令人困惑的,除非我将页面加上书签,否则我无法通过谷歌两次找到文档页面,因为文档太多了,不容易导航。
我已经找到了访问矩阵元素的cv::Mat::at(..)
,但我记得从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 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 mat"可以直接找到基本类型的文档,根据这一点,这应该很好。
矩阵迭代器是随机访问迭代器,因此它们可以传递给任何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);
意味着您将从左上角为(x0,y0)
、大小为(len_x, len_y)
的matrix
中获得sub_matrix
。(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));
- 将 cv::mat 转换为 QImage
- 将 cv::Mat 转换为 std::vector 的通用函数
- 如何将 cv::Mat 转换为 vtkImageData?
- Qt-工作线程崩溃时将cv::Mat转换为QImage
- 将 cv::Mat 转换为无符号的 int 像素
- 如何在不复制数据的情况下将 cv::Mat 转换为 2d 标准::矢量
- 转换 cv::mat 转换为 std::矢量<double>并发症
- 将CV :: MAT转换为STD :: vector而无需复制
- 如何将cv::Mat转换为带有颜色的pcl::点云
- 将 cv::Mat 转换为穿山甲::图像
- c++ OpenCV:将mat转换为base64,反之亦然
- 将 OpenCV Mat 转换为 array(可能是 NSArray)
- 如何在OpenCV 3.0中将Mat转换为cvMat
- 如何将'cv::Mat'转换为"双倍"?
- Lib-svm,如何将MyModel.mat转换为MyModel.model
- 如何将简历::Mat转换为简历::Rect
- 错误 C2664:'cvSaveImage':无法将参数 2 从 'cv::Mat' 转换为 'const CvArr *'
- OpenCV表单应用程序 - 将Mat转换为灰度
- OpenCV:将 Mat 转换为 UChar4
- 使用 QImage::loadFromData 将 cv::mat 转换为 QImage