## 离散余弦变换

### DCT 定义

M×N 矩阵 `A` 的二维 DCT 定义如下。

`$\begin{array}{l}\begin{array}{cc}{B}_{pq}={\alpha }_{p}{\alpha }_{q}\sum _{m=0}^{M-1}\sum _{n=0}^{N-1}{A}_{mn}\mathrm{cos}\frac{\pi \left(2m+1\right)p}{2M}\mathrm{cos}\frac{\pi \left(2n+1\right)q}{2N},& \begin{array}{l}0\le p\le M-1\\ 0\le q\le N-1\end{array}\end{array}\\ \\ \begin{array}{cccc}{\alpha }_{p}=\left\{\begin{array}{l}1/\sqrt{M},\\ \sqrt{2/M},\end{array}& \begin{array}{l}p=0\\ 1\le p\le M-1\end{array}& {\alpha }_{q}=\left\{\begin{array}{l}1/\sqrt{N},\\ \sqrt{2/N},\end{array}& \begin{array}{l}q=0\\ 1\le q\le N-1\end{array}\end{array}\end{array}$`

Bpq 称为 `A`DCT 系数。（请注意，MATLAB® 中的矩阵索引始终从 1 开始，而不是从 0 开始；因此，MATLAB 矩阵元素 `A(1,1)``B(1,1)` 分别对应于数学量 A00B00。）

DCT 是一种可逆变换，其逆变换由下式给出

`$\begin{array}{l}\begin{array}{cc}{A}_{mn}=\sum _{p=0}^{M-1}\sum _{q=0}^{N-1}{\alpha }_{p}{\alpha }_{q}{B}_{pq}\mathrm{cos}\frac{\pi \left(2m+1\right)p}{2M}\mathrm{cos}\frac{\pi \left(2n+1\right)q}{2N},& \begin{array}{l}0\le m\le M-1\\ 0\le n\le N-1\end{array}\end{array}\\ \\ \begin{array}{cccc}{\alpha }_{p}=\left\{\begin{array}{l}1/\sqrt{M},\\ \sqrt{2/M},\end{array}& \begin{array}{l}p=0\\ 1\le p\le M-1\end{array}& {\alpha }_{q}=\left\{\begin{array}{l}1/\sqrt{N},\\ \sqrt{2/N},\end{array}& \begin{array}{l}q=0\\ 1\le q\le N-1\end{array}\end{array}\end{array}$`

### DCT 变换矩阵

`$\begin{array}{ccc}{T}_{pq}=\left\{\begin{array}{l}\frac{1}{\sqrt{M}}\\ \sqrt{\frac{2}{M}}\mathrm{cos}\frac{\pi \left(2q+1\right)p}{2M}\end{array}& \begin{array}{l}p=0,\\ \\ 1\le p\le M-1,\end{array}& \begin{array}{l}0\le q\le M-1\\ \\ 0\le q\le M-1\end{array}\end{array}$`

### 使用离散余弦变换的图像压缩

```I = imread('cameraman.tif'); I = im2double(I);```

```T = dctmtx(8); dct = @(block_struct) T * block_struct.data * T'; B = blockproc(I,[8 8],dct);```

```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);```

```invdct = @(block_struct) T' * block_struct.data * T; I2 = blockproc(B2,[8 8],invdct);```

`imshow(I)`

```figure imshow(I2)```