Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [SOLVED] save QVector<QImage> to QDataStream and read back
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] save QVector<QImage> to QDataStream and read back

Scheduled Pinned Locked Moved General and Desktop
20 Posts 2 Posters 10.0k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    Francknos
    wrote on last edited by
    #11

    No you don't have to convert before saving can you send me your code ?

    1 Reply Last reply
    0
    • C Offline
      C Offline
      chebhou
      wrote on last edited by
      #12

      do i post it here or send it in another way ?

      1 Reply Last reply
      0
      • F Offline
        F Offline
        Francknos
        wrote on last edited by
        #13

        you can send me francknos[at]gmail.com

        1 Reply Last reply
        0
        • C Offline
          C Offline
          chebhou
          wrote on last edited by
          #14

          @
          void savedata(const std::vectorcv::Mat* MatVect,const std::vector<int>* intVect){
          QFile file("students_dataset.dat");
          file.open(QIODevice::WriteOnly);
          QDataStream out(&file);
          qimgvect.clear();
          for (size_t i = 0; i < MatVect->size(); ++i) {
          cv::Mat matt = MatVect->at(i);
          QImage img= Mat2QImage(matt);
          qimgvect.push_back(img);
          }
          QVector<int> qintvect = QVector<int>::fromStdVector(*intVect);

              int nbImages = qimgvect.size();
              out << nbImages;
              for(int i=0; i<nbImages ;i++)
              {
                  QImage img = qimgvect.value(i);
                  out << img;
              }
              out  << qintvect;
              file.flush();
              file.close();
              return;
          

          }

          void loadData(std::vectorcv::Mat* MatVect,std::vector<int>* intVect){
          QFile file("students_dataset.dat");
          file.open(QIODevice::ReadOnly);
          QDataStream in(&file);
          qimgvect.clear();
          MatVect->clear();
          QVector<int> qintvect ;
          int nbImages =-1;
          QVector<QRgb> grayscale;
          for (int i = 0; i < 256; ++i) grayscale.append(qRgb(i, i, i));

          in >> nbImages;
          for(int i=0; i<nbImages ;i++)
          {
               QImage img;
               in >> img;
               img = img.convertToFormat(QImage::Format_Indexed8,grayscale);
               qimgvect.push_back(img);
          }
          in >> qintvect;
          
          for (size_t i = 0; i < qimgvect.size(); ++i) {
              QImage img = qimgvect.value(i);
              cv::Mat matt = QImage2Mat(img);
              MatVect->push_back(matt);
          }
          *intVect  = qintvect.toStdVector();
          file.close();
          return;
          

          }
          @

          1 Reply Last reply
          0
          • F Offline
            F Offline
            Francknos
            wrote on last edited by
            #15

            Are you sure that
            @QImage img= Mat2QImage(matt);@
            construct a Image Index_8 ?
            try qDebug on each pixel of img and look if all pixel are between 0 and 255.
            Or try to convert in written:
            @
            for (size_t i = 0; i < MatVect->size(); ++i)
            {
            cv::Mat matt = MatVect->at(i);
            QImage img= Mat2QImage(matt).convertToFormat(QImage::Format_Indexed8,grayscale);
            qimgvect.push_back(img);
            }
            @

            1 Reply Last reply
            0
            • C Offline
              C Offline
              chebhou
              wrote on last edited by
              #16

              Here is the the function :
              @
              QImage Mat2QImage(cv::Mat const& src)
              {
              cv::Mat temp; // make the same cv::Mat
              src.copyTo(temp);
              QImage dest((const uchar *) temp.data, temp.cols, temp.rows, temp.step, QImage::Format_Indexed8);
              dest.bits(); // enforce deep copy
              return dest;
              }
              @
              I've converted them as you suggested also I've checked using
              @qDebug() << QString::number(img.isGrayscale());@

              the result was always 1
              all the image have the same effect : image repeated 4 times horizontally inside itself like shown :
              !http://i.stack.imgur.com/Y8LLI.png(img)!
              thanks again for your help

              1 Reply Last reply
              0
              • F Offline
                F Offline
                Francknos
                wrote on last edited by
                #17

                try this function :
                @
                /* OpenCV ===========================================================================/
                QImage cvtCvMat2QImage(const cv::Mat & image, bool isBgr)
                {
                QImage qtemp;
                if(!image.empty() && image.depth() == CV_8U)
                {
                if(image.channels()==3)
                {
                const unsigned char * data = image.data;
                if(image.channels() == 3)
                {
                qtemp = QImage(image.cols, image.rows, QImage::Format_RGB32);
                for(int y = 0; y < image.rows; ++y, data += image.cols
                image.elemSize())
                {
                for(int x = 0; x < image.cols; ++x)
                {
                QRgb * p = ((QRgb*)qtemp.scanLine (y)) + x;
                if(isBgr)
                {
                *p = qRgb(data[x * image.channels()+2], data[x * image.channels()+1], data[x * image.channels()]);
                }
                else
                {
                *p = qRgb(data[x * image.channels()], data[x * image.channels()+1], data[x * image.channels()+2]);
                }
                }
                }
                }
                }
                else if(image.channels() == 1)
                {
                // mono grayscale
                qtemp = QImage(image.data, image.cols, image.rows, image.cols, QImage::Format_Indexed8).copy();
                QVector<QRgb> my_table;
                for(int i = 0; i < 256; i++) my_table.push_back(qRgb(i,i,i));
                qtemp.setColorTable(my_table);
                }
                else
                {
                printf("Wrong image format, must have 1 or 3 channels\n");
                }
                }
                return qtemp;
                }

                cv::Mat cvtQImage2CvMat(const QImage & image)
                {
                cv::Mat cvImage;
                if(!image.isNull() && image.depth() == 32 && image.format() == QImage::Format_RGB32)
                {
                // assume RGB (3 channels)
                int channels = 3;
                cvImage = cv::Mat(image.height(), image.width(), CV_8UC3);
                unsigned char * data = cvImage.data;
                for(int y = 0; y < image.height(); ++y, data+=cvImage.cols*cvImage.elemSize())
                {
                for(int x = 0; x < image.width(); ++x)
                {
                QRgb rgb = image.pixel(x, y);
                data[x * channels+2] = qRed(rgb); //r
                data[x * channels+1] = qGreen(rgb); //g
                data[x * channels] = qBlue(rgb); //b
                }
                }
                }
                else
                {
                printf("Failed to convert image : depth=%d(!=32) format=%d(!=%d)\n", image.depth(), image.format(), QImage::Format_RGB32);
                }
                return cvImage;
                }

                QImage cvtIplImage2QImage(const IplImage * image)
                {
                QImage qtemp;
                if (image && image->depth == IPL_DEPTH_8U && cvGetSize(image).width>0)
                {
                const char * data = image->imageData;
                qtemp= QImage(image->width, image->height,QImage::Format_RGB32);

                    for(int y = 0; y < image->height; ++y, data +=image->widthStep )
                    {
                        for(int x = 0; x < image->width; ++x)
                        {
                            uint *p = (uint*)qtemp.scanLine (y) + x;
                            *p = qRgb(data[x * image->nChannels+2], data[x * image->nChannels+1],data[x * image->nChannels]);
                        }
                    }
                }
                else if(image && image->depth != IPL_DEPTH_8U)
                {
                    printf("Wrong iplImage format, must be 8_bits\n");
                }
                return qtemp;
                

                }

                // Returned image must be released explicitly (using cvReleaseImage()).
                IplImage * cvtQImage2IplImage(const QImage & image)
                {
                IplImage * iplTmp = 0;
                if(!image.isNull() && image.depth() == 32 && image.format() == QImage::Format_RGB32)
                {
                // assume RGB (3 channels)
                int channels = 3;
                iplTmp = cvCreateImage(cvSize(image.width(), image.height()), IPL_DEPTH_8U, channels);
                char * data = iplTmp->imageData;
                for(int y = 0; y < image.height(); ++y, data+=iplTmp->widthStep)
                {
                for(int x = 0; x < image.width(); ++x)
                {
                QRgb rgb = image.pixel(x, y);
                data[x * channels+2] = qRed(rgb); //r
                data[x * channels+1] = qGreen(rgb); //g
                data[x * channels] = qBlue(rgb); //b
                }
                }
                }
                else
                {
                printf("Failed to convert image : depth=%d(!=32) format=%d(!=%d)\n", image.depth(), image.format(), QImage::Format_RGB32);
                }
                return iplTmp;
                }
                @

                1 Reply Last reply
                0
                • C Offline
                  C Offline
                  chebhou
                  wrote on last edited by
                  #18

                  thank you Francknos for keeping up with me, I have tried converting the image before saving and it did solve the problem
                  @ img = img.convertToFormat(QImage::Format_ARGB32); @

                  Here is the saving part now :
                  @
                  QFile file("students_dataset.dat");
                  file.open(QIODevice::WriteOnly);
                  QDataStream out(&file);
                  qimgvect.clear();
                  int nbImages = qimgvect.size();
                  out << nbImages;
                  for(int i=0; i<nbImages ;i++)
                  {
                  QImage img = qimgvect.value(i);
                  img = img.convertToFormat(QImage::Format_ARGB32);
                  out << img;
                  }
                  file.flush();
                  file.close();
                  @
                  Format_ARGB32 is the reason for the effect in the result ( 4 channels )
                  I'll try to elemenate the for loop and post back .
                  thank you !

                  1 Reply Last reply
                  0
                  • F Offline
                    F Offline
                    Francknos
                    wrote on last edited by
                    #19

                    Glad it's works !!

                    1 Reply Last reply
                    0
                    • C Offline
                      C Offline
                      chebhou
                      wrote on last edited by
                      #20

                      SO Here is the final 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

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved