第三次作业
3.1 计算下图的 DFT, DCT, Hadamard 变换和Haar变换
3.2 设有一组64*64的图像,它们的协方差矩阵式单位矩阵.如果只使用一半的原始特征值计算重建图像,那么原始图像和重建图像间的均方误差是多少?
编程作业 3.3 编程实现lena.bmp的离散Fourier变换和离散余弦变换,并显示频谱图像。 【提交时间】:3月31日
3.1
这是一个典型的图像处理或信号处理练习。
给定的 $4 \times
4$ 矩阵 $f$ 为:
[ f = \left[ \begin{array}{cccc}
0 & 1 & 1 & 0\
0 & 1 & 1 & 0\
0 & 1 & 1 & 0\
0 & 1 & 1 & 0
\end{array} \right] ]
由于该矩阵的所有行都相同,且所有列也相同(属于可分离矩阵),我们可以利用可分离变换的性质:
$$F= TfT^T$$
其中 $T$ 是变换矩阵。
对于这个特定的矩阵,它可以写成外积形式:
$$f = \textbf{1} \cdot \mathbf{r}$$
其中 $\textbf{1} = [1, 1, 1, 1]^T$,$\mathbf{r} = [0, 1, 1, 0]$.
因此,$F = (T \textbf{1}) (T \mathbf{r})^T$。
在所有的标准正交变换(DFT, DCT, Hadamard, Haar)中,第一行基向量通常是常数向量(DC分量)。
因此 $T \textbf{1} = [2, 0, 0, 0]^T$(假设使用了单位矩阵归一化系数 $1 / \sqrt{N}$)。
这意味着结果矩阵只有第一行有非零值,该行数值等于行向量
$[0, 1, 1, 0]$ 的一维变换结果乘以 $2$。
- 二维离散傅里叶变换 (DFT)一维 DFT 公式(归一化):
$$X (k) = \frac{1}{2} \sum_{n = 0}^3 x (n) e^{- j \frac{2 \pi}{4} kn}$$
对于行向量 $[0, 1, 1, 0]$:
$$ \begin{aligned} X(0) &= \frac{1}{2}(0 + 1 + 1 + 0) = 1 \ X(1) &= \frac{1}{2}(0 + 1 \cdot (-j) + 1 \cdot (-1) + 0) = -0.5 - 0.5j \ X(2) &= \frac{1}{2}(0 + 1 \cdot (-1) + 1 \cdot (1) + 0) = 0 \ X(3) &= \frac{1}{2}(0 + 1 \cdot (j) + 1 \cdot (-1) + 0) = -0.5 + 0.5j \end{aligned} $$ 乘以系数 $2$,得到二维 DFT 结果: [ F_{DFT} = \left[ \begin{array}{cccc} 2 & - 1 - j & 0 & - 1 + j\ 0 & 0 & 0 & 0\ 0 & 0 & 0 & 0\ 0 & 0 & 0 & 0 \end{array} \right] ] - 离散余弦变换 (DCT)使用标准 DCT-II 变换。行向量 $[0, 1, 1,
0]$ 的变换:
$X (0) = 1 $ (DC分量)
$X (1) = 0$ (对称性抵消)
$X (2) = \frac{1}{2} \sum x (n) \cos (\frac{(2 n + 1) 2 \pi}{8}) = \frac{1}{2} (\cos (\frac{3 \pi}{4}) + \cos (\frac{5 \pi}{4})) = - \frac{\sqrt{2}}{2} \approx - 0.707$
$X (3) = 0$
乘以系数 $2$,得到二维 DCT 结果: [ F_{DCT} = \left[ \begin{array}{cccc} 2 & 0 & - \sqrt{2} & 0\ 0 & 0 & 0 & 0\ 0 & 0 & 0 & 0\ 0 & 0 & 0 & 0 \end{array} \right] \approx \left[ \begin{array}{cccc} 2 & 0 & - 1.414 & 0\ 0 & 0 & 0 & 0\ 0 & 0 & 0 & 0\ 0 & 0 & 0 & 0 \end{array} \right] ] - Hadamard 变换 (WHT)
使用 Walsh 排序或自然排序(此处以常用的 $4 \times 4$ 哈达玛矩阵为例):
$$H_4 = \frac{1}{2} \left[ \begin{array}{cccc} 1 & 1 & 1 & 1\ 1 & - 1 & 1 & - 1\ 1 & 1 & - 1 & - 1\ 1 & - 1 & - 1 & 1 \end{array} \right]$$
行向量 $[0, 1, 1, 0]$ 的变换为 $[1, 0, 0, - 1]^T$。乘以系数 $2$,得到二维 WHT 结果: [ F_{WHT} = \left[ \begin{array}{cccc} 2 & 0 & 0 & - 2\ 0 & 0 & 0 & 0\ 0 & 0 & 0 & 0\ 0 & 0 & 0 & 0 \end{array} \right] ] - Haar 变换
$4 \times 4$ Haar 变换矩阵:
$T_{Haar} = \frac{1}{2} \left[ \begin{array}{cccc} 1 & 1 & 1 & 1\ 1 & 1 & - 1 & - 1\ \sqrt{2} & - \sqrt{2} & 0 & 0\ 0 & 0 & \sqrt{2} & - \sqrt{2} \end{array} \right]$
行向量 $[0, 1, 1, 0]$ 的变换:
$X (0) = 1$
$X (1) = \frac{1}{2} (0 + 1 - 1 - 0) = 0$
$X (2) = \frac{1}{2} (0 - \sqrt{2}) = - \frac{1}{\sqrt{2}}$
$X (3) = \frac{1}{2} (\sqrt{2} - 0) = \frac{1}{\sqrt{2}}$
乘以系数 $2$,得到二维 Haar 变换结果:
[ F_{Haar} = \left[ \begin{array}{cccc} 2 & 0 & - \sqrt{2} & \sqrt{2}\ 0 & 0 & 0 & 0\ 0 & 0 & 0 & 0\ 0 & 0 & 0 & 0 \end{array} \right] ] 总结:
由于输入图像在垂直方向上是恒定的(频率为0),所有变换后的能量都集中在第一行(即 $u = 0$ 的行),体现了图像的水平结构特性。
3.2
这是一个关于 KLT(K-L变换/主成分分析 PCA)重建误差的典型问题。
在这种情况下,均方误差(MSE)可以通过协方差矩阵的特征值直接计算得出。
核心结论
在图像压缩或重建中,如果使用前 $k$ 个主成分进行重建,其最小均方误差等于所有被舍弃的特征值之和。
计算步骤
确定维度 ($N$):
图像大小为 $64 \times 64$,将其展开为一维向量后,总维数为:
[ N = 64 \times 64 = 4096 ]
分析特征值 ($\lambda$):
题目给出协方差矩阵是单位矩阵 ($C = I$)。
单位矩阵的特征值全部相等,且都等于 $1$:
[ \lambda_1 = \lambda_2 = \ldots = \lambda_{4096} = 1 ]
计算重建误差:
题目指出只使用’‘一半的特征值’‘进行重建,意味着我们保留了
$2048$ 个特征值,舍弃了剩下的 $M = 2048$ 个特征值。
总平方误差 (Total Squared Error) 为舍弃的特征值之和:
[ \sum_{i = 2049}^{4096} \lambda_i = 2048 \times 1 = 2048 ]
均方误差 (MSE) 是总误差除以总维数 $N$:
[ MSE = \frac{1}{N} \sum_{i = k + 1}^N \lambda_i = \frac{2048}{4096} = 0.5 ]
结果
原始图像和重建图像间的均方误差是 $0.5$。
深度解析:为什么是 0.5?
- 物理意义:
当协方差矩阵为单位矩阵时,意味着图像的每一个像素点之间完全不相关,且每个像素的方差(能量)都是 $1$。 - 压缩效率:
在这种情况下,没有任何一个维度比其他维度更重要(没有能量集中现象)。因此,当你丢弃一半的数据时,你恰好丢弃了一半的能量,误差也就正好是 $50%$。
这反映了一个事实:KLT 变换(或 PCA)在处理完全不相关的数据(如白噪声)时是没有压缩优势的。
3.3
| |
关键点解释:
- 无库保存图像:
- 我们手动生成了一个 8 位伪彩色(Grayscale)BMP 文件。
- 它由 54 字节头 + 1024 字节调色板(定义 0-255 级灰色)+ 像素数据组成。
- 注意:BMP 数据在文件中是’‘倒着’‘存的(第一行数据实际上是图像的最底行),所以我们在
save\_bmp\_8bit里做了 $range(height - 1, -1, -1)$ 处理。
- 频谱处理逻辑:
- DFT:进行了``中心化’‘操作(四象限交换),这样亮亮的低频点就在正中心了。
- DCT:不需要中心化,低频通常集中在左上角。
- 对数压缩:如果不做 math.log,你看到的图像会是几乎全黑的,只有一个白点。
- 运行速度:256 阶的变换虽然是 $O (N^3)$,但在 Python 下纯循环还是有几千万次运算。运行约需 20-30 秒。如果你觉得慢,那是 Python 循环的锅,不是算法问题。
输出结果:
lena_dct.bmp
lena_dft.bmp
