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. Problem to convert QImage to cv::Mat
Qt 6.11 is out! See what's new in the release blog

Problem to convert QImage to cv::Mat

Scheduled Pinned Locked Moved Solved General and Desktop
3 Posts 2 Posters 1.6k 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.
  • H Offline
    H Offline
    HB76
    wrote on last edited by HB76
    #1

    Hello there !

    I am facing a problem when trying to convert a QImage to cv:Mat to perform a lens distortion correction with opencv.

    I have a ImageProcessingToolBox class that regroup some static image processing functions. Here is my code :

    QImage ImageProcessingToolBox::undistortImage(const QImage &image, const ImageProcessingParameters &parameters)
    {
        cv::Mat inputImage = cv::Mat(image.height(), image.width(), image.format(), (uchar*)image.bits(), image.bytesPerLine());
        //cv::imshow("Test",inputImage);
    
        int fov = parameters.camera.fov;
        auto x = image.width()/2;
        auto y = image.height()/2;
        auto focalLengthX = x / tan(fov * 0.5 * acos(-1) / 180.0);
        auto focalLengthY = y / tan(fov* 0.5 * acos(-1) / 180.0);
        cv::Mat cameraMatrix = (cv::Mat_<double>(3, 3) <<  focalLengthX,   0,              x,
                                                           0,              focalLengthY,   y,
                                                           0,              0,              1);
    
        cv::Mat distortionCoefficients = (cv::Mat1d(1, 5) <<  parameters.camera.k1,
                                                              parameters.camera.k2,
                                                              parameters.camera.p1,
                                                              parameters.camera.p2,
                                                              parameters.camera.k3);
        cv::Mat undistordedImage;
        cv::undistort(inputImage, undistordedImage, cameraMatrix, distortionCoefficients);
        
        qDebug() <<  undistordedImage.cols << undistordedImage.rows << undistordedImage.step;
    
        return QImage((uchar*) undistordedImage.data, undistordedImage.cols, undistordedImage.rows, undistordedImage.step, image.format());
    }
    

    When I send a QImage to my function with a QImage::Format_Grayscale8, if I try to visualize my inputImage cv::Mat after conversion, I got the same image displayed 4 times like a spaghetti. And when I convert back my cv::Mat to QImage to return it, the program crash.

    I tried differents ways to convert QImage to cv::mat but it doesn't change anything or worse, it can't compile anymore. When I ask the debugger to show the inputImage rows and cols values, it correspond to my Qimage width and height but the step value is 4 times the width value. This makes me think that it is the reason why I got 4 times the same image when I call imshow after converting the QImage to cv::Mat, but I don't know of to figure this out...

    Does any of you has already faced this issue ?

    Thanks in advance !

    HB76

    1 Reply Last reply
    0
    • B Offline
      B Offline
      Bonnie
      wrote on last edited by Bonnie
      #2

      You are passing image.format() as cv::Mat's type, which are totally different things.
      If you are sure the format is grayscale8, I think you should use CV_8UC1 as the type.
      (FYI, QImage::Format_Grayscale8 have the value of 24, which happens to equal CV_8UC(4).)
      If the format is not fixed, then this may be helpful to your conversion: https://github.com/dbzhang800/QtOpenCV

      Another problem

      return QImage((uchar*) undistordedImage.data, undistordedImage.cols, undistordedImage.rows, undistordedImage.step, image.format());

      It is not safe to return a QImage constructed with inner data of a cv::Mat which will soon be out of scope.
      My suggestion is to add copy() like:

      return QImage((uchar*) undistordedImage.data, undistordedImage.cols, undistordedImage.rows, undistordedImage.step, image.format()).copy();
      

      Or you could use the mat2Image method from the project I mentioned above.

      H 1 Reply Last reply
      2
      • B Bonnie

        You are passing image.format() as cv::Mat's type, which are totally different things.
        If you are sure the format is grayscale8, I think you should use CV_8UC1 as the type.
        (FYI, QImage::Format_Grayscale8 have the value of 24, which happens to equal CV_8UC(4).)
        If the format is not fixed, then this may be helpful to your conversion: https://github.com/dbzhang800/QtOpenCV

        Another problem

        return QImage((uchar*) undistordedImage.data, undistordedImage.cols, undistordedImage.rows, undistordedImage.step, image.format());

        It is not safe to return a QImage constructed with inner data of a cv::Mat which will soon be out of scope.
        My suggestion is to add copy() like:

        return QImage((uchar*) undistordedImage.data, undistordedImage.cols, undistordedImage.rows, undistordedImage.step, image.format()).copy();
        

        Or you could use the mat2Image method from the project I mentioned above.

        H Offline
        H Offline
        HB76
        wrote on last edited by
        #3

        @Bonnie you made my day ! Many thanks for your help !

        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