本文譯自: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