我在Qt& amp; openCV使用FisherFaces识别器,它不支持更新,所以我必须保存faces数据库,以便在任何更改后重新训练识别器。
这是我保存的代码:
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();
}
这是用于加载:
load(std::vector* MatVect)
{
QFile file("students_dataset.dat");
file.open(QIODevice::ReadOnly);
QDataStream in(&file);
QVector qimgvect;
in >> qimgvect;
for (size_t i = 0; i < qimgvect.size(); ++i)
{
QImage img = qimgvect.at(i);
cv::Mat matt = cv::Mat(70, 70, CV_8U, img.bits(), img.bytesPerLine());
MatVect->push_back(matt);
}
file.close();
return;
}
问题是我从文件中读回的不是我保存的内容
那么这段代码究竟出了什么问题(希望不是全部)?
是否有更好/更简单的方法来保存向量?
编辑:
感谢 Marek_R ,转换部分已修复,但现在保存和加载QDataStream是问题:
是什么导致这些线?
编辑:
我试过这个:
使QimgVect
公共和最终的QDataStream部分: MatVect-&gt; QimgVect 比 QimgVect-&gt; MatVect 并且它确实工作正常,但在添加QDataStream之后: MatVect-&gt; QimgVect-&gt; QDataStream 和 QDataStream-&gt; QimgVect-&gt; MatVect 我得到上面显示的结果(垂直白线)。
的修改
从qdatastream读取后,将图像从 RGB32 转换为 Indexed8 会产生以下结果:
答案 0 :(得分:1)
这是内存管理问题。当您从内存块创建矩阵时,不会创建此内存的副本。同时,当QImage
超出范围时,将释放此内存。
检查有关converting between QImage
and cv:Mat
的答案(评论中有更好的链接但由于某种原因页面无效,所以我在此处未提供此链接。)
当你处理cv::Mat
时,只创建一个浅拷贝。不复制实际矩阵内容。见cv::Mat
constructor documentation:
m - 将(作为整体或部分)分配给构造矩阵的数组。 这些构造函数不会复制任何数据。 而是构造指向m数据或其子数组的头 并与之相关联。参考计数器(如果有)递增。 所以,当你修改使用这样的构造函数形成的矩阵时,你 还修改了m的相应元素。 如果你想要一个 子阵列的独立副本,使用
Mat::clone()
答案 1 :(得分:0)
SO这是一个解决方案:
要保存灰度Qimage
到QDataStream
,请将其转换为Format_ARGB32
然后保存,以便将其转换回Format_Indexed8
:
保存代码
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();
我认为即使QImage
其他格式也会遇到同样的问题,因为我们假设默认格式为Format_ARGB32