将 Vector<float> 中的数据复制到 Vector<Mat> (Opencv/C++)

Posted

技术标签:

【中文标题】将 Vector<float> 中的数据复制到 Vector<Mat> (Opencv/C++)【英文标题】:Copy data in Vector<float> to Vector<Mat> (Opencv/C++) 【发布时间】:2016-01-23 14:58:53 【问题描述】:

在 C++ 中,我有以下代码。我正在尝试将存储在向量中的数据复制到矩阵中(在向量内)。我试过这样做:

Vector<float> vec;
// Let's imagine that vec contains 10 float values: 1,2,3 ...., 10
// I'd like to copy those numbers into a Mat variable 
Vector<Mat> myMats;
myMats.push_back(Mat(2,5,CV_32FC1,&vec.front()));

它有效。但是!当修改向量“vec”上的内容并尝试将其插入到我的 Mat 向量中的另一个位置时,它们都获得了最后一个“push_back”操作的值。 “myMats”中的所有条目都被最后一个条目覆盖。我该如何解决这个问题?

我认为问题在于使用每次修改地址的引用(“&”),在哪里查找。

【问题讨论】:

为什么要推送临时对象的地址? 是的,刚刚编辑了我提到的问题。我第一次就这样搞定了,后来修改代码不知道怎么弄。 另外,我不清楚你想做什么。请描述现在正在发生的事情以及您想要实现的目标。 【参考方案1】:

好的。我已经知道怎么做(创建一个临时垫)

Mat temp_;
temp_ = Mat(2,5,CV_32FC1,&vec.front());
myMats.push_back(temp_.clone());

我想有一种更有效的方法,但这没问题。

【讨论】:

如果可能,请接受您自己的答案。之所以必须克隆,是因为这个 Mat 构造函数只是使用数据指针,而不是分配自己的内存。【参考方案2】:

OP已经自己解决了。但是,如果以后有人提出这个问题,这是一些澄清。

cv::Mat 是一个带有指向实际数据的指针的容器。当您像这样创建cv::Mat 时:

cv::Mat some_mat;

cv::Mat 在堆栈中创建,它将通过在其结构中保留一个指针来指向堆中的数据。当您像这样使用其复制构造函数/分配复制cv::Mat 时:

cv::Mat another_mat=some_mat;

或者这个:

some_vector_of_mats.push_back(some_mat);

会发生浅拷贝。换言之,cv::Mat 的标头(行数和列数,类型...)将被深度复制,而指向实际数据的指针将被浅复制。但不会复制实际数据。那么在 OP 案例中发生了什么,每次将 cv::Mat 推送到向量时,都会发生浅拷贝。复制的指针没有改变它的值。所以,所有的 cv::Mat 都指向同一个地方。因此导致其中一个数据的任何变化都会影响其他数据。

【讨论】:

以上是关于将 Vector<float> 中的数据复制到 Vector<Mat> (Opencv/C++)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 .NET 中将 Vector128<float> 转换为 Vector128<int>?

在 C++ 中将 vector<Rect> OpenCV 转换为 vector<vector<float>>

如何使用 Eigen 从 vector<vector<float>> 创建矩阵? [复制]

如何使用可变长度类型将包含多个 std::vector<float> 的结构写出到 HDF5?

处理 vector<vector<float>> 的 size() 时,vector<vector<float>>::size_type 还是 vect

从 std::vector<std::vector<float>> 转换为 float**