Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Image processing 如何指定JPEG压缩的比特率?_Image Processing_Compression_Opencv_Imagemagick_Jpeg - Fatal编程技术网

Image processing 如何指定JPEG压缩的比特率?

Image processing 如何指定JPEG压缩的比特率?,image-processing,compression,opencv,imagemagick,jpeg,Image Processing,Compression,Opencv,Imagemagick,Jpeg,有没有办法以特定的比特率对JPEG进行编码 目前,我正在使用imagemagick的convert: convert Lenna-gray-100.jpeg -quality 1.1111 test.jpeg 比特率随着质量的提高而增加,但它是非线性的。我想显式地控制比特率。它不必精确,但我希望它合理地接近(在指定设置的0.1 bpp范围内) 有没有允许以特定比特率对图像进行编码的编码器?它不一定是imagemagick,我会选择任何可行的(最好是在Linux上) 一种愚蠢的方法是在-qual

有没有办法以特定的比特率对JPEG进行编码

目前,我正在使用imagemagick的
convert

convert Lenna-gray-100.jpeg -quality 1.1111 test.jpeg
比特率随着质量的提高而增加,但它是非线性的。我想显式地控制比特率。它不必精确,但我希望它合理地接近(在指定设置的0.1 bpp范围内)

有没有允许以特定比特率对图像进行编码的编码器?它不一定是imagemagick,我会选择任何可行的(最好是在Linux上)

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

编辑:

所以我厌倦了,决定用快速(但愚蠢)的方式做事

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

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

因此,对于较低质量的值,比特率的变化非常细微,但在大约80之后变得粗糙

下面是一些以某种目标比特率对图像进行编码的示例代码。我使用OpenCV是因为它允许内存中的JPEG编码(无需I/O)。虽然我最初打算用Python来模拟它,但不幸的是Python OpenCV包装器没有公开内存中的编码功能。所以我用C++写的。 最后,我考虑在质量上使用线性插值以接近目标比特率,但由于
cv::imencode
只接受整数参数,因此无法设置非整数JPEG质量。OpenCV和imagemagick之间的质量等级似乎也有所不同,因此从OpenCV中获取插值质量参数并在imagemagick的
convert
中使用效果不佳

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

有人能提出更好的建议吗

代码:


我知道在控制JPEG编码器(例如;)的输出比特率方面存在很多工作,而且JPEG2000中也存在这样的控制。不幸的是,我不确定JPEG是否标准化了任何一种比特率控制,或者是否在公共库中实现了这种控制。您可能需要编写自己的方法,例如使用某种二进制搜索

但是,我可能又错了——如果是的话,我很想听听这样一个图书馆


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

JPG中的比特率质量比完全取决于内容。如果您想以特定比特率编码,我建议您进行两次: 1.以固定的质量因子编码(更接近目标比特率更好,可以基于图形) 2.根据其大小,以更高或更低的质量重新编码原始文件。同样,这可以基于您的图表或类似的内容

您还可以无限期地重复最后一步,以获得所需的准确比特率


我会用各种极端情况来测试这一点,比如非常嘈杂/繁忙的图像、黑色矩形或平滑的渐变。

谢谢你的回答和链接。不幸的是,我的大学没有订阅SpringerLink,但我读了第二篇论文。回答你的问题:对于严肃的图像工作,我使用C/C++,但如果我最终为此编写了自己的方法,我可能会使用Python/Bash,因为我很懒。这也会更简单。不管怎样,如果你偶然发现了一个解决这个问题的好方法,请告诉我们:)我用示例代码更新了这个问题。我不认为这是一个好的解决方案,但这是我目前唯一的解决方案。我想发布同样的答案,但我自己也不确定。这是有意义的,因为JPEG比特流不是像EZW、SPIHT或JPEG2000那样的嵌入式比特流。换句话说,您不能简单地截断JPEG比特流以接收较低质量的图像版本,但使用上述其他编解码器,您(某种程度上)可以。建议:删除for循环,替换为search。我不敢相信有人会想要一个质量因子在1->~30或~99->100范围内的JPEG编码。您还可以为各种不同的图像类型创建图形,并为搜索找到更好的初始起点。这是非常幼稚的,因为你甚至不考虑质量(例如PSNR);选择不同的量化表可能会得到您想要的比特率,但质量要高得多。谢谢您的建议。搜索将提高代码的效率,但目前这并不是一个真正的问题,因为它已经足够快了。你对质量的看法是对的——大多数普通人不需要那么低质量的JPEG,因为它们看起来像垃圾。然而,我自己对这些图像感兴趣,因为我正在研究图像退化。关于量化表的观点很有趣——我想我会研究一下。它可能需要远离OpenCV并使用类似ijg的东西,因为OpenCV似乎没有公开量化表。
#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