您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“QT中怎么對Mat類進行操作”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“QT中怎么對Mat類進行操作”吧!
opencv在QT中的應用通常會涉及到這三者的轉(zhuǎn)換,即Mat、QImage、QPixmap。
下面分別給出了
Mat轉(zhuǎn)QImage
QImage轉(zhuǎn)Mat
Mat轉(zhuǎn)QPixmap
1??:Mat轉(zhuǎn)QImage
QImage MainWindow::MatToImage(const Mat &m) //Mat轉(zhuǎn)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的順序,所以要轉(zhuǎn)一下 } 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轉(zhuǎn)Mat
Mat MainWindow::ImageToMat(const QImage &img,bool inCloneImageData) //Image轉(zhuǎn)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: //這種寫法表示并列關(guān)系 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的順序,所以要轉(zhuǎn)一下 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轉(zhuǎn)QPixmap
QPixmap MainWindow::MatToPixmap(const Mat &m) { return QPixmap::fromImage(MatToImage(m)); //相當于先將Mat轉(zhuǎn)成Image,再轉(zhuǎn)成Pixmap }
我這里是直接將Mat類型的數(shù)據(jù)以二進制數(shù)據(jù)流的方式保存到數(shù)據(jù)庫中,有些文章是將文件名及其所在的路徑保存到數(shù)據(jù)庫中,這個還是要好看項目需求,個人而言,我這個要更復雜一點。
演示效果如下:
1??:基礎(chǔ)界面
2??:磨皮處理
3??:數(shù)據(jù)庫中的數(shù)據(jù)
4??:核心代碼
注意: 創(chuàng)建數(shù)據(jù)表的時候,字段的類型,一定要滿足數(shù)據(jù)的大小,比方說保存圖片一般使用blob相關(guān)的類型,其中blob最大為64k,mediumblob最大為16M。
思路,先捕獲ui控件(我用于顯示圖片的控件是QLabel)中的數(shù)據(jù),然后進行數(shù)據(jù)庫操作。具體步驟如下:
數(shù)據(jù)類型:Image —>Mat。
然后再將Mat類型保存到byte數(shù)組中,再上傳到數(shù)據(jù)庫。(此時有小伙伴可能就要問了,為什么不直接從Image類型轉(zhuǎn)byte數(shù)組呢?當然可以,不過我們饒了個彎子也是想讓大家學會如何將Mat類型轉(zhuǎn)成byte數(shù)組)
上傳數(shù)據(jù)庫,用戶名+圖片數(shù)據(jù)(這個看自身的需求)
準備數(shù)據(jù)庫查詢語句query,用法如下圖所示
驗證階段,取回圖片,然后顯示在右側(cè)的QLabel中,因為我代碼中取回的是用戶id為33的圖片數(shù)據(jù),所以顯示的是一個水瓶。
void MainWindow::Upmysql() //將處理的圖片上傳至數(shù)據(jù)庫 { QImage pix=ui->Process_image->pixmap()->toImage(); Mat m=ImageToMat(pix); //QImage--->Mat格式轉(zhuǎn)換 int height = pix.height(); //定義這兩者的目的是為了傳給Mat的構(gòu)造函數(shù) int width = pix.width(); int iSize = m.total() * m.elemSize(); //記錄Mat圖像的大小,以便于創(chuàng)建同等大小的字節(jié)數(shù)組 unsigned char* bytes = new unsigned char[iSize]; //創(chuàng)建一個字節(jié)數(shù)組,用于保存二進制數(shù)據(jù) memcpy(bytes, m.data, iSize * sizeof(unsigned char)); //將Mat類型的數(shù)據(jù)賦給byte數(shù)組 //qDebug()<<QByteArray((char*)bytes, 100); //查看前100個字符 QByteArray sbuf = QByteArray::fromRawData((char *)bytes, iSize * sizeof(unsigned char)); //將unsigned char轉(zhuǎn)為QByteArray類型 QVariant var(sbuf); //將QByteArray類型轉(zhuǎn)成QVariant以便于插入到MYSql QSqlQuery query; //下面為數(shù)據(jù)庫查詢的一種方式,要特別注意格式的要求 //創(chuàng)建數(shù)據(jù)表的時候,一定要注意數(shù)據(jù)的大小,比方說圖片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()<<"圖片成功上傳至數(shù)據(jù)庫"; } else{ qDebug()<<"圖片上傳數(shù)據(jù)庫失敗"; } QString sql1=QString("select img_data from Image_All where id='33'"); //獲取數(shù)據(jù)庫中圖片數(shù)據(jù) if(query.exec(sql1)) //執(zhí)行sql語句是否成功 { while(query.next())//指向下一條 { //根據(jù)下標將返回結(jié)果進行分割 QByteArray TEXT1=query.value(0).toByteArray(); //將查詢結(jié)果以QByteArray形式返回 unsigned char *data2; data2 = reinterpret_cast<unsigned char*>(TEXT1.data()); //將QByteArray類型轉(zhuǎn)為unsigned char Mat image=Mat(height,width,CV_8UC3,data2); //將unsigned char轉(zhuǎn)成Mat類型的數(shù)據(jù) QPixmap temp = MatToPixmap(image); ui->Process_image->setPixmap(temp); } }else { qDebug()<<"從數(shù)據(jù)庫獲取圖片失敗"; } }
到此,相信大家對“QT中怎么對Mat類進行操作”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學習!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。