[OpenCV Qt教程] 如何在内存中压缩图像

来源:互联网 发布:统计软件使用次数 编辑:程序博客网 时间:2024/06/05 05:53

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

0 0
原创粉丝点击