QT中对Mat类的一些操作详解
目录
- 一、类型转换
- 二、保存至数据库
一、类型转换 opencv在QT中的应用通常会涉及到这三者的转换,即Mat、QImage、QPixmap。
下面分别给出了
- Mat转QImage
- QImage转Mat
- Mat转QPixmap
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://单通道{Matmat( img.height(), img.width(), CV_8UC1,const_cast(img.bits()), static_cast(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"; }QImageswapped = 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 (swapped.bits()), static_cast(swapped.bytesPerLine()) ).clone(); }// 8-bit, 4 channelcase QImage::Format_ARGB32:case QImage::Format_ARGB32_Premultiplied:{Matmat( img.height(), img.width(), CV_8UC4,const_cast (img.bits()), static_cast(img.bytesPerLine()) ); return (inCloneImageData ? mat.clone() : mat); }// 8-bit, 1 channeldefault: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}
二、保存至数据库 【QT中对Mat类的一些操作详解】我这里是直接将Mat类型的数据以二进制数据流的方式保存到数据库中,有些文章是将文件名及其所在的路径保存到数据库中,这个还是要好看项目需求,个人而言,我这个要更复杂一点。
演示效果如下:
1??:基础界面
文章图片
2??:磨皮处理
文章图片
3??:数据库中的数据
文章图片
4??:核心代码
注意: 创建数据表的时候,字段的类型,一定要满足数据的大小,比方说保存图片一般使用blob相关的类型,其中blob最大为64k,mediumblob最大为16M。
思路,先捕获ui控件(我用于显示图片的控件是QLabel)中的数据,然后进行数据库操作。具体步骤如下:
数据类型:Image —>Mat。
然后再将Mat类型保存到byte数组中,再上传到数据库。(此时有小伙伴可能就要问了,为什么不直接从Image类型转byte数组呢?当然可以,不过我们饶了个弯子也是想让大家学会如何将Mat类型转成byte数组)
上传数据库,用户名+图片数据(这个看自身的需求)
准备数据库查询语句query,用法如下图所示
文章图片
验证阶段,取回图片,然后显示在右侧的QLabel中,因为我代码中取回的是用户id为33的图片数据,所以显示的是一个水瓶。
文章图片
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()<(TEXT1.data()); //将QByteArray类型转为unsigned charMat image=Mat(height,width,CV_8UC3,data2); //将unsigned char转成Mat类型的数据QPixmap temp = MatToPixmap(image); ui->Process_image->setPixmap(temp); }}else{qDebug()<<"从数据库获取图片失败"; }}
到此这篇关于QT中对Mat类的一些操作详解的文章就介绍到这了,更多相关QT Mat操作内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- C/C++基本数据类型 所占字节数 在内存中存储方式 内存 指针
- SpringBoot Redis五种数据类型的简单操作
- wordpress|WordPress获取分类数据函数(get_term)
- #yyds干货盘点#K8S 之对象类资源配置
- 带你掌握Redis数据类型(string和Hash)
- (注册中心启动类上的注解EnableEurekaServer)
- Matlab完整代码|【Matlab语言去噪】IIR+FIR滤波器语音去噪【含GUI源码 1027期】
- Linux|Redis(测试连接, 五大数据类型,三种特殊数据类型)
- 了解下C# 可空类型(Nullable)
- #yyds干货盘点# C#中的File类