[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

上一篇:JAVA多线程(一)


下一篇:rest api设计的一般原则