我有一些代码可以查看白色和黑色图像的目录,对其进行读取,调整大小,然后压入图像向量。但是,当我从矢量调用图像时,它不起作用。它像两个图像一样打印出来。我在这里做错了什么?它与向量相关吗?
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;
}
这是我得到的输出。前两张图像显示图像的正确像素值(23->黑色,255->白色),但是第二张图像从向量中回想起,我发现我的两张图像都是白色。我在做什么错了?
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]
答案 0 :(得分:2)
cv::Mat
的复制操作不会复制基础数据。 cv::Mat
使用引用计数器机制。复制完成后,复制矩阵的引用计数器增加,没有数据被复制。
考虑以下代码:
vector<cv::Mat> vec;
cv::Mat m1;
vec.push_back(m1); // vec[0] refers to m1
some operations on m1
现在vec[0]
和m1
的打印内容将是相同的。
在 for 循环中,您正在推送cv::Mat
的两个新实例,但它们引用了grey
数据。因此,在打印矢量内容时,您会在grey
矩阵上看到最后修改。
在 for 循环内在本地创建out
和grey
:
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;
另一种解决方案是使用clone方法复制cv::Mat
的深层副本。