Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    Unsolved How to convert QImage to opencv Mat c++

    General and Desktop
    6
    11
    3536
    Loading More Posts
    • 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 last edited by

      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.Hilk Pl45m4 JKSH 3 Replies Last reply Reply Quote 0
      • J.Hilk
        J.Hilk Moderators @Malikov last edited by

        @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

        Qt Needs YOUR vote: https://bugreports.qt.io/browse/QTQAINFRA-4121


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

        1 Reply Last reply Reply Quote 2
        • M
          Malikov last edited by

          Is their simpler way? In one method?

          1 Reply Last reply Reply Quote 0
          • Pl45m4
            Pl45m4 @Malikov last edited by

            @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 Reply Quote 0
            • JKSH
              JKSH Moderators @Malikov last edited by

              @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

              Pl45m4 1 Reply Last reply Reply Quote 2
              • Pl45m4
                Pl45m4 @JKSH last edited by

                @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 Reply Quote 1
                • M
                  Malikov @Pl45m4 last edited by

                  @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 Reply Quote 0
                  • eyllanesc
                    eyllanesc last edited by eyllanesc

                    @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 Reply Quote 0
                    • M
                      Malikov last edited by

                      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 Reply Quote 0
                      • B
                        Bonnie @Malikov last edited by Bonnie

                        @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 Reply Quote 4
                        • M
                          Malikov last edited by

                          tnx.
                          It worked

                          1 Reply Last reply Reply Quote 0
                          • First post
                            Last post