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. How to convert QImage to opencv Mat c++
QtWS25 Last Chance

How to convert QImage to opencv Mat c++

Scheduled Pinned Locked Moved Unsolved General and Desktop
11 Posts 6 Posters 7.1k Views
  • 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.
  • M Offline
    M Offline
    Malikov
    wrote on last edited by
    #1

    I have searched on the internet but I cannot find a method in C++ of converting a QImage ( QImage(2048, 1148, QImage::Format_Grayscale8) ) to a OpenCV Mat for write frames to cv::VideoWriter("output.avi",cv::VideoWriter::fourcc('D','I','V','X'),10, size,0);

    This is the method I'm using but it throws exception when write to cv::VideoWriter :

    cv::Mat QImageToCvMat(QImage &inImage)
    {
    cv::Mat mat(inImage.height(), inImage.width(),
    CV_16UC1, inImage.bits(), inImage.bytesPerLine());
    return mat;
    }

    The exception:

    OpenCV Error: Image step is wrong () in cvSetData, file /build/opencv-XDqSFW/opencv-3.2.0+dfsg/modules/core/src/array.cpp, line 939
    terminate called after throwing an instance of 'cv::Exception'
    what(): /build/opencv-XDqSFW/opencv-3.2.0+dfsg/modules/core/src/array.cpp:939: error: (-13) in function cvSetData

    How would I do this the right way ?.

    Any help is appreciated.

    J.HilkJ Pl45m4P JKSHJ 3 Replies Last reply
    0
    • M Malikov

      I have searched on the internet but I cannot find a method in C++ of converting a QImage ( QImage(2048, 1148, QImage::Format_Grayscale8) ) to a OpenCV Mat for write frames to cv::VideoWriter("output.avi",cv::VideoWriter::fourcc('D','I','V','X'),10, size,0);

      This is the method I'm using but it throws exception when write to cv::VideoWriter :

      cv::Mat QImageToCvMat(QImage &inImage)
      {
      cv::Mat mat(inImage.height(), inImage.width(),
      CV_16UC1, inImage.bits(), inImage.bytesPerLine());
      return mat;
      }

      The exception:

      OpenCV Error: Image step is wrong () in cvSetData, file /build/opencv-XDqSFW/opencv-3.2.0+dfsg/modules/core/src/array.cpp, line 939
      terminate called after throwing an instance of 'cv::Exception'
      what(): /build/opencv-XDqSFW/opencv-3.2.0+dfsg/modules/core/src/array.cpp:939: error: (-13) in function cvSetData

      How would I do this the right way ?.

      Any help is appreciated.

      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #2

      @Malikov
      https://github.com/dbzhang800/QtOpenCV


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      1 Reply Last reply
      2
      • M Offline
        M Offline
        Malikov
        wrote on last edited by
        #3

        Is their simpler way? In one method?

        1 Reply Last reply
        0
        • M Malikov

          I have searched on the internet but I cannot find a method in C++ of converting a QImage ( QImage(2048, 1148, QImage::Format_Grayscale8) ) to a OpenCV Mat for write frames to cv::VideoWriter("output.avi",cv::VideoWriter::fourcc('D','I','V','X'),10, size,0);

          This is the method I'm using but it throws exception when write to cv::VideoWriter :

          cv::Mat QImageToCvMat(QImage &inImage)
          {
          cv::Mat mat(inImage.height(), inImage.width(),
          CV_16UC1, inImage.bits(), inImage.bytesPerLine());
          return mat;
          }

          The exception:

          OpenCV Error: Image step is wrong () in cvSetData, file /build/opencv-XDqSFW/opencv-3.2.0+dfsg/modules/core/src/array.cpp, line 939
          terminate called after throwing an instance of 'cv::Exception'
          what(): /build/opencv-XDqSFW/opencv-3.2.0+dfsg/modules/core/src/array.cpp:939: error: (-13) in function cvSetData

          How would I do this the right way ?.

          Any help is appreciated.

          Pl45m4P Offline
          Pl45m4P Offline
          Pl45m4
          wrote on last edited by
          #4

          @Malikov said in How to convert QImage to opencv Mat c++:

          Image step is wrong () in cvSetData

          Set correct imageStep and it should work.

          See here:
          https://stackoverflow.com/questions/17127762/cvmat-to-qimage-and-back/17137998

          or here:
          https://stackoverflow.com/questions/5026965/how-to-convert-an-opencv-cvmat-to-qimage


          If debugging is the process of removing software bugs, then programming must be the process of putting them in.

          ~E. W. Dijkstra

          M 1 Reply Last reply
          0
          • M Malikov

            I have searched on the internet but I cannot find a method in C++ of converting a QImage ( QImage(2048, 1148, QImage::Format_Grayscale8) ) to a OpenCV Mat for write frames to cv::VideoWriter("output.avi",cv::VideoWriter::fourcc('D','I','V','X'),10, size,0);

            This is the method I'm using but it throws exception when write to cv::VideoWriter :

            cv::Mat QImageToCvMat(QImage &inImage)
            {
            cv::Mat mat(inImage.height(), inImage.width(),
            CV_16UC1, inImage.bits(), inImage.bytesPerLine());
            return mat;
            }

            The exception:

            OpenCV Error: Image step is wrong () in cvSetData, file /build/opencv-XDqSFW/opencv-3.2.0+dfsg/modules/core/src/array.cpp, line 939
            terminate called after throwing an instance of 'cv::Exception'
            what(): /build/opencv-XDqSFW/opencv-3.2.0+dfsg/modules/core/src/array.cpp:939: error: (-13) in function cvSetData

            How would I do this the right way ?.

            Any help is appreciated.

            JKSHJ Offline
            JKSHJ Offline
            JKSH
            Moderators
            wrote on last edited by
            #5

            @Malikov said in How to convert QImage to opencv Mat c++:

            cv::Mat mat(inImage.height(), inImage.width(),
            CV_16UC1, inImage.bits(), inImage.bytesPerLine());

            CV_16UC1 is for 16-bit data. QImage::Format_Grayscale8 is for 8-bit data. If I'm not mistaken, these are incompatible. (Try converting your QImage to a 16-bit format first)

            Also, see this answer: https://stackoverflow.com/a/17137998/1144539

            Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

            Pl45m4P 1 Reply Last reply
            2
            • JKSHJ JKSH

              @Malikov said in How to convert QImage to opencv Mat c++:

              cv::Mat mat(inImage.height(), inImage.width(),
              CV_16UC1, inImage.bits(), inImage.bytesPerLine());

              CV_16UC1 is for 16-bit data. QImage::Format_Grayscale8 is for 8-bit data. If I'm not mistaken, these are incompatible. (Try converting your QImage to a 16-bit format first)

              Also, see this answer: https://stackoverflow.com/a/17137998/1144539

              Pl45m4P Offline
              Pl45m4P Offline
              Pl45m4
              wrote on last edited by
              #6

              @JKSH said in How to convert QImage to opencv Mat c++:

              Try converting your QImage to a 16-bit format first

              Just using CV_8UC1 type Mat would be the easier way, since @Malikov wants to get a cv::Mat from existing QImage :)


              If debugging is the process of removing software bugs, then programming must be the process of putting them in.

              ~E. W. Dijkstra

              1 Reply Last reply
              1
              • Pl45m4P Pl45m4

                @Malikov said in How to convert QImage to opencv Mat c++:

                Image step is wrong () in cvSetData

                Set correct imageStep and it should work.

                See here:
                https://stackoverflow.com/questions/17127762/cvmat-to-qimage-and-back/17137998

                or here:
                https://stackoverflow.com/questions/5026965/how-to-convert-an-opencv-cvmat-to-qimage

                M Offline
                M Offline
                Malikov
                wrote on last edited by
                #7

                @Pl45m4

                Hi

                I'm not sure what format type I need to set in the Mat contractor.
                Each frame has 1 channels and 2 elem bytes. I initialize QImage variable this way:

                        img = QImage(width, height, QImage::Format_Grayscale8);
                        uchar *pSrc = (uchar *)m_frame.pBuffer + m_frame.usHeader;
                        uchar *pDst = (uchar *)img.bits();
                
                       int pixels = frame.width * frame.height * frame.channels;
                       for (int i = 0; i < pixels; ++i)
                       {
                                    *pDst++ = *pSrc;
                                    pSrc += elementBytes;
                       } 
                

                My issue is to convert this QImage img to Mat variable in order to write frames to cv::VideoWriter.

                1 Reply Last reply
                0
                • eyllanescE Offline
                  eyllanescE Offline
                  eyllanesc
                  wrote on last edited by eyllanesc
                  #8

                  @Malikov See this answer: https://stackoverflow.com/a/50848100/6622587

                  static cv::Mat QImageToMat(const QImage & image){
                      cv::Mat out;
                      switch(image.format()) {
                      case QImage::Format_Invalid:
                      {
                          cv::Mat empty;
                          empty.copyTo(out);
                          break;
                      }
                      case QImage::Format_RGB32:
                      {
                          cv::Mat view(image.height(),image.width(),CV_8UC4,(void *)image.constBits(),image.bytesPerLine());
                          view.copyTo(out);
                          break;
                      }
                      case QImage::Format_RGB888:
                      {
                          cv::Mat view(image.height(),image.width(),CV_8UC3,(void *)image.constBits(),image.bytesPerLine());
                          cv::cvtColor(view, out, cv::COLOR_RGB2BGR);
                          break;
                      }
                      default:
                      {
                          QImage conv = image.convertToFormat(QImage::Format_ARGB32);
                          cv::Mat view(conv.height(),conv.width(),CV_8UC4,(void *)conv.constBits(),conv.bytesPerLine());
                          view.copyTo(out);
                          break;
                      }
                      }
                      return out;
                  }
                  

                  If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    Malikov
                    wrote on last edited by
                    #9

                    Sorry its not helping me

                    The format is QImage::Format_Grayscale8 and Im not sire what format I need for Mat.

                    B 1 Reply Last reply
                    0
                    • M Malikov

                      Sorry its not helping me

                      The format is QImage::Format_Grayscale8 and Im not sire what format I need for Mat.

                      B Offline
                      B Offline
                      Bonnie
                      wrote on last edited by Bonnie
                      #10

                      @Malikov
                      As @JKSH and @Pl45m4 already said, just replace CV_16UC1 with CV_8UC1 like

                      cv::Mat mat(image.height(), image.width(), CV_8UC1, image.bits(), image.bytesPerLine());
                      

                      Have you tried that?
                      You need to keep image valid and unchanged during the use of mat because they are sharing internal data.

                      1 Reply Last reply
                      4
                      • M Offline
                        M Offline
                        Malikov
                        wrote on last edited by
                        #11

                        tnx.
                        It worked

                        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