基于 LBG 算法的向量量化图像压缩系统
项目简介
本项目是一个基于 MATLAB 环境开发的图像压缩系统,完整实现了经典的 Linde-Buzo-Gray (LBG) 向量量化算法。向量量化 (Vector Quantization, VQ) 是一种高效的有损数据压缩技术,通过将高维数据空间划分为若干个互不重叠的区域(Voronoi 区域),并用每个区域的质心(码字)代表该区域内的所有向量,从而显著减少数据表示所需的比特数。
本项目模拟了完整的 VQ 流程,包括图像的分块矢量化、码书(Codebook)的初始化与训练、图像的编码与解码,以及最终的重建质量评估。系统特别采用了分裂法 (Splitting Method) 来生成初始码书,保证了算法的鲁棒性。
功能特性
- 图像矢量化处理:自动将输入图像分割为非重叠的固定大小块(默认 4x4 像素),并将二维图像块转换为一维训练向量。
- LBG 码书训练:
* 实现了基于分裂法的码书初始化,从单码字逐步分裂至目标大小(默认 256 码字)。
* 包含扰动参数 ($epsilon$) 控制分裂幅度。
* 基于 K-means 聚类思想的迭代优化,利用相对失真率 ($delta$) 作为收敛条件。
- 死单元处理机制:在迭代过程中,包含对空 Voronoi 区域(未分配任何样本的码字)的检测与处理机制,防止训练过程中产生无效码字。
- 鲁棒的图像读取:程序包含容错机制,优先尝试读取本地标准测试图像(如 cameraman.tif);若文件缺失,则自动生成合成测试图像以保证程序可运行。
- 高性能运算:在最近邻搜索环节,利用矩阵代数运算加速欧氏距离的计算,避免了低效的循环操作。
- 多维度评估与可视化:
* 提供均方误差 (MSE) 和峰值信噪比 (PSNR) 的定量评估。
* 计算每像素比特数 (bpp) 和实际压缩比。
* 直观展示原始图像、重构图像以及经过放大的误差热力图。
系统要求
- MATLAB R2016a 或更高版本(需包含基础数学运算及图像处理工具箱的支持)。
- 内存要求取决于输入图像大小,一般标准测试图像(256x256 或 512x512)在常规 PC 上即可运行。
使用方法
- 确保 MATLAB 的当前工作路径设置为项目所在文件夹。
- 直接运行主脚本。
- 程序将自动执行从图像加载到结果评估的全过程,并在命令窗口输出训练进度、迭代次数、当前失真度以及最终的性能指标。
- 运行结束会弹出一个图形窗口,对比显示原图、压缩后的重构图以及误差图像。
详细算法实现逻辑
本项目的核心逻辑完全封装在主函数及其辅助子函数中,具体实现流程如下:
1. 参数配置与预处理
程序首先定义关键参数,包括块大小(4x4)、目标码书大小(256,即 8-bit索引)、分裂扰动因子(0.01)以及收敛阈值。在读取图像后,会将其转换为灰度图(如果是彩图),并根据块大小对图像边缘进行裁剪,确保图像尺寸能被块大小整除。
2. 图像矢量化
预处理后的图像被分割成互不重叠的小块。通过重排操作,将每个 $4 times 4$ 的像素块拉伸为一个维度为 16 的列向量。所有这些列向量构成了 LBG 算法的训练集。
3. LBG 码书训练 (核心)
这是本项目的核心部分,采用
二分分裂法逐步构建码书:
- 初始化:首先计算所有训练向量的全局均值(全局质心),作为初始大小为 1 的码书。
- 分裂阶段:当当前码书小于目标大小时,对现有每个码字 $c$ 进行分裂,生成两个新码字 $c(1+epsilon)$ 和 $c(1-epsilon)$,使码书大小翻倍。
- 优化迭代 (Lloyd 算法):在每次分裂后,进行迭代优化:
1.
最近邻划分:计算所有训练向量到当前码书中所有码字的欧氏距离,将每个向量分配给距离最近的码字。
2.
失真度计算:统计当前的总平均量化误差。
3.
收敛判断:计算前一次迭代与当前迭代失真度的相对变化率,若小于设定阈值则停止迭代,进入下一轮分裂或结束训练。
4.
质心更新:计算归属于每个码字的训练向量的新均值,更新码字位置。如果发现某个码字未分配到任何向量(死单元),算法会随机选取一个训练向量作为新码字,以保持码书大小不变。
4. 编码与解码
- 编码 (Quantization):利用训练好的最终码书,再次计算所有图像向量到码字的距离,仅保存每个向量对应的最近码字的索引。这部分代表了实际的数据压缩过程。
- 解码 (Reconstruction):根据保存的索引,从码书中查找对应的码字向量,通过逆向重排将向量还原为 $4 times 4$ 的图块,并拼接回完整的图像矩阵。
5. 性能评估
程序会对重构图像进行 uint8 类型转换,并同原始图像进行对比:
- 计算MSE:反映像素值的平均差异。
- 计算PSNR:反映信号重建质量,值越高表示失真越小。
- 计算压缩指标:对比原始 8-bit 像素深度,计算基于码书索引长度的压缩后比特率 (bpp) 和压缩比。
- 可视化:生成包含原图、重构图和误差图(误差值放大 5 倍显示以增强人眼可观测性)的对比图表。
关键代码模块分析
以下是对代码中内部实现的具体技术细节分析:
imageToVectors 逻辑
该模块负责将二维图像矩阵转换为适合聚类算法处理的列向量矩阵。它通过双重循环遍历图像块,将每个块内的像素按列优先顺序提取,最终输出一个 (块面积) x (块总数) 的矩阵。
findNearestCentroids 逻辑
为了加速 LBG 迭代中极其频繁的距离计算,该模块避免了通过循环计算每个向量与每个码字的距离,而是利用了展开公式 $|x-y|^2 = x^2 + y^2 - 2xy$。
- 分别预计算数据向量的平方和与码字的平方和。
- 利用矩阵乘法一次性计算所有 $x^T y$ 交叉项。
- 通过广播机制(
bsxfun 或隐式扩展)合成距离矩阵,并直接利用 min 函数获取最近邻索引。
updateCentroids 逻辑
该模块执行 K-means 算法中的 "M-step"。它根据索引将数据分组并计算均值。代码中特别包含了一个容错逻辑:当检测到某个聚类簇为空(即没有任何数据点分配给该码字)时,为了避免
NaN 值并维持码书的多样性,它会随机从原始数据中选择一个向量作为该位置的新码字。
vectorsToImage 逻辑
这是矢量化的逆过程。它按照编码时的顺序,将重建后的列向量重新 reshape 为方块,并将其准确填入结果矩阵的对应坐标位置,从而恢复出完整的图像结构。