基于K-SVD与OMP算法的图像稀疏重构系统
项目简介
本项目是一个基于MATLAB实现的图像稀疏表示与重构演示系统。它结合了K-SVD(K-奇异值分解)字典学习算法与OMP(正交匹配追踪)稀疏编码算法,旨在展示如何利用过完备字典对自然图像进行稀疏分解,并利用学习到的字典项高质量地重建图像。该系统完整包含了从数据预处理、字典训练、稀疏编码到图像逆向合成及质量评估的全流程。
功能特性
- 图像分块处理:支持将图像分割为重叠的小尺寸图像块,并进行向量化处理。
- 自适应字典学习:利用K-SVD算法从图像自身的纹理结构中学习过完备字典,相比固定基(如DCT)具有更好的适应性。
- 稀疏编码:内置OMP算法实现,在给定的稀疏度约束下求解图像块的最优稀疏系数。
- 去直流分量:在训练前移除图像块的直流平均值(DC Mean),使字典专注于学习纹理特征。
- 重叠区域融合:在重构阶段,采用加权平均法处理图像块之间的重叠区域,有效消除了块效应。
- 实时可视化:提供包含原始图像、学习到的字典原子、收敛曲线、稀疏系数矩阵及残差图的综合可视化界面。
- 质量评估:自动计算重构图像的峰值信噪比(PSNR)。
系统要求
- MATLAB R2016a 或更高版本(需具备图像处理工具箱)。
- 内存建议:4GB以上(取决于输入图像大小和字典规模)。
核心算法实现流程
本项目的所有逻辑集成在一个主脚本中,执行流程如下:
1. 系统参数配置与初始化
系统首先定义了关键的超参数:
- 图像块尺寸:设置为8x8像素,即向量维度为64。
- 字典规模:设置为256个原子,实现了从64维到256维的过完备映射。
- 稀疏度约束:每个图像块最多由6个字典原子线性组合表示。
- 迭代次数:K-SVD字典训练迭代10次。
- 图像缩放:为了加快演示速度,默认将输入图像缩小为原始尺寸的0.5倍。
2. 图像读取与预处理
- 程序尝试读取标准的
cameraman.tif 图像。如果文件不存在,会自动生成一张随机噪声图像以防止程序崩溃。 - 如果输入是彩色图像,会自动转换为灰度图像。
- 图像被转换为双精度浮点型(double)以便于数值计算。
3. 构建训练样本集
- 滑动窗口分块:利用
im2col 函数以滑动步长(Sliding)模式提取图像中所有可能的重叠块。 - 去直流(Remove DC):计算并减去每个图块的平均值,保留纯纹理信息用于字典训练。
- 随机采样:为了提高训练效率,如果提取的样本块过多,程序会随机采样最多4000个样本构成训练集。
4. 字典初始化
- 无需预设DCT字典,系统直接从训练样本集中随机抽取256列数据作为初始字典。
- 对初始字典的每一列进行L2范数归一化处理。
5. K-SVD 迭代训练
程序进入主循环,交替执行以下两个步骤:
- 稀疏编码 (Sparse Coding):保持字典固定,调用OMP算法计算训练样本在当前字典下的稀疏系数矩阵。
- 字典更新 (Dictionary Update):保持稀疏系数中的非零位置不变,逐一更新字典原子。计算除去当前原子后的残差误差矩阵,利用SVD分解(取最大奇异值对应的左右奇异向量)来同时更新当前原子及其对应的系数值。
- 误差记录:每次迭代计算训练数据的Frobenius范数重构误差,并绘制动态收敛曲线。
6. 全图稀疏重构
- 字典学习完成后,利用最终的字典对整幅图像的所有重叠块(不仅仅是训练样本)进行OMP稀疏编码。
- 逆向合成:通过
字典 * 系数 恢复去直流后的图像块,然后加回步骤3中移除的直流分量。 - 重叠平均:使用自定义的聚合算法,将重叠的图像块还原到二维图像平面。对于重叠像素点,通过计算累加值与覆盖次数的商(平均值)来平滑连接处。
- 数值截断:将重构后的像素值限制在[0, 1]范围内,防止溢出。
7. 结果评估与展示
- PSNR计算:对比原始图像与重构图像,计算峰值信噪比。
- 多视图展示:
* 原始灰度图像。
* 学习到的前64个字典原子(以8x8小方块形式排列展示)。
* 最终重构图像及其PSNR值。
* K-SVD训练过程的误差收敛曲线。
* 稀疏系数矩阵的局部热力图(展示稀疏性)。
* 重构误差残差图(通过伪彩色图显示差异区域)。
关键算法细节分析
代码中包含了三个核心辅助函数,实现了具体的数学逻辑:
OMP 正交匹配追踪 (omp_algorithm)
这是稀疏编码的核心求解器。
* 对每个样本进行逐一处理。
*
贪婪选择:在每一步迭代中,计算残差与字典原子的内积(投影),选择相关性最大(内积绝对值最大)的原子索引。
*
正交投影:将已选中的原子集合构成子字典,通过最小二乘法求解系数,确保残差垂直于这组原子所张成的空间。
*
残差更新:更新残差向量,直到达到稀疏度K或误差阈值。
* 为了保持纯MATLAB实现的可移植性,使用了循环结构而非MEX加速。
K-SVD 字典更新 (ksvd_update)
这是字典学习的核心步骤,实现了从样本中提炼特征的过程。
* 逐列遍历字典原子。
*
样本索引:找出所有使用了当前原子的样本集合。
*
误差分离:计算假设移除该原子贡献后的残差矩阵 $E_k$。
*
SVD分解:对局部误差矩阵 $E_k$ 进行奇异值分解(使用
svds 求解最大的一个奇异值),分解结果中的 $U$ 向量更新为新的字典原子,$S times V^T$ 更新为对应的非零系数。这一步同时优化了字典原子形状和对应的系数值,保证了该原子能最大程度地修正当前误差。
图像聚合 (col2im_custom)
这是处理图像块重叠的关键函数。
* 创建一个与原图等大的累加矩阵和权重计数矩阵。
* 按照
im2col 的滑动顺序(列优先),将每个重构后的向量块Reshape回 $8 times 8$ 矩阵。
* 将块数据累加到图像平面的对应坐标位置,并记录该位置被覆盖的次数。
* 最终将累加值除以权重矩阵,得到平滑的重构图像。
使用方法
- 确保MATLAB工作路径下包含本代码文件。
- (可选)在同目录下放置名为
cameraman.tif 的图片文件,否则系统将使用随机噪声图演示。 - 直接运行主函数。
- 观察弹出的可视化窗口,等待迭代完成(控制台会输出迭代进度和误差值)。