文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

QT中怎么对Mat类进行操作

2023-07-02 06:35

关注

本篇内容主要讲解“QT中怎么对Mat类进行操作”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“QT中怎么对Mat类进行操作”吧!

一、类型转换

opencv在QT中的应用通常会涉及到这三者的转换,即MatQImageQPixmap
下面分别给出了

1️⃣:Mat转QImage

QImage MainWindow::MatToImage(const Mat &m)  //Mat转Image{    switch(m.type())    {        case CV_8UC1:        {            QImage img((uchar *)m.data,m.cols,m.rows,m.cols * 1, QImage::Format_Grayscale8);            return img;        }            break;        case CV_8UC3:        {            QImage img((uchar *)m.data,m.cols,m.rows,m.cols * 3, QImage::Format_RGB888);            return img.rgbSwapped();  //因为在QT中彩色图象是RGB的顺序,但是在OPENCV中是BGR的顺序,所以要转一下        }            break;        case CV_8UC4:        {            QImage img((uchar *)m.data,m.cols,m.rows,m.cols * 4, QImage::Format_ARGB32);            return img;        }            break;        default:     //如果是默认的,那么将其返回为一个空对象        {            QImage img;            return img;        }    }}

2️⃣:QImage转Mat

Mat MainWindow::ImageToMat(const QImage &img,bool inCloneImageData)  //Image转Mat{    switch(img.format())    {        case QImage::Format_Indexed8:   //单通道        {            Mat  mat( img.height(), img.width(), CV_8UC1,                          const_cast<uchar*>(img.bits()), static_cast<size_t>(img.bytesPerLine()) );            return (inCloneImageData ? mat.clone() : mat);        }        // 8-bit, 3 通道        case QImage::Format_RGB32:   //这种写法表示并列关系        case QImage::Format_RGB888:        {            if ( !inCloneImageData )            {                qWarning() << "CVS::QImageToCvMat() - Conversion requires cloning because we use a temporary QImage";            }            QImage  swapped = img;            if ( img.format() == QImage::Format_RGB32 )            {                swapped = swapped.convertToFormat( QImage::Format_RGB888 );            }            swapped = swapped.rgbSwapped();  //因为在QT中彩色图象是RGB的顺序,但是在OPENCV中是BGR的顺序,所以要转一下            return Mat( swapped.height(), swapped.width(), CV_8UC3,                        const_cast<uchar*>(swapped.bits()), static_cast<size_t>(swapped.bytesPerLine()) ).clone();        }        // 8-bit, 4 channel        case QImage::Format_ARGB32:        case QImage::Format_ARGB32_Premultiplied:        {            Mat  mat( img.height(), img.width(), CV_8UC4,                          const_cast<uchar*>(img.bits()), static_cast<size_t>(img.bytesPerLine()) );            return (inCloneImageData ? mat.clone() : mat);        }        // 8-bit, 1 channel        default:            qWarning() << "CVS::QImageToCvMat() - QImage format not handled in switch:" << img.format();            break;        }    return Mat();}

3️⃣:Mat转QPixmap

QPixmap MainWindow::MatToPixmap(const Mat &m){    return QPixmap::fromImage(MatToImage(m));   //相当于先将Mat转成Image,再转成Pixmap}

二、保存至数据库

我这里是直接将Mat类型的数据以二进制数据流的方式保存到数据库中,有些文章是将文件名及其所在的路径保存到数据库中,这个还是要好看项目需求,个人而言,我这个要更复杂一点。
演示效果如下:

1️⃣:基础界面

QT中怎么对Mat类进行操作

2️⃣:磨皮处理

QT中怎么对Mat类进行操作

3️⃣:数据库中的数据

QT中怎么对Mat类进行操作

4️⃣:核心代码

注意: 创建数据表的时候,字段的类型,一定要满足数据的大小,比方说保存图片一般使用blob相关的类型,其中blob最大为64k,mediumblob最大为16M。

思路,先捕获ui控件(我用于显示图片的控件是QLabel)中的数据,然后进行数据库操作。具体步骤如下:

数据类型:Image &mdash;>Mat。

然后再将Mat类型保存到byte数组中,再上传到数据库。(此时有小伙伴可能就要问了,为什么不直接从Image类型转byte数组呢?当然可以,不过我们饶了个弯子也是想让大家学会如何将Mat类型转成byte数组)

上传数据库,用户名+图片数据(这个看自身的需求)

准备数据库查询语句query,用法如下图所示

QT中怎么对Mat类进行操作

验证阶段,取回图片,然后显示在右侧的QLabel中,因为我代码中取回的是用户id为33的图片数据,所以显示的是一个水瓶。

QT中怎么对Mat类进行操作

void MainWindow::Upmysql()   //将处理的图片上传至数据库{    QImage pix=ui->Process_image->pixmap()->toImage();    Mat m=ImageToMat(pix);  //QImage--->Mat格式转换    int height = pix.height();   //定义这两者的目的是为了传给Mat的构造函数    int width = pix.width();    int iSize = m.total() * m.elemSize();   //记录Mat图像的大小,以便于创建同等大小的字节数组    unsigned char* bytes = new unsigned char[iSize];   //创建一个字节数组,用于保存二进制数据    memcpy(bytes, m.data, iSize * sizeof(unsigned char));    //将Mat类型的数据赋给byte数组    //qDebug()<<QByteArray((char*)bytes, 100);    //查看前100个字符    QByteArray sbuf = QByteArray::fromRawData((char *)bytes, iSize * sizeof(unsigned char));   //将unsigned char转为QByteArray类型    QVariant var(sbuf);   //将QByteArray类型转成QVariant以便于插入到MYSql    QSqlQuery query;   //下面为数据库查询的一种方式,要特别注意格式的要求    //创建数据表的时候,一定要注意数据的大小,比方说图片blob为64k,mediumblob为16m    query.prepare("INSERT INTO Image_All (id, img_data) "                        "VALUES (:id, :img_data)");    query.bindValue(":id", 77877);    //我这里随便设的    query.bindValue(":img_data",var);    if(query.exec())    {        qDebug()<<"图片成功上传至数据库";    }    else{        qDebug()<<"图片上传数据库失败";    }    QString sql1=QString("select img_data from Image_All where id='33'");   //获取数据库中图片数据    if(query.exec(sql1)) //执行sql语句是否成功    {        while(query.next())//指向下一条        {            //根据下标将返回结果进行分割            QByteArray TEXT1=query.value(0).toByteArray();  //将查询结果以QByteArray形式返回            unsigned char *data2;             data2 = reinterpret_cast<unsigned char*>(TEXT1.data());   //将QByteArray类型转为unsigned char            Mat image=Mat(height,width,CV_8UC3,data2);      //将unsigned char转成Mat类型的数据            QPixmap temp = MatToPixmap(image);            ui->Process_image->setPixmap(temp);        }    }else    {        qDebug()<<"从数据库获取图片失败";    }}

到此,相信大家对“QT中怎么对Mat类进行操作”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯