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++
Forum Updated to NodeBB v4.3 + New Features

How to convert QImage to opencv Mat c++

Scheduled Pinned Locked Moved Unsolved General and Desktop
11 Posts 6 Posters 8.0k Views 2 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.
  • 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