基于霍夫曼编码的图像压缩重建与基于小波变换的RGB图像压缩Matlab代码

基于霍夫曼图像图像压缩重建 霍夫曼编码,又称为哈夫曼编码、赫夫曼编码,是一种用于无损数据压缩的熵编码(权编码)算法。 基于小波变换的 RGB 图像压缩matlab代码

最近在折腾图像压缩的时候,发现霍夫曼编码和小波变换这对组合挺有意思。直接拿MATLAB试了试手,结果意外地好玩------虽然压缩率不算顶尖,但整个流程特别适合用来理解原理。今天就跟大伙儿唠唠这个实操过程。

霍夫曼编码说白了就是给高频出现的像素值分配短码,低频的长码。比如一张图里白色特别多,那就用"01"这种短二进制表示白色。而小波变换这货厉害在能把图像信息分层,高频部分(细节)和低频部分(轮廓)拆得明明白白。这俩一结合,压缩效果就出来了。

先上主菜,看看怎么用MATLAB整活:

matlab 复制代码
% 读取图像并转换颜色空间
orig_img = imread('peppers.png');
ycbcr_img = rgb2ycbcr(orig_img);

% 小波分解
[LL, LH, HL, HH] = dwt2(ycbcr_img(:,:,1), 'haar');

这里先把RGB转成YCbCr不是闲得慌。Y通道(亮度)人眼敏感,CbCr(色度)相对不敏感。后面的压缩主要在Y通道搞事情,色度通道可以适当摆烂。小波分解用最基础的haar小波,LL是低频分量,剩下三个都是高频细节。

接下来是重头戏------量化。这个阈值我随便设的,实际应用得调参:

matlab 复制代码
% 量化高频分量
quant_step = 15;
LH_q = round(LH/quant_step);
HL_q = round(HL/quant_step);
HH_q = round(HH/quant_step);

量化步长越大,数据越容易变成零,压缩率越高但画质扑街。这里把高频分量除以15再取整,原本0-255的像素值被压缩到0-17左右。不过注意这个操作是有损的,这也是为什么霍夫曼要放在后面------先做有损压缩再做无损编码。

霍夫曼编码部分得统计符号频率。MATLAB自带的huffman函数不太友好,得自己折腾字典:

matlab 复制代码
% 合并所有量化后的数据
all_data = [LL(:); LH_q(:); HL_q(:); HH_q(:)];

% 统计符号频率
symbols = unique(all_data);
counts = histcounts(all_data, [symbols; max(symbols)+1]);
prob = counts/length(all_data);

% 生成霍夫曼字典
dict = huffmandict(symbols, prob);

% 编码
compressed_data = huffmanenco(all_data, dict);

这里有个坑:原始数据要是整数,但MATLAB的huffmandict对符号类型敏感。遇到过好几次因为数据类型不对导致编码失败的情况,后来学乖了都先转成uint8。

解码重建就是倒着走一遍流程:

matlab 复制代码
% 霍夫曼解码
decoded_data = huffmandeco(compressed_data, dict);

% 拆分数据
len = numel(LL);
Y_LL = reshape(decoded_data(1:len), size(LL));
Y_LH = reshape(decoded_data(len+1:2*len), size(LH)) * quant_step;
% ...类似处理其他分量

% 小波重构
reconstructed_Y = idwt2(Y_LL, Y_LH, Y_HL, Y_HH, 'haar');

这里有个骚操作:解码出来的数据要乘回量化步长。但因为之前做过取整操作,重建的高频分量会有误差------这也是图像损失的主要来源。不过人眼对高频细节不敏感,实际看起来影响不大。

最后算个压缩率收尾:

matlab 复制代码
original_size = whos('orig_img').bytes;
compressed_size = ceil(length(compressed_data)/8); % 转字节
cr = original_size / compressed_size;

实测512x512的测试图能到3:1左右的压缩率,PSNR大概28dB。想再提升的话可以搞多级小波分解,或者用更复杂的熵编码。不过对于教学演示来说,这个简单版本已经够说明问题------毕竟压缩的本质就是扔掉不重要的,再聪明地编码剩下的。

整个过程最爽的时刻是看着重建后的图像虽然有点模糊,但关键轮廓都在。这种在压缩率和质量之间走钢丝的感觉,大概就是做信号处理的乐趣所在吧。

相关推荐
旧梦吟1 天前
脚本网页 三人四字棋
前端·数据库·算法·css3·html5
打工人小夏1 天前
vue3使用transition组件,实现过度动画
前端·vue.js·前端框架·css3
奶球不是球2 天前
elementplus组件中el-calendar组件自定义日期单元格内容及样式
javascript·css·css3
❆VE❆3 天前
tailwindcss:安装避坑,从 0 到项目跑通
前端·javascript·vue.js·css3·组件·tailwindcss
旧梦吟4 天前
脚本网页 地球演化
前端·算法·css3·html5·pygame
Wiktok5 天前
tailwindcss常用类名写法及其含义
css3·tailwindcss
阿珊和她的猫6 天前
CSS3新特性概述
前端·css·css3
三十_A7 天前
如何正确实现圆角渐变边框?为什么 border-radius 对 border-image 不生效?
前端·css·css3
冰暮流星7 天前
css3如何引入外部字体
前端·css·css3
行走的陀螺仪8 天前
重绘和重排怎么触发?怎么优化?
前端·css·性能优化·css3·浏览器原理