Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/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());
        //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



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



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


Log in to reply