数组实现DCT图像压缩的核心是:先用双重循环和预计算余弦表完成一维DCT-II,再通过行列分离法扩展至二维;压缩靠量化表除法取整与高频系数截断,重构时逆序IDCT并裁剪像素值。

用数组实现离散余弦变换(DCT)并用于图像压缩,核心是把图像看作二维数值矩阵,通过数学运算将其从像素空间转到频率空间,再靠舍弃不敏感的高频系数来压缩。整个过程不依赖现成函数库也能完成,关键是理解每一步的数组操作逻辑。
用纯数组实现一维DCT-II(最常用形式)
先从最基础的一维开始,这是二维DCT的构建块。对长度为 N 的输入数组 x[n](n = 0…N−1),DCT-II 公式为:
X[k] = α(k) × Σ x[n] × cos[π×(n+0.5)×k / N],其中 k = 0…N−1
α(k) 是归一化系数:k=0 时为 1/√N,其余为 √(2/N)
- 用双重循环实现:外层遍历 k(频率索引),内层遍历 n(采样点)
- cos 项可预先计算并存入二维查找表(如 dct_matrix[N][N]),避免重复调用三角函数,提升速度
- 注意浮点精度,建议统一用 double 类型存储中间结果
- 验证正交性:对同一组数据做 DCT 再 IDCT,应基本还原原数组(误差在 1e−12 量级内)
扩展到二维DCT:先按行再按列(或反之)
图像本质是二维数组,标准做法是分块处理(如 8×8)。对一个 8×8 块 A,二维DCT等价于:DCT(A) = M × A × Mᵀ,其中 M 是 8×8 的一维DCT基矩阵
- 先对每行做一维DCT → 得中间矩阵 B
- 再对 B 的每列做一维DCT → 得最终频域系数矩阵 D
- 也可先列后行,结果一致(因矩阵乘法满足 (M×A)×Mᵀ = M×(A×Mᵀ))
- 实际编码中,避免显式构造大矩阵,直接用嵌套循环模拟矩阵乘法更省内存
图像压缩实战:量化 + 截断是关键压缩动作
DCT本身不压缩,只是重排能量。真正压缩发生在后续两步,都基于数组操作:
- 量化:用一个 8×8 量化表 Q(如 JPEG 默认亮度表),对 D 中每个元素除以对应位置的 Q[i][j],再四舍五入取整。高频位置(右下角)Q 值大 → 结果更易为 0
- 截断/清零:设定阈值(如只保留左上 4×4 区域),将右下三角或 Z 字形扫描后第 32 位之后的系数全置 0
- 压缩率粗略估算:原始 64 个 float → 量化后可能只剩 15 个非零 int → 存储体积下降明显
- 注意:量化不可逆,是信息损失主因;IDCT 只能重建近似图像
重构图像:IDCT 数组实现与注意事项
逆变换公式与 DCT 类似,仅系数和 cos 相位略有调整。对量化后的 8×8 矩阵 Dq,IDCT 同样分两步:
- 先对每列做一维 IDCT → 得中间矩阵 C
- 再对每行做一维 IDCT → 得重建块 R
- IDCT 中的归一化系数需与 DCT 配对使用(例如 DCT 用 √(2/N),IDCT 就要补回 √(2/N) 或 1/√N)
- 重建块像素值可能超出 [0,255],需做截断(clip)或重缩放,否则显示发白或发黑
- 多个 8×8 块拼回原图时,注意保持行列顺序,避免错位

















