Std :: vector does not create a new cv :: Mat reference for more than one vector record - data becomes redundant when initializing matrices
So here's what I came across that really bothered me and made me try to figure out why it works like this:
If you have the following super simplifying error code just to show an example:
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;
}
Printout:
[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]
Why is the same reference used for different vector records? I am forced to create different matrices separately, rather than create them together with the vector itself.
Is there a way to avoid this?
thank
source to share
The problem is that it cv::Mat
has referential semantics, so copying objects cv::Mat
results in copies sharing the data with the original. So by initializing the vector this way
std::vector<cv::Mat> newData(N, a_cv_mat);
will cause the vector containing N cv::Mat
to share the same data as a_cv_mat
.
To avoid having objects cv::Mat
referencing the same data, you can initialize the vector using the parenthesized initialization list:
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)};
If you don't know the number of elements at compile time, you can put them into a vector one at a time:
std::vector<cv::Mat> newData
newData.emplace_back(height, width, cv::DataType<T>::type);
If you don't have C ++ 11 support, you can push each matrix into a vector:
std::vector<cv::Mat> newData
newData.push_back(cv::Mat(height, width, cv::DataType<T>::type));
source to share