0

我正在使用不支持更新的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;
    } 
问题是我从文件中读回的不是我保存的
已保存 加载

那么这段代码到底有什么问题(希望不是全部)?
有没有更好/更简单的方法来保存向量?
编辑:
感谢Marek_R,转换部分已修复,但现在使用 QDataStream 保存和加载是问题:
已保存 加载
那么是什么导致了这些行?
编辑:
我已经尝试过:
公开QimgVect和元素化 QDataStream 部分:MatVect-> QimgVectQimgVect->MatVect并且它确实工作正常,但是在添加 QDataStream 之后:MatVect-> QimgVect->QDataStreamQDataStream->QimgVect->MatVect i得到上面显示的结果(垂直白线)。
编辑
从 qdatastream 读取后RGB32Indexed8给出以下结果:
在此处输入图像描述

4

2 回答 2

1

这是内存管理问题。当您从一块内存创建矩阵时,不会创建此内存的副本。同时该内存在QImage超出范围时被处理。

检查关于在和之间转换的QImagecv:Mat答案(评论中有一个更好的链接,但由于某种原因页面无法正常工作,所以我没有在此处提供此链接)。

当您应对时,cv::Mat只会创建一个浅拷贝。不复制实际的矩阵内容。请参阅cv::Mat构造函数文档

m – (作为整体或部分)分配给构造矩阵的数组。这些构造函数不会复制任何数据。相反,指向 m 个数据或其子数组的标头被构造并与之关联。引用计数器(如果有)会递增。因此,当您修改使用此类构造函数形成的矩阵时,您也修改了 m 的相应元素。如果要拥有子数组的独立副本,请使用Mat::clone()

于 2014-09-28T08:54:35.180 回答
0

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

于 2014-09-30T10:12:08.920 回答