Step1:RGB 转 YCrCb
![YCbCr-color-spaces](https://i.loli.net/2020/10/22/vMSq9GLoD1azcCp.jpg)
图片中 8x8 的一小块:
62 | 55 | 55 | 54 | 49 | 48 | 47 | 55 |
62 | 57 | 54 | 52 | 48 | 47 | 48 | 53 |
61 | 60 | 52 | 49 | 48 | 47 | 49 | 54 |
63 | 61 | 60 | 60 | 63 | 65 | 68 | 65 |
67 | 67 | 70 | 74 | 79 | 85 | 91 | 92 |
82 | 95 | 101 | 106 | 114 | 115 | 112 | 117 |
96 | 111 | 115 | 119 | 128 | 128 | 130 | 127 |
109 | 121 | 127 | 133 | 139 | 141 | 140 | 133 |
对应的灰度图:
![灰度图](https://i.loli.net/2020/10/21/vMAebcth7fXrRCs.png)
DCT:分解为基的线性组合
![DCT Basis](https://i.loli.net/2020/10/21/MNtrgTWEeDQCsfc.png)
分解后的结果:
-211.8 | 9.2 | 6.3 | -2.7 | 5.3 | 0.8 | 3.1 | -1.1 |
-213.2 | 10.5 | 7.7 | -1.7 | 3.2 | 0.4 | 1. | -0.7 |
-213.5 | 9.5 | 10.2 | -0.9 | 1.4 | -2.5 | -1.2 | -0.8 |
-183.5 | -5.6 | 3.1 | 3.1 | -1.1 | 1.1 | -0.9 | 1.1 |
-141.1 | -26.9 | 3.3 | 0.7 | -0.4 | 1.3 | -0.2 | 0.4 |
-64.3 | -28.9 | -11.4 | -3.8 | -1.4 | -6.1 | 0.1 | -0.6 |
-24.7 | -27.6 | -11.5 | -2.2 | -4.9 | -4.3 | -3.7 | 1.3 |
6.7 | -24.1 | -15.2 | 0.4 | -5.3 | -1.2 | -2.5 | 0.1 |
利用量化表进行量化:
$$
\begin{array}{|c|c|c|c|c|c|c|c|}
\hline
6 & 12&14&14&18&24&49&72\\
\hline
11&12&13&17&22&35&64&92\\
\hline
10&14&16&22&37&55&78&95\\
\hline
16&19&24&29&56&64&87&98\\
\hline
24&26&40&51&68&81&103&112\\
\hline
40&58&57&87&109&104&121&100\\
\hline
48&60&69&80&103&113&120&103\\
\hline
51&55&56&62&77&92&101&99\\
\hline
\end{array}
$$
最终得到的压缩图:
$$
\begin{array}{|c|c|c|c|c|c|c|c|}
\hline
-35 & 1&0 & 0&0&0& 0 & 0 \\
\hline
-19&1&1 & 0&0&0& 0&0 \\
\hline
-21&1&1 & 0& 0&0&0&0 \\
\hline
-12 & 0&0&0 & 0& 0&0& 0 \\
\hline
-6 & -1& 0&0&0& 0&0& 0 \\
\hline
-2 & 0 & 0 & 0&0&0&0&0 \\
\hline
0 & 0 & 0 & 0&0&0&0& 0 \\
\hline
0 & 0 & 0&0&0 & 0&0& 0 \\
\hline
\end{array}
$$
反编码得到的图片:
原图 |
压缩图 |
![dct_origin_picture](https://i.loli.net/2020/10/21/vMAebcth7fXrRCs.png) |
![dct_compressed_picture](https://i.loli.net/2020/10/22/GhRagVbEf9F3Q8J.png) |
实验代码(Python):
```python
import matplotlib.pyplot as plt
import numpy as np
from scipy.fft import dct, idct
#设置显示一位小数点
np.set_printoptions(precision=1, suppress=True)
#原图
origin_pic = np.array(
[
[62, 55, 55, 54, 49, 48, 47, 55],
[62, 57, 54, 52, 48, 47, 48, 53],
[61, 60, 52, 49, 48, 47, 49, 54],
[63, 61, 60, 60, 63, 65, 68, 65],
[67, 67, 70, 74, 79, 85, 91, 92],
[82, 95, 101, 106, 114, 115, 112, 117],
[96, 111, 115, 119, 128, 128, 130, 127],
[109, 121, 127, 133, 139, 141, 140, 133],
]
)
#显示原图
plt.figure("original picture")
plt.imshow(origin_pic, cmap="gray")
plt.show()
#归一化
centered_pic = origin_pic - 128
#DCT
dct_pic = dct(centered_pic, 2, norm="ortho")
#量化表
table = np.array(
[
[6, 12, 14, 14, 18, 24, 49, 72],
[11, 12, 13, 17, 22, 35, 64, 92],
[10, 14, 16, 22, 37, 55, 78, 95],
[16, 19, 24, 29, 56, 64, 87, 98],
[24, 26, 40, 51, 68, 81, 103, 112],
[40, 58, 57, 87, 109, 104, 121, 100],
[48, 60, 69, 80, 103, 113, 120, 103],
[51, 55, 56, 62, 77, 92, 101, 99],
]
)
#量化
compressed_pic = np.around(dct_pic / table)
print(compressed_pic)
#解码
decode_pic = idct(compressed_pic * table, 2, norm="ortho") + 128
#显示压缩图
plt.figure("compressed picture")
plt.imshow(decode_pic, cmap="gray")
plt.show()
```