将 Mat 对象推回矢量的安全方法
Safe way to push back Mat objects to a vector
>我有一个虚拟问题,因为发生了一些非常奇怪的事情。我正在尝试将 Mat 对象推送到矢量。例如:
int main()
{
vector<Mat_<float>> a;
Mat M(2,1, CV_32FC1, Scalar(100));
Mat K(2,1, CV_32FC1, Scalar(150));
Mat b;
b=K-M;
a.push_back(b);
b=K+M;
a.push_back(b);
cout<<a[0]<<endl<<endl;
cout<<a[1]<<endl<<endl;
system("pause");
}
这个效果不好.最后,我的向量只包含 b=K+M 垫子。我认为这是意料之中的,因为我每次只push_back标题,如果数据发生变化,这会影响向量中的两个 Mats。如果我改用a.push_back(b).clone,问题就解决了。现在,当我像这样运行代码(将CV_32FC1更改为CV_8UC1):
int main()
{
vector<Mat_<float>> a;
Mat M(2,1, CV_8UC1, Scalar(100));
Mat K(2,1, CV_8UC1, Scalar(150));
Mat b;
b=K-M;
a.push_back(b);
b=K+M;
a.push_back(b);
cout<<a[0]<<endl<<endl;
cout<<a[1]<<endl<<endl;
system("pause");
}
最终向量包含我推回的两个矩阵。这是怎么发生的?也许我也不明白第一种情况到底发生了什么,但我找不到任何其他方法可以在不使用clone()的情况下安全地将Mat对象传递给向量(就像在这种情况下一样)。
将 cv::Mat 类型从 CV_32FC1 更改为 CV_8UC1 不会改变任何东西 - 添加到向量时您仍然做了标头复制。这是意料之中的,也是所期望的。默认情况下,opencv 避免复制整个矩阵数据。如果你想将元素存储在 vector 中,并且它们在值上彼此不同,你必须使用 clone()。这就像一个证明。假设您没有使用 clone(),并且仍然想通过它们的值来区分向量中的矩阵。在我看来,这似乎是一个矛盾。Opencv Mat就像一个智能指针。它存储数据,直到变量的引用计数变为 0。因此,您可以安全地执行以下操作,就像您自己在问题中注意到的那样:
b=K-M;
a.push_back(b.clone());
b=K+M;
a.push_back(b);
在第二种情况下,您正在创建一个应包含 cv::Mat_<float>
类型的元素的std::vector
,但您正在向其中添加 cv::Mat_<unsigned char>
类型的元素。因此,您面临着未定义的行为。
如果要创建类型 CV_8UC1
的矩阵,则应将它们放在 std::vector< cv::Mat_<unsigned char> >
类型的向量中。
您还可以通过使用 cv::Mat
类型而不是 cv::Mat_
来使其成为通用型。
std::vector<cv::Mat> a;
正如他们已经说过的那样,默认情况下 cv::Mat 不复制,而是尽可能多地使用已经分配的数据,在您的代码中 b 被使用了两次。另一种解决方案是直接push_back(K-M)
和(K+M)
,正如您在我的代码中看到的那样。如果你想说清楚,你可以push_back(cv::Mat_<float>(K-M))
只是为了明确你每次都在构建一个新的cv::Mat
。
int main() {
vector<Mat_<float>> a;
Mat M(2, 1, CV_32FC1, Scalar(100));
Mat K(2, 1, CV_32FC1, Scalar(150));
a.push_back(K-M);
a.push_back(K+M);
cout << a[0] << endl << endl;
cout << a[1] << endl << endl;
system("pause");
}
- 将传入的网络"char*"数据转换为"uint8_t"并返回的安全方法是什么?
- 在 c++ 中从执行的 shell 命令获取返回状态的安全方法是什么?
- 在C++线程内实现多个计时器的最安全方法
- 最有效的安全方法将 std::map<int, std::shared_ptr> 转换为 std::<Base>map<int, std::shared_ptr<D
- 重新分配指针阵列的一部分的安全方法
- 将整数添加到数组值而无需调用它的最安全方法
- 使用括号运算符实现矩阵类的安全方法
- 将空隙动态铸造到类型的安全方法?
- C/通过套接字发送time_t的最安全方法
- 交换两个类实例的最安全方法
- 将uint16_t投射到wchar_t的安全方法
- 从字符串中读取溢出双倍作为'inf'的安全方法
- 期货是检查单个线程完成情况的安全方法吗
- 在C++中动态分配向量的安全方法是什么
- 在C++类中构建互斥保护的线程安全方法
- C++和跳出动态生成代码的安全方法
- 这是实现错误处理的安全方法吗
- 将长整数转换为字符数组的最安全方法是什么
- 缓存 PID 到端口映射窗口的安全方法
- 将无符号长整整除以无符号长整型的最安全方法