使用 python-opencv 压缩图像实际上会产生更大的尺寸

问题描述 投票:0回答:1

我想使用 python 压缩内存中的图像。

使用答案中的代码https://stackoverflow.com/a/40768705我希望更改“质量参数”(90)我会得到更小的结果图像。

encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 90]
result, enc_img = cv2.imencode('.jpg', img_np, encode_param)

我最初的计划是降低这个“质量参数”,直到获得所需的图像尺寸。 像这样:

def compress_img(img: bytes, max_size: int = 102400):
    """

    @param max_size: maximum allowed size in bytes
    """
    quality = 90
    while len(img) > max_size:
        img = _compress_img(img, quality=quality)
        quality -= 5
        if quality < 0:
            raise ValueError(f"Too low quality: {quality}")
    return img

但是在运行一些测试之后,我实际上得到的结果图像比原始图像更大。我不明白原始大小如何小于压缩后的大小。这个逻辑有什么问题吗?

original size: 125.07 kb
load to cv2 size: 4060.55 kb
compressed size: 186.14 kb

这是完整代码:

import cv2
import requests
import numpy as np


def request_img(img_url: str) -> bytes:
    r = requests.get(img_url, stream=True)
    img = r.raw.read()
    return img


if __name__ == '__main__':
    url = "https://m.media-amazon.com/images/I/71bUROETvoL._AC_SL1500_.jpg"
    img_bytes = request_img(url)
    # the original size of image is 128073 bytes `len(img_bytes)`
    with open("__img_orig.jpg", "wb") as f:
        f.write(img_bytes)
    print(f"original size: {round(len(img_bytes)/ 1024, 2)} kb")

    # after I load image to cv2 - it becomes `4158000` bytes
    image_np = np.frombuffer(img_bytes, np.uint8)
    img_np = cv2.imdecode(image_np, cv2.IMREAD_COLOR)
    print(f"load to cv2 size: {round(len(img_np.tobytes()) / 1024, 2)} kb")

    # resulting "compressed" size is `190610` bytes which is 48% more than original sie. How can it be???
    encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 90]
    result, enc_img = cv2.imencode('.jpg', img_np, encode_param)
    res_img_bytes = enc_img.tobytes()
    print(f"compressed size: {round(len(res_img_bytes) / 1024, 2)} kb")
    with open("__img_compress.jpg", "wb") as f:
        f.write(res_img_bytes)

python opencv python-imaging-library image-compression
1个回答
0
投票

原始 JPEG 压缩质量为 81,大小为 125kB。请参阅下面的方法来获得质量评估。

图像为 1500x924 RGB 像素,因此解压后将占用内存 1500x924x3 字节,即 4,158,000 字节。

你用质量 90 压缩它,得到了 186kB,这是可以预料的,因为原始质量是 81,即更低。


以 90 质量压缩它是毫无意义的,无论如何你都无法恢复超过 81 的质量。失去的就是失去了。


您可以使用以下方法确定 JPEG 编码的质量:

exiftool -JPEGQualityEstimate IMAGE.JPG

或者使用 ImageMagick 如下:

magick IMAGE.JPG -format %Q info:
© www.soinside.com 2019 - 2024. All rights reserved.