Geo*_*lov 4 c++ opencv vector matrix
所以我遇到了一些让我非常困扰的事情,让我试着弄清楚为什么它会这样工作:
如果有以下超级简单、容易出错的代码只是为了展示一个例子:
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;
}
Run Code Online (Sandbox Code Playgroud)
打印:
[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]
Run Code Online (Sandbox Code Playgroud)
为什么不同的向量条目使用相同的引用? 我被迫分别创建不同的矩阵,而不是与向量本身一起创建它们。
有没有办法避免这种情况?
谢谢
问题在于它cv::Mat
具有引用语义,因此复制cv::Mat
对象会导致副本与原始副本共享数据。因此以这种方式初始化向量
std::vector<cv::Mat> newData(N, a_cv_mat);
Run Code Online (Sandbox Code Playgroud)
将导致包含 Ncv::Mat
的向量都与 共享相同的数据a_cv_mat
。
为了避免cv::Mat
对象引用相同的数据,您可以使用大括号括起来的初始化列表来初始化向量:
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)};
Run Code Online (Sandbox Code Playgroud)
如果你在编译时不知道元素的数量,你可以将它们一一放入向量中:
std::vector<cv::Mat> newData
newData.emplace_back(height, width, cv::DataType<T>::type);
Run Code Online (Sandbox Code Playgroud)
如果您没有 C++11 支持,您可以将每个矩阵推入向量中:
std::vector<cv::Mat> newData
newData.push_back(cv::Mat(height, width, cv::DataType<T>::type));
Run Code Online (Sandbox Code Playgroud)