~~第一次原创博客,记录一下课程实验,这次实验主要是实现利用霍夫曼编码方法对图像进行编码,利用matlab实现。在网上搜寻了一下,高阅读量的几个matlab都是通过数组实现,很是方便,但是理解起来比较困难,我便从霍夫曼编码树出发,从概率分布生成霍夫曼编码树,然后再得到编码。直接上代码。
function code_table=huffman_my(L,imhist_p)
%% L 是灰度级,一般为256,imhist_p 为灰度概率分布
%%进行霍夫曼编码
tic
%% 生成结点,存放到leaf_str 的结构体数组中
for i =1 : L
tmp_str=struct('name',i,'prob',imhist_p(i),'Parent',[],'lchild',[],'rchild',[],'code',[]);
leaf_str(i)=tmp_str;
end
%% 生成霍夫曼编码树
while length(leaf_str)>1
[~,index]=sort([leaf_str.prob]);
leaf_str=leaf_str(index);
tmp_str.prob=leaf_str(1).prob+leaf_str(2).prob;
tmp_str.name=0;
tmp_str.lchild=leaf_str(1);
tmp_str.rchild=leaf_str(2);
tmp_str.Parent=[];
leaf_str(1).Parent=tmp_str;
leaf_str(2).Parent=tmp_str;
leaf_str(end+1)=tmp_str;
leaf_str(1:2)=[];
end
%% 广度优先搜索进行编码,构建编码表
BFS=leaf_str;
code_table=cell(L,1);
% code_talbe=strings(256,1)
while ~isempty(BFS)
tmp_str=BFS(1);
if ~isempty(tmp_str.lchild)
tmp_str.lchild.code=[tmp_str.code,1];
% tmp_str.lchild.code=[tmp_str.code,'1'];
BFS(end+1)=tmp_str.lchild;
end
if ~isempty(tmp_str.rchild)
tmp_str.rchild.code=[tmp_str.code,0];
% tmp_str.rchild.code=[tmp_str.code,'0'];
BFS(end+1)=tmp_str.rchild;
end
if tmp_str.name~=0
code_table{tmp_str.name}=tmp_str.code;
end
BFS(1)=[];
end
toc
end
从训练集获取图像获取总的灰度级概率分布,然后对测试集中数据进行编码。
function main
clear
clc
%% 导入数据,统计灰度级的概率分布
train_file_path = '.\train\';
train_img_path_list = dir(strcat(train_file_path,'*.bmp'));
img_num = length(train_img_path_list);
L=256;
counts_total=zeros(L,1);
if img_num > 0
for k = 1:img_num
image_name=train_img_path_list(k).name;
image = imread(strcat(train_file_path,image_name));
image=rgb2gray(image);
[counts_one,~]=imhist(image);
counts_total=counts_total+counts_one;
end
end
%% 概率分布
imhist_p=counts_total/sum(counts_total);
%% 进行霍夫曼编码
code_table=huffman_my(L,imhist_p);
%% 对测试图像进行编码
test_file_path = '.\test\';
test_img_path_list = dir(strcat(test_file_path,'*.bmp'));
img_num = length(test_img_path_list);
if img_num > 0
for j = 1:img_num
image_name=test_img_path_list(j).name;
image = imread(strcat(test_file_path,image_name));
image=rgb2gray(image);
name_former=split(image_name,'.');
bin_file_name=cell2mat(strcat( name_former(1),'.txt'));
[h,w]=size(image);
write_file=fopen(['.\result\',bin_file_name],'w');
code_len=0;
for i = 1:h
for j = 1:w
fprintf(write_file,dec2bin(cell2mat(code_table(image(i,j)+1))));
code_len=code_len+length(cell2mat(code_table(image(i,j)+1)));
end
end
compressing_rate=code_len/(h*w*8);
disp(['The Compression rate of ',bin_file_name,' is ',num2str(compressing_rate)])
fclose(write_file);
end
end
end
目前只实现的以01字符流写入文本,等有时间更新一下以01二进制流写入文件。