离散余弦变换
DCT 定义
离散余弦变换 (DCT) 将图像表示为不同幅值和频率的正弦的总和。dct2
函数计算图像的二维离散余弦变换 (DCT)。对于典型图像,DCT 具有这样的属性,即关于图像的大部分视觉上显著的信息只集中在 DCT 的几个系数中。因此,DCT 经常用于图像压缩应用。例如,DCT 是国际标准有损图像压缩算法 JPEG 的核心。此名称来自制定标准的工作组:联合图像专家组,即 Joint Photographic Experts Group。
M×N 矩阵 A
的二维 DCT 定义如下。
值 Bpq 称为 A
的 DCT 系数。(请注意,MATLAB® 中的矩阵索引始终从 1 开始,而不是从 0 开始;因此,MATLAB 矩阵元素 A(1,1)
和 B(1,1)
分别对应于数学量 A00 和 B00。)
DCT 是一种可逆变换,其逆变换由下式给出
逆 DCT 方程可以理解为任何 M×N 矩阵 A
可写为以下形式的 MN 函数之和:
这些函数称为 DCT 的基函数。然后,DCT 系数 Bpq 可视为应用于每个基函数的权重。对于 8×8 矩阵,该图可表示为 64 个基函数。
构成 8×8 矩阵的 64 个基函数
水平频率从左到右递增,垂直频率从上到下递增。左上角的常量值基函数通常称为 DC 基函数,对应的 DCT 系数 B00 通常称为 DC 系数。
DCT 变换矩阵
使用 Image Processing Toolbox™ 软件有两种计算 DCT 的方法。第一种方法是使用 dct2
函数。dct2
使用基于 FFT 的算法对大型输入实现快速计算。第二种方法是使用 DCT 变换矩阵,该矩阵由函数 dctmtx
返回,对于小型方阵输入(如 8×8 或 16×16)可能更高效。M×M 变换矩阵 T
由下式给出
对于 M×M 矩阵 A
,T*A
是 M×M 矩阵,其列包含由 A
的列组成的一维 DCT。A
的二维 DCT 可以计算为 B=T*A*T'
。由于 T
是实数正交矩阵,它的逆矩阵与它的转置矩阵相同。因此,B
的逆二维 DCT 由 T'*B*T
给出。
使用离散余弦变换的图像压缩
此示例说明如何使用离散余弦变换 (DCT) 压缩图像。该示例计算输入图像中 8×8 个数据块的二维 DCT,丢弃(设置为零)每个数据块中 64 个 DCT 系数中除 10 个以外的所有系数,然后使用每个数据块的二维逆 DCT 重构图像。该示例使用变换矩阵计算方法。
在 JPEG 图像压缩算法中使用 DCT。将输入图像分成 8×8 或 16×16 个数据块,并对每个数据块计算二维 DCT。然后对 DCT 系数进行量化、编码和传输。JPEG 接收机(或 JPEG 文件读取器)对量化的 DCT 系数进行解码,计算每个数据块的逆二维 DCT,然后将这些数据块一起放回单个图像中。对于典型图像,许多 DCT 系数的值接近于零。可以丢弃这些系数,而不会严重影响重构图像的质量。
将图像读入工作区,并将其转换为 double
类。
I = imread('cameraman.tif');
I = im2double(I);
计算图像中 8×8 个数据块的二维 DCT。函数 dctmtx
返回 N×N DCT 变换矩阵。
T = dctmtx(8); dct = @(block_struct) T * block_struct.data * T'; B = blockproc(I,[8 8],dct);
丢弃每个数据块中 64 个 DCT 系数的大部分系数,仅保留 10 个。
mask = [1 1 1 1 0 0 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]; B2 = blockproc(B,[8 8],@(block_struct) mask .* block_struct.data);
使用每个数据块的二维逆 DCT 重构图像。
invdct = @(block_struct) T' * block_struct.data * T; I2 = blockproc(B2,[8 8],invdct);
并排显示原始图像和重构图像。尽管几乎 85% 的 DCT 系数被丢弃,导致重构图像的质量有所下降,但它仍是清晰可辨的。
imshow(I)
figure imshow(I2)