我正在使用不支持更新的FisherFaces识别器在Qt和openCV中进行人脸识别,因此我必须保存面部数据库以在进行任何更改后重新训练识别器。
这是我保存的代码:
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; }
问题是我从文件中读取的不是我保存的
那么,这段代码到底有什么错(希望不是全部)?
有没有更好/更容易的方法来保存 vector ?
编辑:
多亏了 Marek_R ,转换部分是固定的,但是现在用QDataStream保存和加载是一个问题:
那么是什么原因导致这些线路?
编辑:
我已经试过了
将QimgVect
公开并声明为QDataStream部分: MatVect-> QimgVect 比 QimgVect-> MatVect 确实工作正常,但是在添加QDataStream之后: MatVect-> QimgVect-> QDataStream ojit_r 我得到上面显示的结果(垂直白线)。
编辑
从qdatastream读取后,将图像从 RGB32 转换为 Indexed8 会得到以下结果:
最佳答案
这是内存管理问题。当您从一块内存创建矩阵时,不会创建此内存的副本。同时,当QImage
超出范围时,将处理此内存。
检查有关converting between QImage
and cv:Mat
的答案(评论中有一个更好的链接,但由于某些原因页面无法正常工作,因此我在此处未提供此链接)。
当您处理cv::Mat
时,只会创建一个浅拷贝。实际的矩阵内容不会被复制。参见 cv::Mat
constructor documentation: