欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

QT中對Mat類的一些操作詳解

 更新時間:2022年06月08日 15:07:29   作者:桂花年糕仔  
本文主要介紹了QT中對Mat類的一些操作詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

一、類型轉(zhuǎn)換

opencv在QT中的應用通常會涉及到這三者的轉(zhuǎn)換,即MatQImage、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:   //這種寫法表示并列關系
        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
}

二、保存至數(shù)據(jù)庫

我這里是直接將Mat類型的數(shù)據(jù)以二進制數(shù)據(jù)流的方式保存到數(shù)據(jù)庫中,有些文章是將文件名及其所在的路徑保存到數(shù)據(jù)庫中,這個還是要好看項目需求,個人而言,我這個要更復雜一點。
演示效果如下:

1??:基礎界面

2??:磨皮處理

3??:數(shù)據(jù)庫中的數(shù)據(jù)

4??:核心代碼

注意: 創(chuàng)建數(shù)據(jù)表的時候,字段的類型,一定要滿足數(shù)據(jù)的大小,比方說保存圖片一般使用blob相關的類型,其中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類的一些操作詳解的文章就介紹到這了,更多相關QT Mat操作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家! 

相關文章

  • C++實現(xiàn)賓館房間管理系統(tǒng)

    C++實現(xiàn)賓館房間管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C++實現(xiàn)賓館房間管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • 基于C++實現(xiàn)TCP聊天室功能

    基于C++實現(xiàn)TCP聊天室功能

    這篇文章主要為大家詳細介紹了基于C++實現(xiàn)TCP聊天室功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • C++中Operator類型強制轉(zhuǎn)換成員函數(shù)解析

    C++中Operator類型強制轉(zhuǎn)換成員函數(shù)解析

    轉(zhuǎn)換函數(shù)定義了由<類型說明符1>到<類型說明符2>之間的映射關系。可見,轉(zhuǎn)換函數(shù)是用來將一種類型的數(shù)據(jù)轉(zhuǎn)換成為另一種類型
    2013-09-09
  • 大數(shù)據(jù)情況下桶排序算法的運用與C++代碼實現(xiàn)示例

    大數(shù)據(jù)情況下桶排序算法的運用與C++代碼實現(xiàn)示例

    在排序元素很多的情況下,其實桶排序的性能并不是太高,這里我們配合單鏈表的直接插入排序,來看下一大數(shù)據(jù)情況下桶排序算法的運用與C++代碼實現(xiàn)示例:
    2016-07-07
  • 用C語言進行最基本的socket編程

    用C語言進行最基本的socket編程

    這篇文章主要介紹了C語言下socket編程的基本知識講解,包括最基本的客戶端發(fā)送及服務器端接受數(shù)據(jù)的實現(xiàn),需要的朋友可以參考下
    2015-11-11
  • Opencv檢測多個圓形(霍夫圓檢測,輪廓面積篩選)

    Opencv檢測多個圓形(霍夫圓檢測,輪廓面積篩選)

    本文主要介紹了Opencv檢測多個圓形(霍夫圓檢測,輪廓面積篩選),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-08-08
  • C++人工模擬棧實現(xiàn)方法

    C++人工模擬棧實現(xiàn)方法

    在本篇內(nèi)容里小編為大家整理了關于C++人工模擬棧實現(xiàn)方法和步驟,需要的朋友們可以學習下。
    2018-12-12
  • C++算法學習之分支限界法的應用

    C++算法學習之分支限界法的應用

    分支限界法常以廣度優(yōu)先或以最小耗費(最大效益)優(yōu)先的方式搜索問題的解空間樹。本文將詳細講解分支限界法的應用,需要的可以參考一下
    2022-05-05
  • C/C++ 中extern關鍵字詳解

    C/C++ 中extern關鍵字詳解

    這篇文章主要介紹了C/C++ 中extern關鍵字詳解的相關資料,需要的朋友可以參考下
    2017-06-06
  • C++中頭文件與源文件的作用詳解

    C++中頭文件與源文件的作用詳解

    這篇文章主要給大家介紹了關于C++中頭文件與源文件的作用的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用C++具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-05-05

最新評論