JPEG 与视频压缩的关系
JPEG(Joint Photographic Experts Group)是一种静态图像有损压缩标准 ,虽然它并不直接用于视频压缩,但现代视频编码技术(MPEG、H.264、H.265)在空间压缩层面大量继承了 JPEG 的思想,例如:
- 分块处理(Block-based Coding)
- 颜色空间变换
- DCT 变换
- 量化与熵编码
JPEG 编码的设计目标
JPEG 的主要目标是:
- 在尽可能降低视觉感知损失的前提下压缩图像
- 针对自然图像(非线条图、非二值图)
- 提供可调节的压缩比与图像质量
JPEG 采用的是有损压缩 + 感知编码模型。
JPEG 编码的总体流程
JPEG 编码的完整流程如下:
markdown
原始 RGB 图像
↓
颜色空间转换(RGB → YCbCr)
↓
色度下采样
↓
图像分块(8×8)
↓
离散余弦变换(DCT)
↓
量化
↓
Zig-Zag 扫描
↓
熵编码(RLE + Huffman)
↓
JPEG 比特流
颜色空间转换(RGB → YCbCr)
1. 转换目的
人眼对亮度(Luminance)比对色度(Chrominance)更敏感,因此 JPEG 将图像从 RGB 转换为 YCbCr:
- Y:亮度分量
- Cb / Cr:蓝色差 / 红色差分量
2. 转换公式(典型)
Y=0.299R+0.587G+0.114B
Cb=−0.1687R−0.3313G+0.5B+128
Cr=0.5R−0.4187G−0.0813B+128
色度下采样(Chroma Subsampling)
1. 原理
利用人眼对色彩不敏感的特性,对 Cb / Cr 分量进行降采样。
2. 常见格式
| 格式 | 含义 |
|---|---|
| 4:4:4 | 不下采样 |
| 4:2:2 | 水平方向减半 |
| 4:2:0 | 水平和垂直方向均减半 |
JPEG 中 4:2:0 是最常见方案。
图像分块(8×8 Block)
1. 分块原因
- DCT 在小块上效果最佳
- 减少计算复杂度
- 便于局部特征建模
2. 块结构
- 每个 Y / Cb / Cr 分量单独分块
- 每块大小固定为 8×8 像素
- 图像尺寸不足时进行边缘填充
离散余弦变换(DCT)
1. 作用
将空间域像素值转换为频率域系数:
- 左上角:直流分量(DC)
- 其余:交流分量(AC)
2. DCT 特性
- 能量高度集中在低频
- 高频系数接近 0
- 为量化提供基础
量化(Quantization)
1. 有损压缩的关键步骤
量化是 JPEG 中唯一的有损环节。

- 使用不同的量化表
- 高频量化步长更大
- 低频保留更多细节
2. 质量因子(Quality Factor)
- 质量因子越低 → 压缩率越高 → 失真越明显
- 可动态调整量化表
Zig-Zag 扫描
1. 目的
将二维 8×8 量化系数转换为一维序列,使:
- 低频在前
- 高频在后
- 连续 0 更集中
2. 扫描顺序示意
0 → 1 → 5 → 6
↓ ↓
2 → 4 → 7
熵编码(Entropy Coding)
1. DC 系数编码
- 使用差分编码(DPCM)
- 当前 DC - 前一块 DC
2. AC 系数编码
- 游程编码(RLE)
- Huffman 编码
3. 压缩效果
- 连续 0 被高效表示
- 高频大量 0 压缩率极高
JPEG 解码流程
解码过程与编码流程基本相反:
JPEG 文件/码流
↓
解析 JPEG 文件结构(Marker)
↓
熵解码(Huffman)
↓
反 Zig-Zag 扫描
↓
反量化(Dequantization)
↓
IDCT(反离散余弦变换)
↓
块拼接(MCU 重组)
↓
色度上采样
↓
颜色空间转换(YCbCr → RGB)
↓
输出像素图像
JPEG 文件结构解析(解码前准备)
1. JPEG 文件由 Marker 组成
JPEG 解码第一步不是算 DCT,而是解析文件结构。
常见 Marker:
| Marker | 含义 |
|---|---|
| SOI | 图像开始 |
| APPn | 应用段 |
| DQT | 量化表 |
| DHT | Huffman 表 |
| SOF0 | 图像基本信息 |
| SOS | 扫描开始 |
| EOI | 图像结束 |
2. 解码器需提前获取的信息
- 图像宽高
- 分量数(Y、Cb、Cr)
- 采样因子(如 4:2:0)
- 量化表
- Huffman 表
如果 Marker 顺序或参数异常,解码直接失败
熵解码(Entropy Decoding)
JPEG 默认使用 Huffman 编码。
1. 扫描段(SOS)之后是真正的压缩数据
- 所有压缩的 DCT 系数都在 SOS 后
- 按 MCU(Minimum Coded Unit)解码
2. DC 系数解码
(1)差分编码
JPEG 中 DC 系数采用 DPCM:

(2)解码步骤
- 读取 Huffman 编码,得到 category(比特数)
- 再读取 category 位,得到差分值
- 累加得到当前 DC
AC 系数解码
(1)RLE + Huffman
AC 系数使用 (RunLength, Size) 方式:
- RunLength:连续 0 的个数
- Size:非 0 值的比特长度
(2)特殊符号
| 符号 | 含义 |
|---|---|
| EOB (0x00) | 块结束 |
| ZRL (0xF0) | 16 个连续 0 |
(3)解码流程
- Huffman 解码得到 (Run, Size)
- 填充 Run 个 0
- 读取 Size 位得到非 0 值
- 重复直到 64 个系数或 EOB
反 Zig-Zag 扫描
1. 目的
将一维序列恢复为 8×8 二维矩阵。
2. 原因
编码阶段 Zig-Zag 是为了让低频在前、高频在后;
解码阶段需按固定表逆序恢复。
3. 输出
得到量化后的 8×8 DCT 系数矩阵。
反量化(Dequantization)
1. 解码阶段的恢复公式

- Q(u,v):解码后的量化值
- Qtable:对应分量的量化表
2. 注意事项
- Y、Cb、Cr 可能使用不同量化表
- 精度影响最终图像质量
反离散余弦变换(IDCT)
1. IDCT 的作用
将频域数据转换回空间域像素残差。

2. 实现方式
- 浮点 IDCT
- 定点 / 整数 IDCT(工程中常用)
3. Level Shift 反向操作
- 编码前:像素 − 128
- 解码后:像素 + 128
块拼接(MCU 重组)
1. MCU(最小编码单元)
- MCU = 若干个 Y 块 + Cb 块 + Cr 块
- 数量取决于采样因子(如 4:2:0)
2. 拼接方式
- 按图像扫描顺序(左→右,上→下)
- 每个块输出 8×8 像素
色度上采样(Chroma Upsampling)
1. 为什么需要上采样
编码阶段对色度进行了下采样,解码必须恢复到与亮度同分辨率。
2. 常见方法
- 最近邻
- 双线性插值(最常用)
- 高质量滤波
颜色空间转换(YCbCr → RGB)
1. 转换公式
R=Y+1.402(Cr−128)
G=Y−0.34414(Cb−128)−0.71414(Cr−128)
B=Y+1.772(Cb−128)
2. 输出裁剪
- 像素值裁剪到 [0,255]
- 防止溢出
JPEG 解码中的常见问题
1. 块错位 / 花屏
- MCU 顺序错误
- 采样因子处理错误
2. 灰度正常,颜色异常
- Cb/Cr 量化表或 Huffman 表错误
- YCbCr → RGB 转换错误
3. 图像偏亮或偏暗
- 忘记 Level Shift
- IDCT 精度问题
总结
JPEG 编码通过:
- 感知模型
- 分块 DCT
- 量化 + 熵编码
实现了在视觉质量与压缩率之间的平衡。