基于MATLAB的矢量量化图像压缩系统
项目简介
本项目是一个基于MATLAB环境开发的图像处理工程,专注于演示和实现基于矢量量化(Vector Quantization, VQ)的图像压缩技术。核心算法采用经典的LBG(Linde-Buzo-Gray)算法进行码书(Codebook)的设计与训练。该系统能够对数字图像进行分块、训练最优码书、编码压缩以及解码重建,并未提供详尽的图像质量评价指标(PSNR、MSE)和可视化结果,非常适合用于理解数据压缩原理和聚类算法在图像处理中的应用。
功能特性
- 鲁棒的图像读取机制:支持读取外部图像文件,若文件不存在会自动生成MATLAB内置的测试图像(基于peaks函数),确保程序始终可运行。
- 自动预处理与填充:自动将彩色图像转换为灰度图像,并根据设定的块大小(Block Size)对图像边缘进行自动填充,确保图像尺寸能被完整分块。
- 高效矢量化处理:将图像分解为互不重叠的矢量块,利用矩阵操作加速处理。
- LBG码书训练算法:实现了完整的LBG算法流程,包含分裂法初始化(Splitting Initialization)和K-means迭代优化,支持自定义收敛阈值和扰动因子。
- 快速距离计算:利用矩阵展开公式优化欧氏距离的计算过程,避免了低效的循环运算。
- 性能评估:内置图像质量评价模块,输出均方误差(MSE)、峰值信噪比(PSNR)、原图位深、压缩位深及压缩比。
- 多维度可视化:提供原始图像、重建图像、部分码书(可视化为图像块)的对比展示,以及训练过程中的收敛曲线图。
系统要求
- MATLAB R2016a 或更高版本
- Image Processing Toolbox(图像处理工具箱)
使用方法
- 确保MATLAB当前工作目录包含项目脚本。
- 默认处理图像名为
peppers.png,如需处理自定义图像,请修改脚本参数设置部分的 img_filename 变量。 - 直接运行主程序脚本。
- 程序运行结束后,控制台将输出训练耗时及压缩性能指标,并弹出的图形窗口展示处理结果。
核心逻辑与实现细节
本项目的核心逻辑严格遵循以下步骤实现:
1. 参数设置与环境初始化
程序首先清理工作区变量与图形窗口。预定义了关键压缩参数,包括块大小设置为4x4,目标码书大小(码字数量)为256,LBG分裂扰动因子为0.01,迭代收敛阈值为0.001。
2. 图像读取与预处理
程序尝试读取指定路径的图像。如果读取失败(例如文件缺失),则自动生成一个基于
peaks 函数的灰度测试图像。读取成功后,若为彩色图像则转为灰度图,并转换为双精度浮点型。随后,计算图像长宽是否能被块大小整除,若不能,则使用边缘复制(replicate)的方式在图像右侧和下侧进行填充。
3. 图像分块(矢量化)
利用自定义的封装逻辑(基于
im2col 的 distinct 模式),将填充后的图像切割为互不重叠的 4x4 像素块,并将每个块拉伸为 16维 的列向量。这些向量构成了后续训练的训练集。
4. LBG 码书训练(算法核心)
这是系统最关键的部分,采用双层循环结构:
- 外层循环(分裂阶段):从大小为1的初始码书(全局质心)开始,每次循环将当前码书均分为二,通过乘以 $(1 + epsilon)$ 和 $(1 - epsilon)$ 进行分裂,直到达到预设的256个码字。
- 内层循环(迭代优化阶段):在每一级码书大小下,执行K-means聚类优化:
*
距离计算优化:利用公式 $||x-y||^2 = x^2 + y^2 - 2x^Ty$ 计算所有训练矢量与所有码字的欧氏距离。通过矩阵运算
bsxfun 实现,显著提高了匹配速度。
*
最近邻搜索:为每个训练矢量找到距离最近的码字索引。
*
收敛判断:计算当前的平均畸变(平均最小距离),并与上一次迭代对比计算相对误差。若误差小于阈值(0.001),则停止迭代。
*
质心更新:根据索引分类,计算每个簇的新质心(均值)。
*
空胞腔处理:如果在迭代中出现某个码字未被任何矢量选中的情况(空胞腔),程序采用简单策略,将其重置为全局质心,以防止死码字的产生。
5. 图像编码
训练完成后,利用最终生成的码书,再次计算所有图像块矢量的最佳匹配码字索引。同时计算压缩指标,包括压缩后的比特率(bpp)和压缩比。
6. 图像解码与重建
根据编码阶段生成的索引表,从码书中查找对应的码字向量。利用自定义的重组逻辑(基于
col2im 的 distinct 模式),将这些向量重新排列并还原为二维图像块,最后裁剪掉预处理阶段添加的填充边缘,并将数据类型转换回
uint8。
7. 质量评价与可视化
- 评价:使用自定义的MSE计算逻辑(兼容性强)和标准PSNR公式计算重建质量,并在控制台打印详细报告。
- 可视化:
* 创建一个包含三个子图的窗口:分别显示原始灰度图、重建后的图像、以及可视化后的部分码书(将前64个16维码字向量重塑为4x4图像块进行展示)。
* 若存在迭代历史数据,会额外通过折线图展示LBG算法训练过程中平均量化误差随迭代次数的收敛情况。
关键算法说明
快速欧氏距离计算
为了避免在MATLAB中使用多重循环计算距离,代码中采用矩阵代数展开法计算距离矩阵 $D$:
D(i, j) = ||c_i||^2 + ||v_j||^2 - 2 * (c_i' * v_j)
其中 $c$ 为码字,$v$ 为输入矢量。这种方法充分利用了MATLAB的矩阵乘法优化。
空胞腔(Empty Cells)处理策略
在K-means迭代过程中,通过统计每个码字归属的矢量数量,能够检测出“空胞腔”。为了避免这些码字被浪费,代码实现了一个保护机制:一旦发现空胞腔,强制将其位置复位到全局平均值附近。这虽然是一种简化的处理策略,但能有效避免算法崩溃或局部极值问题。
图像分块与重组
代码未直接依赖某些高版本工具箱的特定函数,而是通过封装
im2col 和
col2im 的
distinct(不重叠)模式,明确实现了图像到矢量的转换和逆转换。这确保了压缩是基于独立的块进行的,符合标准矢量量化的定义。