[OpenCV Qt教程] 如何在內存中壓縮圖像


本文譯自:http://www.robot-home.it/blog/en/software/tutorial-opencv-qt-comprimere-un-immagine-in-memoria/

修正了原程序中的文字錯誤。


在這個簡短的教程中,我會展示一個壓縮圖像的簡單步驟。這個操作用處很大,比如獲取網絡攝像頭的圖像,這些圖像要發送到另一台設備上必須經過壓縮。

這個程序充分利用了我們之前看到的兩個教程,如果你還沒有看過,我建議你先閱讀之前的教程,它分為第一部分第二部分

與先前的教程不同,這次我們要顯示兩個widget:一個顯示原始圖像,另一個顯示壓縮過的圖像。這使得我們能直觀的評估壓縮質量。

壓縮質量可通過一個滑塊調節:0代表最低質量、最高壓縮率,100代表最高質量、最低壓縮率。

你還可以選擇JPEG或PNG兩種壓縮格式,你會看到JPEG圖像比PNG的圖像質量要低,但是體積更小。

將之前的教程作為參考,我們要做的修改只有一個函數:TimerEvent ( QTimerEvent * event) :

void MainWindow::timerEvent(QTimerEvent *event)
{
    Q_UNUSED(event);

    cv::Mat raw;
    mCapture >> raw;

    // >>>>> Params from widgets
    QString comprType;
    int quality = ui->horizontalSlider_quality->value();
    int compr;

    if( ui->radioButton_jpeg->isChecked() )
    {
        comprType = ".jpg";
        compr = cv::IMWRITE_JPEG_QUALITY;
    }
    else
    {
        comprType = ".png";
        quality = qMin( 9, quality/10 ); // PNG quality is in [0,9] range
        compr = cv::IMWRITE_PNG_COMPRESSION;
    }
    // <<<<< Params from widgets

    // >>>>> FPS Calculation
    static int frameCount = 0;
    static qreal timeAcc = 0;
    static qreal fps=0.0;

    int nFrm = 10; // 10 frames

    qreal elapsed = (qreal)mFpsTimer.elapsed();
    timeAcc += elapsed;
    frameCount++;

    if(frameCount%nFrm==0) // Update every "nFrm" frames
    {
        fps = 1000.0/(timeAcc/nFrm);
        timeAcc=0;
        frameCount=0;
    }

    mFpsTimer.restart();
    // <<<<< FPS Calculation

    if( !raw.empty() )
    {
        // >>>>> Jpeg compression in memory
        vector<uchar> buf; // Memory buffer
        vector<int> params;

        params.push_back( compr );
        params.push_back( quality ); // Quality of compression

        cv::imencode( comprType.toLocal8Bit().data(), raw, buf, params );
        cv::Mat compressed;
        cv::imdecode( cv::Mat(buf), cv::IMREAD_COLOR, &compressed );

        mInfoLabel.setText( tr("<b>Compression quality:</b> %1 - <b>Raw data:</b> %2 bytes - <b>Compressed data:</b> %3 bytes - <b>FPS:</b> %4")
                            .arg(quality).arg(raw.cols*raw.rows*raw.channels()).arg(buf.size()).arg(fps) );
        // <<<<< Jpeg compression in memory

        // Show the images
        ui->widget_raw->showImage( raw );

        if( !compressed.empty())
            ui->widget_compressed->showImage( compressed );
    }
}

在8到25行,讀取由GUI設置的的參數。26到45行,計算FPS來表示壓縮占用的資源。壓縮操作是在第56行使用OpenCV的 imencode 函數完成的,傳入與壓縮類型有關的參數以及壓縮質量。

第58行,從緩存中解壓縮圖像,使圖像可以在右側的widget中顯示。

在客戶端/服務器程序中,第56行由服務器在發送圖像之前執行,而第58行則由客戶端在收到圖像數據時執行。

本例代碼:http://www.robot-home.it/blog/download/Tutorial/ImageCompressionDemo.rar


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM