Сохранение и загрузка вектора<Mat> Qt & OpenCV

Я работаю над распознаванием лиц в Qt & openCV, используя распознаватель FisherFaces, который не поддерживает обновление, поэтому мне нужно сохранить базу данных лиц, чтобы переучить распознаватель после любых изменений.
Вот мой код для сохранения:

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 public и elemenated часть QDataStream: MatVect-> QimgVect, чем QimgVect->MatVect, и она работала нормально, но после добавления QDataStream: MatVect-> QimgVect-> QDataStream и QDataStream->QimgVect->MatVect я получаю результат, показанный выше (вертикальный белые линии).
РЕДАКТИРОВАТЬ
преобразование изображения из RGB32 в Indexed8 после чтения из qdatastream дает следующий результат:

2 ответа

Решение

Так вот решение: для сохранения оттенков серого 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

Это проблема управления памятью. При создании матрицы из куска памяти копия этой памяти не создается. В то же время эта память удаляется, когда QImage выходит за рамки.

Проверьте ответ о конвертации между QImage а также cv:Mat (есть лучшая ссылка в комментарии, но по какой-то причине страница не работает, поэтому я не предоставил эту ссылку здесь).

Когда вы справляетесь cv::Mat создается только поверхностная копия. Фактическое содержание матрицы не копируется. Увидеть cv::Mat конструкторская документация:

m - Массив, который (полностью или частично) присваивается построенной матрице. Данные конструкторы не копируются. Вместо этого создается заголовок, указывающий на m данных или его подмассив и связанный с ним. Счетчик ссылок, если есть, увеличивается. Таким образом, когда вы модифицируете матрицу, сформированную с помощью такого конструктора, вы также модифицируете соответствующие элементы m. Если вы хотите иметь независимую копию подмассива, используйте Mat::clone()

Другие вопросы по тегам