本篇内容主要讲解“QT中怎么对Mat类进行操作”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“QT中怎么对Mat类进行操作”吧!
一、类型转换
opencv在QT中的应用通常会涉及到这三者的转换,即Mat、QImage、QPixmap。
下面分别给出了
Mat转QImage
QImage转Mat
Mat转QPixmap
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️⃣:基础界面
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()<<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类进行操作”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!