[Qt-opencv] QImage and conversion between cv :: Mat

Code updates. Please use the following code in this article.

https://blog.csdn.net/liyuanbhu/article/details/86307283

More recently do image processing aspects of the project, many algorithms to write their own from scratch, then a waste of time, but not necessarily improve their own writing, had heard OpenCV function is very powerful in terms of image processing algorithm, we have no time to learn, time project uses just cramming to learn some OpenCV started. Because my program interface is written using Qt, and therefore took some time to study how to OpenCV and Qt together, work together.

 

Qt the processed image is mainly used is QImage class, OpenCV is mainly used cv :: Mat class. The following two functions can be used to achieve conversion between these two classes.

QImage cvMat2QImage(const cv::Mat& mat)
{
    // 8-bits unsigned, NO. OF CHANNELS = 1
    if(mat.type() == CV_8UC1)
    {
        QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
        // Set the color table (used to translate colour indexes to qRgb values)
        image.setColorCount(256);
        for(int i = 0; i < 256; i++)
        {
            image.setColor(i, qRgb(i, i, i));
        }
        // Copy input Mat
        uchar *pSrc = mat.data;
        for(int row = 0; row < mat.rows; row ++)
        {
            uchar *pDest = image.scanLine(row);
            memcpy(pDest, pSrc, mat.cols);
            pSrc += mat.step;
        }
        return image;
    }
    // 8-bits unsigned, NO. OF CHANNELS = 3
    else if(mat.type() == CV_8UC3)
    {
        // Copy input Mat
        const uchar *pSrc = (const uchar*)mat.data;
        // Create QImage with same dimensions as input Mat
        QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
        return image.rgbSwapped();
    }
    else if(mat.type() == CV_8UC4)
    {
        qDebug() << "CV_8UC4";
        // Copy input Mat
        const uchar *pSrc = (const uchar*)mat.data;
        // Create QImage with same dimensions as input Mat
        QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
        return image.copy();
    }
    else
    {
        qDebug() << "ERROR: Mat could not be converted to QImage.";
        return QImage();
    }
}
cv::Mat QImage2cvMat(QImage image)
{
    cv::Mat mat;
    qDebug() << image.format();
    switch(image.format())
    {
    case QImage::Format_ARGB32:
    case QImage::Format_RGB32:
    case QImage::Format_ARGB32_Premultiplied:
        mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());
        break;
    case QImage::Format_RGB888:
        mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine());
        cv::cvtColor(mat, mat, CV_BGR2RGB);
        break;
    case QImage::Format_Indexed8:
        mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());
        break;
    }
    return mat;
}
 

Procedure is relatively simple, not much explained. The only caveat is cvMat QImage for RGBA and the order of these four components is not identical. A change of conversion when needed. But Qt documentation made it very clear, QImage way internal data storage can not guarantee that will never change. So this is no guarantee that the code is always available.

 

Here are five test cases. Basically put a variety of common situations are covered.

void test1()
{
    cv::Mat mat = cv::imread("Q:\\Koala.jpg", cv::IMREAD_UNCHANGED);
    cv::cvtColor(mat, mat, CV_BGR2BGRA);
    QImage image = cvMat2QImage(mat);
    qDebug() << (mat.type() == CV_8UC4);
    cvNamedWindow("cvMat2QImage RGB32", CV_WINDOW_AUTOSIZE);
    imshow("cvMat2QImage RGB32", mat);
    QLabel label;
    label.setPixmap(QPixmap::fromImage(image));
    label.show();
    cv::waitKey(10000);
}
void test2()
{
    cv::Mat mat = cv::imread("Q:\\Koala.jpg", cv::IMREAD_UNCHANGED);
    cv::cvtColor(mat, mat, CV_BGR2GRAY);
    QImage image = cvMat2QImage(mat);
    cvNamedWindow("cvMat2QImage gray", CV_WINDOW_AUTOSIZE);
    imshow("cvMat2QImage gray", mat);
    QLabel label;
    label.setPixmap(QPixmap::fromImage(image));
    label.show();
    cv::waitKey(10000);
}
void test3()
{
    QImage image("Q:\\Koala.jpg");
    image = image.convertToFormat(QImage::Format_RGB32);
    cv::Mat mat = QImage2cvMat(image);
    //cv::cvtColor(mat, mat, CV_BGR2RGB);
    imshow("QImage2cvMat RGB32", mat);
    cv::waitKey(10000);
}
 
void test4()
{
    QImage image("Q:\\Koala.jpg");
    image = image.convertToFormat(QImage::Format_RGB888);
    cv::Mat mat = QImage2cvMat(image);
    imshow("QImage2cvMat RGB24", mat);
    cv::waitKey(10000);
}
void test5()
{
    QImage image("Q:\\Koala.jpg");
    image = image.convertToFormat(QImage::Format_Indexed8);
    cv::Mat mat = QImage2cvMat(image);
    imshow("QImage2cvMat Indexed8", mat);
    cv::waitKey(10000);
}
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //test1();
    //test2();
    //test3();
    //test4();
    //test5();
    test1();
    return a.exec();
}


--------------------- 
Author: liyuanbhu 
Source: CSDN 
Original: https: //blog.csdn.net/liyuanbhu/article/details/46662115 
Disclaimer: This article as a blogger original article, reproduced, please attach Bowen link!

 

Guess you like

Origin blog.csdn.net/qingzhuyuxian/article/details/93134886