gpt4 book ai didi

c++ - std::vector 不会为多个 vector 条目创建 cv::Mat 的新引用 - 初始化矩阵时数据会被覆盖

转载 作者:太空狗 更新时间:2023-10-29 20:58:51 27 4
gpt4 key购买 nike

所以我遇到了一些真正困扰我的事情,让我试着弄清楚为什么它会这样工作:

如果有以下 super 简单、容易出错的代码只是为了展示一个例子:

std::vector<cv::Mat> newData(3,cv::Mat(height, width, cv::DataType<T>::type));

int counter = 0;
for(int b=0; b<3; b++){
for(int i=0; i<3; i++){
for(int j=0; j<3; j++){
newData[b].at<int>(i,j) = counter++;
std::cout << newData[b].at<T>(i,j) << std::endl;
}
}
}

for(int b=0; b<3; b++){
std::cout << newData[b] << std::endl;
}

打印输出:

[18, 19, 20;
21, 22, 23;
24, 25, 26]
[18, 19, 20;
21, 22, 23;
24, 25, 26]
[18, 19, 20;
21, 22, 23;
24, 25, 26]

为什么不同的 vector 条目使用相同的引用?我被迫分别创建不同的矩阵,而不是将它们与 vector 本身一起创建。

有没有办法避免这种情况?

谢谢

最佳答案

问题在于 cv::Mat 具有引用语义,因此复制 cv::Mat 对象会导致拷贝与原始对象共享数据。从而以这种方式初始化一个 vector

std::vector<cv::Mat> newData(N, a_cv_mat);

将导致包含 N 个 cv::Mat 的 vector 都共享与 a_cv_mat 相同的数据。

为避免 cv::Mat 对象引用相同的数据,您可以使用大括号括起来的初始化列表来初始化 vector :

std::vector<cv::Mat> newData{cv::Mat(height, width, cv::DataType<T>::type),
cv::Mat(height, width, cv::DataType<T>::type),
cv::Mat(height, width, cv::DataType<T>::type)};

如果在编译时不知道元素的个数,可以将它们一个一个的emplace到vector中:

std::vector<cv::Mat> newData
newData.emplace_back(height, width, cv::DataType<T>::type);

如果您没有 C++11 支持,您可以将每个矩阵插入 vector 中:

std::vector<cv::Mat> newData
newData.push_back(cv::Mat(height, width, cv::DataType<T>::type));

关于c++ - std::vector 不会为多个 vector 条目创建 cv::Mat 的新引用 - 初始化矩阵时数据会被覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26315928/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com