QImage 与 cv::Mat 之间的相互转换

来源:互联网 发布:java方法覆盖 编辑:程序博客网 时间:2024/06/05 08:43

最近做图像处理方面的项目比较多,很多算法自己从头写的话太浪费时间,而且自己写的也不一定完善,早就听说OpenCV在图像处理算法方面功能很强大,一直没时间学习,这次正好项目用到了,临时抱佛脚学习些OpenCV入门知识。因为我的程序界面都是用Qt写的,因此也花了点时间研究了如何将OpenCV Qt 融合在一起,协同工作。

 

Qt 中处理图像主要用的是QImage类,OpenCV中主要用的是cv::Mat类。下面的两个函数可以用来实现这两个类相互转换。

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;}
程序比较简单,就不多说明了。唯一需要注意的是cvMat 和QImage 对于RGBA 这四个分量的排列顺序是不相同的。转换的时候需要调换一下。但是Qt 的文档中说的很明确,QImage内部数据存储的方式不能保证以后永远不变。所以这个代码也不能保证一直是可用的。

下面是五个测试用例。基本上把各种常见情况都覆盖了。

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();}


10 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 着凉了腰疼厉害怎么办 腰疼压迫神经腿麻木怎么办 运动后小腿变粗怎么办 跑步后小腿变粗怎么办 嘴腮里面肉肿了怎么办 左胳膊左腿发麻怎么办 右胳膊和右腿麻怎么办 站久了腿肿胀疼怎么办 坐电脑前脖子疼怎么办 一做颈椎就疼怎么办 出了月子腿疼怎么办 坐久了屁股麻木怎么办 搬东西把腰扭了怎么办 蹲时间长了脚麻怎么办 马桶坐久了腿麻怎么办 睡觉手麻怎么办小妙招 手麻了怎么办小妙招吗 腰疼的不能动怎么办 三岁宝宝腿抽筋怎么办 腿抽筋后一直疼怎么办 小腿筋疼怎么办腿无力 小腿里面的筋疼怎么办 腿抽筋,第二天疼怎么办 脚肿了怎么办消肿止痛 颈椎压迫神经手麻怎么办 上课睡觉手麻了怎么办 睡觉手麻了之后怎么办 趴着睡觉会打嗝怎么办 蹲久了脚麻了怎么办 干活累的手麻怎么办 月子手麻怎么办小妙招 电脑检测不到u盘怎么办 跟老婆三观不合怎么办 和老公三观不合怎么办 逗比人生爱之病怎么办 u盘无法识别怎么办修复 睾丸撞击后肿了怎么办 小孩脸过敏肿了怎么办 眼角肿了怎么办才能消肿 憋尿导致小腹痛怎么办 蛋蛋撞到了很疼怎么办