saving and loading vector<Mat> Qt & OpenCV

假装没事ソ 提交于 2019-12-11 14:04:07

问题


I'm working on face recognition in Qt & openCV using the FisherFaces recognizer which doesn't support updating so i have to save the faces database to retrain the recognizer after any changes.
Here is my code for saving :

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();
    } 

and this is for loading :

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;
    } 
the problem is that what I read back from the file is not what i saved

so what's exactly wrong in this code (hope not all of it ) ?
is there a better/easier way of saving the vector ?
EDIT :
thanks to Marek_R the conversion part is fixed, but saving and loading with QDataStream is the problem now :


so what's causing those lines ?
EDIT :
I have tried this :
made QimgVect public and elemenated QDataStream part : MatVect-> QimgVect than QimgVect->MatVect and it did work fine, but after adding QDataStream : MatVect-> QimgVect->QDataStream and QDataStream->QimgVect->MatVect i get get the result shown above( vertical white lines ).
EDIT
converting the image from RGB32 to Indexed8 after reading from qdatastream gives the following result :


回答1:


this is memory management issue. When you create matrix from piece of memory copy of this memory is not created. At the same time this memory is disposed when QImage goes out of the scope.

Check answer about converting between QImage and cv:Mat (there is a better link in comment but for some reason page is not working so I didn't provided this link here).

When you are coping cv::Mat only a shallow copy is created. Actual Matrix contents is not copied. See cv::Mat constructor documentation:

m – Array that (as a whole or partly) is assigned to the constructed matrix. No data is copied by these constructors. Instead, the header pointing to m data or its sub-array is constructed and associated with it. The reference counter, if any, is incremented. So, when you modify the matrix formed using such a constructor, you also modify the corresponding elements of m . If you want to have an independent copy of the sub-array, use Mat::clone()




回答2:


SO Here is a solution : for saving grayscale Qimage through QDataStream convert it to Format_ARGB32 then save it, for loading convert it back to Format_Indexed8 : saving code

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();

for loading

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();

I think even QImage with other Formats will face the same problem since it is assumed that the default format is Format_ARGB32



来源:https://stackoverflow.com/questions/26073613/saving-and-loading-vectormat-qt-opencv

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!