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


person Chebhou    schedule 27.09.2014    source источник
comment
изображение слева больше, чем изображение справа, я думаю, 70x70 неправильно   -  person berak    schedule 27.09.2014
comment
я пробовал img.width(), img.height() раньше, но получил тот же результат, поэтому я использовал 70x70, потому что все изображения имеют размер 70x70 в результате некоторой обработки.   -  person Chebhou    schedule 27.09.2014


Ответы (2)


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

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

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

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

person Marek R    schedule 28.09.2014
comment
qimgvect.push_back(img) берет копию img до того, как она выйдет за рамки - person Chebhou; 28.09.2014
comment
спасибо, это была проблема, вот что заставило меня подумать, что это скопировано Q_about vector, но теперь у меня есть новая проблема в QDataStream, потому что я тестировал код без него, и он работал нормально, пожалуйста, посмотрите правку - person Chebhou; 29.09.2014

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

person Chebhou    schedule 30.09.2014