📄 一句话概括
变换本身不压缩,它做的是把能量集中到少数系数上——它的价值在于【给量化创造好压的形状】。
📝 本节和前面几节的关系
6.3.1 讲了预测,这一节讲预测之后残差要走的下一步:变换。
一、变换在做什么
以最常见的 DCT 为例:把一个 8×8 的像素块,换成 8×8 个频率系数。 它不减少数据的个数,8×8 还是 8×8。 但它改变了数据的分布——这就是它全部的价值所在。
二、能量集中是什么意思
原始像素块里,能量是平均分布的——每个位置都差不多重要。 换到频域之后,能量集中到左上角(低频分量)。 为什么会这样?因为自然图像大多是平滑的,相邻像素差别很小—— 这种【平滑】在频域上,恰好表现为【低频强、高频弱】。
三、之后发生什么
① 量化对系数按重要性分配精度——右下角的高频系数被大量变成 0。 ② 按 zigzag(之字形)顺序扫描,让那些 0 连成一片。 ③ 熵编码再把这一长串 0 轻松压掉。 所以真正的顺序是:变换创造形状 → 量化制造 0 → 熵编码吃掉 0。
四、为什么不能跳过变换
如果在像素域直接量化,你看不出【哪个像素不重要】——每个位置看起来都一样。 变换之后才有依据:高频不重要,低频重要——这个依据来自人眼的感知特性。 所以变换是把【空间】换成【感知敏感的维度】,让后面的取舍有据可依。 这就是 4.2.2 说过的那句话:先把信息摊开,才有得挑。
五、动手 Demo:变换把能量集中到哪里
变换本身不压缩,它做的是【把能量集中到少数系数上】。
rows = [("原始块", "8x8 个像素值", "能量平均分布"),
("DCT 变换", "换成 8x8 个频率系数", "能量集中到左上角"),
("量化", "对系数按重要性分配精度", "右下大量变 0"),
("扫描", "按 zigzag 顺序读", "0 连成一片")]
for a, b, c in rows:
print("%-8s %-22s %s" % (a, b, c))
实跑输出:
--------------------------------------------------------------------
变换把能量集中到哪里
--------------------------------------------------------------------
变换本身不压缩,它做的是【把能量集中到少数系数上】。
步骤 做什么 结果
---------------------------------------------------------
原始块 8x8 个像素值 能量平均分布
DCT 变换 换成 8x8 个频率系数 能量集中到左上角
量化 对系数按重要性分配精度 右下大量变 0
扫描 按 zigzag 顺序读 0 连成一片
关键在第三步:**一旦右下角变成一片 0,后面的熵编码就轻松了。**
所以变换的价值不是【压缩】,而是**给量化创造好压的形状**。
关键在第三步:一旦右下角变成一片 0,后面的熵编码就轻松了。 所以变换的价值不是【压缩】,而是给量化创造好压的形状。
30 秒实验
- 找一张自然照片与一张纯噪声图,各做一次 DCT。
- 对比两者的频谱能量分布有什么不同。
常见误区
- 以为变换会丢信息。它是可逆的,一个比特都不丢。
- 把变换当成压缩。它是【准备步骤】,真正丢信息的是量化。
自测三问(点开对答案)
1. 变换的作用是什么? —— 把能量集中到少数系数上,为量化创造条件。 2. DCT 变换之后能量集中在哪里? —— 左上角的低频分量。 3. zigzag 扫描的目的是什么? —— 让量化产生的 0 连成一片,方便后面的熵编码。- ☐ 下一节(6.3.3 量化)
相关笔记
- 量化 — 变换之后紧接着的一步
- 预测编码 — 它处理的正是残差
- 音频编码 — 音频那边也有这一步
- 🎬 FFmpeg入门详解 · 索引