【第 13 章 基于霍夫曼图像压缩重建--Matlab深度学习实战图像处理应用】

基于霍夫曼图像压缩重建
部分参考来源:
https://blog.csdn.net/qq_59747472/article/details/121890265

为了节省空间,在对数据进行编码时,可以对那些经常出现的数据指定较少的位数表示, 而那些不常出现的数据指定较多的位数表示,从而降低冗余,这样从总的效果看就节省了存储空间。基于哈夫曼编码图像压缩的基本原理是频繁使用的数据用较短的代码代替,较少使用的数据用较长的代码代替,每个数据的代码各不相同,这是一种典型的无损编码方式。

部分函数

Mat2Huff.m

function [zvec, zi] = Mat2Huff(vec)

if ~isa(vec,'uint8')
    fprintf('\n请确认输入uint8类型数据向量!\n');
    return;
end

vec = vec(:)';
f = Frequency(vec);
syminfos = find(f~=0); 
f = f(syminfos);
[f, sind] = sort(f);
syminfos = syminfos(sind);
len = length(syminfos);
syminfos_ind = num2cell(1:len);
cw_temp = cell(len,1);
while length(f)>1
    ind1 = syminfos_ind{1};
    ind2 = syminfos_ind{2};
    cw_temp(ind1) = AddNode(cw_temp(ind1),uint8(0));
    cw_temp(ind2) = AddNode(cw_temp(ind2),uint8(1));
    f = [sum(f(1:2)) f(3:end)];
    syminfos_ind = [{[ind1 ind2]} syminfos_ind(3:end)];
    [f,sind] = sort(f);
    syminfos_ind = syminfos_ind(sind);
end
cw = cell(256,1);
cw(syminfos) = cw_temp;
len = 0;
for i = 1 : length(vec),
    len = len+length(cw{double(vec(i))+1});
end
str_temp = repmat(uint8(0),1,len);
pt = 1;
for index=1:length(vec)
    cd = cw{double(vec(index))+1};
    len = length(cd);
    str_temp(pt+(0:len-1)) = cd;
    pt = pt+len;
end
len = length(str_temp);
pad = 8-mod(len,8);
if pad > 0
    str_temp = [str_temp uint8(zeros(1,pad))];
end
cw = cw(syminfos);
cl = zeros(size(cw));
ws = 2.^(0:51);
mcl = 0;
for index = 1:length(cw)
    len = length(cw{index});
    if len>mcl
        mcl = len;
    end
    if len>0
        cd = sum(ws(cw{index}==1));
        cd = bitset(cd,len+1);
        cw{index} = cd;
        cl(index) = len;
    end
end
cw = [cw{:}];
cols = length(str_temp)/8;
str_temp = reshape(str_temp,8,cols);
ws = 2.^(0:7);
zvec = uint8(ws*double(str_temp));
huffcodes = sparse(1,1);
for index = 1:numel(cw)
    huffcodes(cw(index),1) = syminfos(index);
end
zi.pad = pad;
zi.huffcodes = huffcodes;
zi.ratio = cols./length(vec);
zi.length = length(vec);
zi.maxcodelen = mcl;

直方图对比函数代码
HisteqContrast.m

function HisteqContrast(Img1, Img2)
figure('Name', '直方图对比', 'NumberTitle', 'Off', ...
    'Units', 'Normalized', 'Position', [0.1 0.1 0.5 0.5]);
subplot(2, 2, 1); imshow(mat2gray(Img1)); title('原图像', 'FontWeight', 'Bold');
subplot(2, 2, 2); imshow(mat2gray(Img2)); title('处理后的图像', 'FontWeight', 'Bold');
if ndims(Img1) == 3
    Q = rgb2gray(Img1);
else
    Q = mat2gray(Img1);
end

if ndims(Img2) == 3
    W = rgb2gray(Img2);
else
    W = mat2gray(Img2);
end

subplot(2, 2, 3); imhist(Q, 64); title('原灰度直方图', 'FontWeight', 'Bold');
subplot(2, 2, 4); imhist(W, 64); title('处理后的灰度直方图', 'FontWeight', 'Bold');

这些代码都是二进制码,且码字长度是不均匀的、平均码率可以接近信息源熵值的一种编码。编码过程是先对图像数据扫描一遍, 计算出各种像素出现的概率,按概率的大小建立最优二叉树(二叉树的叶子节点刚好表示的图像中的某种像素)并给二叉树的每个分支赋特定权值(0或1), 然后通过遍历二叉树读取从根节点到叶子节点的路径权值字符串,即给每种像素指定了不同长度的唯一编码, 由此得到一张该图像所有像素的哈夫曼编码表。编码后的图像数据记录的是每个像素的码字,而码字与实际像素值的对应关系记录在码表中,码表是附在图像文件中的。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
得到后续的直方图对比,效果如图
在这里插入图片描述
算法流程
在这里插入图片描述
系统GUI初始界面
在这里插入图片描述
保存截图函数:

function SnapImage()

imagesPath = '.\\snap_images';
if ~exist(imagesPath, 'dir')
    mkdir(imagesPath);
end

[FileName,PathName,FilterIndex] = uiputfile({'*.jpg;*.tif;*.png;*.gif','All Image Files';...
          '*.*','All Files' },'保存截图',...
          '.\\snap_images\\temp.jpg');
if isequal(FileName, 0) || isequal(PathName, 0)
    return;
end
fileStr = fullfile(PathName, FileName);
f = getframe(gcf);
f = frame2im(f);
imwrite(f, fileStr);
msgbox('抓图文件保存成功!', '提示信息');

保存图像函数:

function SaveImage(Img)

imagesPath = '.\\results';
if ~exist(imagesPath, 'dir')
    mkdir(imagesPath);
end

[FileName,PathName,FilterIndex] = uiputfile({'*.jpg;*.tif;*.png;*.gif','All Image Files';...
          '*.*','All Files' },'保存截图',...
          '.\\results\\result.jpg');
if isequal(FileName, 0) || isequal(PathName, 0)
    return;
end
fileStr = fullfile(PathName, FileName);
imwrite(mat2gray(Img), fileStr);

结果展示:
在这里插入图片描述
在这里插入图片描述
本文源代码下载地址–>传送门

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海宝7号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值