Important: Please read the Qt Code of Conduct -

Problem to convert QImage to cv::Mat

  • 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());
        int 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) <<,
        cv::Mat undistordedImage;
        cv::undistort(inputImage, undistordedImage, cameraMatrix, distortionCoefficients);
        qDebug() <<  undistordedImage.cols << undistordedImage.rows << undistordedImage.step;
        return QImage((uchar*), 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 !


  • 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:

    Another problem

    return QImage((uchar*), 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.cols, undistordedImage.rows, undistordedImage.step, image.format()).copy();

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

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

Log in to reply