Reputation: 825
I have some code that looks at a directory of white and black images, reads it, resizes it and then pushes into a vector of images. However, when I call the images from the vector, it does not work. It prints out as if both images were white. What am I doing wrong here? Is it vector related?
vector<cv::Mat> images;
vector<cv::String> imageNames;
void prepareData(cv::String &directory)
{
cv::glob(directory, imageNames, false);
cv::Mat colorful, grey, out;
number = imageNames.size();
cout << "Number of images to train on " << number << endl;
for(size_t i = 0; i < number; i++)
{
colorful = cv::imread(imageNames[i]);
cv::resize(colorful, out, cv::Size(5, 5));
cv::cvtColor(out, grey, cv::COLOR_BGR2GRAY);
images.push_back(grey);
cout << grey << endl;
}
for (int i = 0; i < number; ++i)
{
cout << "IMAGE " << i << " " << images[i] << endl;
}
Here is the output I get. The 2 images at first show proper pixel values of the image (23 -> black, 255 -> white), but the second I recall it from the vector, I get that both of my images are white. What am I doing wrong?
Number of images to train on 2
[23, 23, 23, 23, 23;
23, 23, 23, 23, 23;
23, 23, 23, 23, 23;
23, 23, 23, 23, 23;
23, 23, 23, 23, 23]
[255, 255, 255, 255, 255;
255, 255, 255, 255, 255;
254, 254, 255, 255, 255;
254, 255, 255, 255, 254;
255, 255, 255, 255, 255]
IMAGE 0 [255, 255, 255, 255, 255;
255, 255, 255, 255, 255;
254, 254, 255, 255, 255;
254, 255, 255, 255, 254;
255, 255, 255, 255, 255]
IMAGE 1 [255, 255, 255, 255, 255;
255, 255, 255, 255, 255;
254, 254, 255, 255, 255;
254, 255, 255, 255, 254;
255, 255, 255, 255, 255]
Upvotes: 0
Views: 51
Reputation: 20959
Copy operation of cv::Mat
doesn't copy underlying data. cv::Mat
uses reference counter mechanism. When copy is done, ref counter of copied matrix is increased, no data is copied.
Consider the code below:
vector<cv::Mat> vec;
cv::Mat m1;
vec.push_back(m1); // vec[0] refers to m1
some operations on m1
now the printed content of vec[0]
and m1
will be the same.
In for loop you are pushing two new instances of cv::Mat
but they refer to grey
data. So when you are printing contents of vector, you see the last modification on grey
matrix.
Create out
and grey
as local inside for loop:
colorful = cv::imread(imageNames[i]);
cv::Mat out, grey; // <----- added
cv::resize(colorful, out, cv::Size(5, 5));
cv::cvtColor(out, grey, cv::COLOR_BGR2GRAY);
images.push_back(grey);
cout << grey << endl;
Another solution is to use clone method that makes deep copy of cv::Mat
.
Upvotes: 2