如何为JPEG压缩指定比特率? [英] How to specify bitrate for JPEG compression?

查看:78
本文介绍了如何为JPEG压缩指定比特率?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种方法可以以特定的比特率编码JPEG?

Is there a way to encode JPEG at a specific bitrate?

目前,我正在使用imagemagick的 convert :

Presently, I'm using imagemagick's convert:

convert Lenna-gray-100.jpeg -quality 1.1111 test.jpeg

比特率随质量而增加,但它是非线性的.我想明确地控制比特率.不一定是准确的,但我希望它合理地接近(例如,在指定设置的0.1 bpp以内).

Bitrate increases with quality, but it's non-linear. I want to control the bitrate explicitly. It doesn't have to be exact, but I want it reasonably close (within, say 0.1 bpp of the specified setting).

那里是否存在允许以特定比特率对图像进行编码的编码器?不一定是imagemagick,我会采取一切可行的措施(最好在Linux上).

Is there any encoder there that allows images to be encoded at a particular bit-rate? It doesn't have to be imagemagick, I'll take whatever works (preferably on Linux).

一种愚蠢的方法是在 -quality 参数上使用分数值,直到出现接近目标比特率的值,但我希望有一个更优雅的解决方案.

A dumb way to do this would be to play around with fractional values to the -quality parameter until something close to the target bitrate comes out, but I'm hoping for a more elegant solution.

所以我很无聊,决定以快速(但愚蠢)的方式做事.

So I got bored and decided to do things the quick (but stupid) way.

首先,这是imagemagick的-质量与比特率的关系图:

First, here's a graph of imagemagick's -quality vs bitrate:

顺便说一句,这是我使用的图像:

BTW, here's the image I used:

因此,对于较低的质量值,比特率的变化相当不错,但在大约80后会变得很粗糙.

So the change in bitrate is quite fine for lower quality values, but becomes coarse after about 80.

以下是一些示例代码,用于以某种目标比特率对图像进行编码.我使用OpenCV是因为它允许内存中JPEG编码(无需I/O).当我最初打算用Python模拟时,不幸的是Python OpenCV包装器没有公开内存中的编码功能.所以我用C ++编写的.

Here's some sample code to encode an image at some target bitrate. I used OpenCV cause it allows for in-memory JPEG encoding (no I/O necessary). While I originally was going to mock this up with Python, unfortunately the Python OpenCV wrappers don't expose the in-memory encoding functionality. So I wrote it in C++.

最后,我正在考虑对质量使用线性插值以使其更接近目标比特率,但是由于 cv :: imencode 仅接受整数参数,因此无法设置非整数JPEG质量.OpenCV和imagemagick之间的质量等级似乎也有所不同,因此从OpenCV插入插值质量参数并在imagemagick的 convert 中使用效果不佳.

Lastly, I was thinking of using linear interpolation on the quality to get closer to the target bitrate, but since cv::imencode only accepts integer parameters, it's not possible to set a non-integer JPEG quality. The quality scale between OpenCV and imagemagick seems to differ somewhat as well, so taking the interpolated quality parameter from OpenCV and using in imagemagick's convert didn't work well.

这意味着输出比特率不等于目标比特率,尤其是在较高比特率(> 1)时.但这很接近.

This means that the output bitrate isn't equal to the target bitrate, especially at higher bitrates ( > 1). But it's close.

有人可以提出更好的建议吗?

Can anyone suggest something better?

代码:

#include <stdio.h>
#include <cv.h>
#include <highgui.h>
#include <assert.h>
#include <vector>

using cv::Mat;
using std::vector;

#define IMENCODE_FMT   ".jpeg"
#define QUALITY_UBOUND 101
#define BITS_PER_BYTE  8

int
main(int argc, char **argv)
{
    if (argc != 4)
    {
        fprintf(stderr, "usage: %s in.png out.jpeg bpp\n", argv[0]);
        return 1;
    }

    char *fname_in = argv[1];
    char *fname_out = argv[2];
    float target;
    sscanf(argv[3], "%f", &target);

    Mat orig = cv::imread(fname_in);
    int pixels = orig.size().width * orig.size().height * orig.channels();

    vector<unsigned char> buf;
    vector<int> params = vector<int>(2);
    params[0] = CV_IMWRITE_JPEG_QUALITY;
    int q;
    double bpp = 0.0;

    for (q = 1; q < QUALITY_UBOUND; ++q)
    {
        params[1] = q;
        cv::imencode(IMENCODE_FMT, orig, buf, params);
        bpp = (double)buf.size() * BITS_PER_BYTE / pixels;
        if (bpp > target)
            break;
    }

    cv::imwrite(fname_out, orig, params);
    printf("wrote %s at %d%% quality, %.2fbpp\n", fname_out, q, bpp);

    return 0;
}

编译并运行:

g++ -c -Wall -ggdb -I../c -I../blur `pkg-config --cflags opencv` -Wno-write-strings jpeg-bitrate.cpp -o jpeg-bitrate.o
g++ -I../c `pkg-config --cflags opencv` `pkg-config --libs opencv` -lboost_filesystem jpeg-bitrate.o -o jpeg-bitrate.out
rm jpeg-bitrate.o
misha@misha-desktop:~/co/cpp$ ./jpeg-bitrate.out Lenna-gray.png test.jpeg 0.53
wrote test.jpeg at 88% quality, 0.55bpp

推荐答案

我知道在控制JPEG编码器的输出比特率方面存在很多工作(例如第二张纸),并且此类控件存在于JPEG2000中.不幸的是,我不确定任何类型的比特率控制是否已针对JPEG标准化或在通用库中实现.您可能必须编写自己的方法,例如使用某种二进制搜索...

I know a lot of work exist on controlling the output bitrate of a JPEG encoder (e.g. 1st paper ; 2nd paper), and that such controls exist in JPEG2000. Unfortunately, I'm not sure any kind of bitrate control is standardized for JPEG, or implemented in common libraries. You may have to code your own method, using some kind of binary search for instance...

但是同样,我可能会弄错了-如果是这样,我很想听听有关这种图书馆的信息.

But again, I may be mistaken - and if so, I'd love to hear about such a library.

出于好奇,您使用的是哪种语言?

Just out of curiosity, what language are you using ?

这篇关于如何为JPEG压缩指定比特率?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆