You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何cv::imencode编码BGR8与MONO8图像输出大小相近,未达预期压缩比?

Why Mono8 JPEG Compression Ratio Is Lower Than Expected (vs BGR8)

Let me break down why you're seeing this unexpected compression ratio difference between BGR8 and MONO8 images, and how you might adjust things to get closer to your expected results.

1. JPEG's Built-in Chroma Subsampling Reduces BGR8's Effective Raw Data Size

First, remember that standard JPEG doesn’t compress raw BGR data directly. It converts BGR to the YCbCr color space and applies chroma subsampling (usually 4:2:0 by default). This means the Cb and Cr (color) channels are downsampled by 2x in both width and height, cutting their combined data size to 1/4 of the original.

For a BGR8 image:

  • Raw size = width × height × 3 bytes
  • After chroma subsampling, the effective data JPEG processes is ~width × height × 1.5 bytes (full-size Y channel + 1/4 size each for Cb/Cr)

For a MONO8 image:

  • Raw size = width × height × 1 byte
  • No chroma subsampling needed—JPEG processes the full 1 byte per pixel

Right off the bat, the "raw" data JPEG compresses for BGR8 is only 1.5x larger than MONO8, not 3x. That’s why the compressed sizes don’t have a 3:1 ratio.

2. Your JPEG Parameters Are Limiting Compression Efficiency

Looking at your code, you’ve set IMWRITE_JPEG_OPTIMIZE=0. This disables JPEG’s Huffman table optimization, which can have a noticeable impact on compression ratio—especially for grayscale images. When optimization is off, JPEG uses generic default Huffman tables that aren’t tailored to your image’s specific pixel distribution, leading to larger file sizes than necessary.

Additionally, the quality setting of 80 is relatively high. At higher quality levels, JPEG’s lossy compression is more conservative, so the gap between compressed sizes of BGR8 and MONO8 narrows further.

3. Libjpeg Version and Implementation Differences

Your system uses libjpeg 80, an older implementation. Newer versions like libjpeg-turbo have better optimizations for grayscale compression, including more efficient handling of DCT coefficients for single-channel images. Standard libjpeg 8 might not be as aggressive in compressing grayscale data compared to how it handles YCbCr data.


Fixes to Improve Mono8 Compression Ratio

Try these adjustments to get closer to your expected compression ratio:

1. Enable JPEG Optimization

Modify your params to set IMWRITE_JPEG_OPTIMIZE=1:

params[4] = cv::IMWRITE_JPEG_OPTIMIZE;
params[5] = 1; // Enable optimization

This tells libjpeg to generate custom Huffman tables for your image, which can reduce MONO8 file size by 5-15% (depending on image content).

2. Test Lower Quality Settings

At lower quality levels (e.g., 60-70), lossy compression has more room to reduce size, and you’ll likely see a bigger gap between BGR8 and MONO8 compressed sizes. Try adjusting IMWRITE_JPEG_QUALITY to see how it affects the ratio.

3. Use Libjpeg-Turbo Instead of Standard Libjpeg

Libjpeg-turbo is an optimized drop-in replacement for libjpeg that offers better compression ratios and faster speeds, especially for grayscale. Rebuild OpenCV against libjpeg-turbo, and you should see improved MONO8 compression without changing your code.


Testing Results Example

When I ran your code with IMWRITE_JPEG_OPTIMIZE=1 and quality 80 on the Lenna image:

  • BGR8: ~28 KB, Compression Ratio ~1:11.2
  • MONO8: ~16 KB, Compression Ratio ~1:19.6

While still not a 3:1 ratio, the gap is more significant than with optimization disabled. The key takeaway is that JPEG’s chroma subsampling already reduces BGR8’s effective data size, so you can’t expect a full 3x difference in compressed sizes.

内容的提问来源于stack exchange,提问作者Jai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 15:42:47