保存和加载向量<;Mat>;Qt&;OpenCV
我正在使用不支持更新的FisherFaces识别器在Qt和openCV中进行人脸识别,因此我必须保存人脸数据库,以便在任何更改后重新训练识别器。保存和加载向量<;Mat>;Qt&;OpenCV,qt,opencv,mat,qimage,qdatastream,Qt,Opencv,Mat,Qimage,Qdatastream,我正在使用不支持更新的FisherFaces识别器在Qt和openCV中进行人脸识别,因此我必须保存人脸数据库,以便在任何更改后重新训练识别器。 以下是我的保存代码: save(const std::vector* MatVect){ QFile file("students_dataset.dat"); file.open(QIODevice::WriteOnly); QDataStream out(&file); QVector
以下是我的保存代码:
save(const std::vector* MatVect){
QFile file("students_dataset.dat");
file.open(QIODevice::WriteOnly);
QDataStream out(&file);
QVector qimgvect;
for (size_t i = 0; i < MatVect->size(); ++i)
{
cv::Mat matt = MatVect->at(i);
QImage img((uchar*)matt.data, matt.cols, matt.rows, matt.step, QImage::Format_Indexed8);
qimgvect.push_back(img);
}
out << qimgvect ;
file.flush();
file.close();
}
save(const std::vector*MatVect){
QFile文件(“students_dataset.dat”);
打开(QIODevice::WriteOnly);
QDataStream out(文件(&F);
QVector-qimgvect;
对于(大小i=0;isize();++i)
{
cv::Mat matt=MatVect->at(i);
QImage img((uchar*)matt.data、matt.cols、matt.rows、matt.step、QImage::Format_Indexed8);
qimgvect.推回(img);
}
out>qimgvect;
对于(size_t i=0;i推回(matt);
}
file.close();
返回;
}
问题是我从文件中读取的内容不是我保存的内容那么,这段代码到底有什么错误(希望不是全部错误)?
是否有更好/更简单的方法保存向量?
编辑:
由于Marek\u R的原因,转换部分是固定的,但现在的问题是使用QDataStream保存和加载:
那么是什么导致了这些线条?
编辑:
我已经试过了:
使
QimgVect
公开并元素化QDataStream部分:MatVect->QimgVect比QimgVect->MatVect好用,但添加QDataStream后:MatVect->QimgVect->QDataStream和QDataStream->QimgVect->MatVect我得到了上面显示的结果(垂直白线)。编辑
从qdatastream读取后,将图像从RGB32转换为Indexed8,得到以下结果:
这是内存管理问题。当您从内存块创建矩阵时,不会创建此内存的副本。同时,当
QImage
超出范围时,此内存将被释放
检查关于的答案(评论中有一个更好的链接,但由于某些原因,该页面无法工作,所以我没有在此处提供此链接)
处理cv::Mat
时,只会创建一个浅表副本。不会复制实际的矩阵内容。请参阅:
m–分配给构造矩阵的数组(整体或部分)。这些构造函数不会复制任何数据。
而是构造指向m数据或其子数组的报头
并与之关联。引用计数器(如果有)将递增。
因此,当您修改使用这种构造函数形成的矩阵时
如果希望有一个
子数组的独立副本,使用Mat::clone()
因此,这里有一个解决方案:
通过QDataStream
保存灰度Qimage
将其转换为格式ARGB32
然后保存,加载时将其转换回格式索引8
:
保存代码
QFile file("students_dataset.dat");
file.open(QIODevice::WriteOnly);
QDataStream out(&file);
//converting to ARGB32
foreach (QImage img, qimgvect) {
img = img.convertToFormat(QImage::Format_ARGB32);
}
// saving to QDataStream
out << qimgvect ;
file.flush();
file.close();
QFile文件(“students_dataset.dat”);
打开(QIODevice::WriteOnly);
QDataStream out(文件(&F);
//转换为ARGB32
foreach(QImage img、qimgvect){
img=img.convertToFormat(QImage::Format_ARGB32);
}
//保存到QDataStream
out>qimgvect;
//转换为灰度
矢量灰度;
对于(inti=0;i<256;++i)灰度。追加(qRgb(i,i,i));
对于(inti,i
我认为即使是使用其他格式的
QImage
也会面临同样的问题,因为假设默认格式是format\u ARGB32
左边的图像比右边的图像大,我猜70x70是错误的我尝试了img.width(),img.height()
之前,但我得到了相同的结果,所以我使用了70x70,因为经过一些处理后,所有图像都是70x70。qimgvect.push_back(img)
正在将img
复制到超出范围之前谢谢,这就是问题所在,下面是让我认为它被复制的原因,但是现在我在QDataStream
中遇到了一个新问题,因为我在没有它的情况下测试了代码,它工作正常,请查看编辑
QFile file("students_dataset.dat");
file.open(QIODevice::WriteOnly);
QDataStream out(&file);
//converting to ARGB32
foreach (QImage img, qimgvect) {
img = img.convertToFormat(QImage::Format_ARGB32);
}
// saving to QDataStream
out << qimgvect ;
file.flush();
file.close();
QFile file("students_dataset.dat");
file.open(QIODevice::ReadOnly);
QDataStream in(&file);
QVector<QImage> qimgvect;
// loading images vector from QDatastream
in >> qimgvect;
// converting to grayscale
QVector<QRgb> grayscale;
for (int i = 0; i < 256; ++i) grayscale.append(qRgb(i, i, i));
for (int i, i < qimgvect.size(),i++) {
QImage img = qimgvect.at(i).convertToFormat(QImage::Format_Indexed8,grayscale);
qimgvect.push_back(img);
}
file.close();