多媒体技术与应用实验之Huffman编解码matlab实现

多媒体技术与应用实验之Huffman编解码matlab实现
主函数:

clc;
clear;
close all ;
X=imread( 'lena.bmp' ); %图像灰度化
data=uint8(X); 
[zipped,info]=huffencode(data); %调用 Huffman 编码程序进行压缩 
unzipped=huffdecode(zipped,info); %调用 Huffman 编码程序进行解码

subplot(121);imshow(data);title( ' 原始图像 ' ); 
subplot(122);imshow(unzipped);title( 'Huffman 编码并解码后图像 ' ); 
disp( ' 平均码长 ' );L=info.avalen 
disp( ' 压缩比 ' );CR=info.ratio 
disp( ' 信息熵 ' );H=info.h 
disp( ' 编码效率 ' );CE=info.ce
disp( ' 编码 ' );huffcode = info.huffcodes

编码函数:

function [zipped,info]=huffencode(vector) 

[m,n]=size(vector); %求输入矩阵的行列数 
vector=vector(:)'; %将矩阵按列转换成一列后转至,成为一个行向量 ( 其中存放灰度值 ) 
f=frequency(vector); %0-255灰度概率,值为概率
symbols=find(f~=0); %概率不为零的灰度值,1-215 值为灰度值
f=f(symbols); %筛选后概率向量,0-255 去0概率
[f,sortindex]=sort(f); %排序升序,sortindex筛选后的序号
fs=f; 
symbols=symbols(sortindex); %灰度值按概率排序
len=length(symbols); %读取位置向量的长度 

symbols_index=num2cell(1:len); %生成异质矩阵
codeword_tmp=cell(len,1); %异质变量 存放码字
while length(f)>1     % Huffman 树,得二进制码表
    index1=symbols_index{1}; 
    index2=symbols_index{2};    
    codeword_tmp(index1)=addnode(codeword_tmp(index1),uint8(0)); %添加节点且该分支按 0 标记 
    codeword_tmp(index2)=addnode(codeword_tmp(index2),uint8(1)); %添加节点且该分支按 1 标记 
    f=[sum(f(1:2)) f(3:end)]; %求出两个最小概率之和,列出其他概率,组成一个新的行向量 
    symbols_index=[{[index1,index2]} symbols_index(3:end)]; %合并已编码的符号索引 
    [f,sortindex]=sort(f); %将新的概率向量按照概率从小到大排序   
    symbols_index=symbols_index(sortindex); %得到新的索引表
end 

codeword=cell(256,1); 
codeword(symbols)=codeword_tmp; %各符号二进制码字按原符号位存入细胞型矩阵
len=0; 
for i=1:length(symbols) %得到各符号码长矩阵
    wordlen(i)=length(codeword_tmp{i}); 
end
avawordlen=fs*wordlen'; %计算平均码长
Hlog=log2(fs)'; 
H=-(fs*Hlog); %计算信息熵 

for index=1:length(vector) %得到整个图像各点灰度值转化为二进制码字后的总比特数
    len=len+length(codeword{double(vector(index))+1}); 
end

string=repmat(uint8(0),1,len); %创建元素数与总比特数一致的行向量 
pointer=1; %定义指针变量 
for index=1:length(vector)  % 对输入图像进行编码 
    code=codeword{double(vector(index))+1}; %对应符号的二进制码字给 
    len=length(code); %读取码字长度 
    string(pointer+(0:len-1))=code; %将二进制码字存入行向量中 
    pointer=pointer+len; %指针移移位
end
% 将二进制编码按照每 8 位生成一个新字符。
len=length(string); 
zp=8-mod(len,8); 
if zp>0     
    string=[string uint8(zeros(1,zp))]; %不足 8 位的在后补零
end

codeword=codeword(symbols); %码字按符号概率放入列向量中 
codelen=zeros(size(codeword)); %创建与列向量元素数相同的列向量

%将二进制转化为十进制
weights=2.^(0:23); 
for index=1:length(codeword)    
    len=length(codeword{index}); %读二进制码字长度
    if len>0         
        code=sum(weights(codeword{index}==1)); %计算二进制码字对应的十进制数 
        code=bitset(code,len+1); %将码字最高位的上一位置 1 
        codeword{index}=code;         
        codelen(index)=len; %码字长度存入列向量中
   end 
end

codeword=[codeword{:}]; %转化为行向量



%计算压缩后的向量
cols=length(string)/8; 
string=reshape(string,8,cols); 
weights=2.^(0:7); 
zipped=uint8(weights*double(string)); %码表存储到一个稀疏矩阵



huffcodes=sparse(1,1);

for index=1:nnz(codeword) 
    huffcodes(codeword(index),1)=symbols(index); 
end
%返回编码参数
% info.zeropad=zp; %添加的比特数 
info.huffcodes=huffcodes; %码字表 
info.length=length(vector); %灰度化图像矩阵长度
info.rows=m; %灰度图像行数
info.cols=n; %灰度图像列数
info.avalen=avawordlen; %平均码长 
info.ratio=8/avawordlen; %压缩比 
info.h=H; %信息熵 
info.ce=H/avawordlen; %编码效率 
end

解码函数:

%huffdecode 函数对输入矩阵 vector 进行 Huffman 编码,返回解压后的图像数据
function vector=huffdecode(zipped,info) 
len=length(zipped); %读取压缩矩阵长度 
string=repmat(uint8(0),1,len*8); %创建全为 0的行向量
bitindex=(1:8); 
for index=1:len %还原成01串
    string(bitindex+8.*(index-1))=uint8(bitget(zipped(index),bitindex)); % 读取压缩矩阵中的值并转化为 8位二进制按顺序放入 string 矩阵中
end 
len=length(string); 
%开始解码
vector=repmat(uint8(0),1,info.length); %创建与灰度化图像行向量等长的行向量
vectorindex=1; 
codeindex=1; 
code=0; 
for index=1:len-1     
    code=bitset(code,codeindex,string(index)); %按位读编码码字 
    codeindex=codeindex+1; %移位 
    byte=decode(bitset(code,codeindex),info); %进行码字匹配,读取相对应符号   
    if byte>0 %若读取到对应符号则进行下面操作,无符号继续按位读取码字 
        vector(vectorindex)=byte-1; %将符号表示的灰度值放入容器矩阵中 
        codeindex=1; %重置 
        code=0; %重置 
        vectorindex=vectorindex+1; %容器指针移位
    end 
end
vector=reshape(vector,info.rows,info.cols); %将构成的灰度矩阵按原图矩阵行列 数重构,解码完成
end

检测频率概率:

%函数 frequency 计算各符号出现的概率
function f=frequency(vector) 
f=zeros(1,256); %设置一个 256 个元素都为 0 的行向量 
len=length(vector); %读取输入矩阵元素个数
for index=0:1:255    
    f(index+1)=sum(vector==index); %统计输入图像矩阵中 0 至 255 各值出现的个数, 存入一个行向量中
end
f=f./len; %求各符号值出现的概率
end

decode:

%函数 decode 返回码字对应的符号 
function byte=decode(code,info)
byte=info.huffcodes(code); 
end

addnode:

%函数 addnode 添加节点确定符号码字
function codeword_new=addnode(codeword_old,item) 
codeword_new=cell(size(codeword_old)); %前一步码字维数作为新细胞型变量的维数, 用于存放码字 
for index=1:length(codeword_old) %确定符号对应码字
    codeword_new{index}=[item codeword_old{index}]; 
end
end
### 回答1: Huffman编码是一种压缩算法,它根据字符出现的频率建立编码表,使得出现频率高的字符用较短的编码表示,出现频率低的字符用较长的编码表示。 在MATLAB中,可以使用以下步骤来解码Huffman编码: 1. 读取Huffman编码和待解码的比特流。 2. 根据Huffman编码构建解码表。解码表可以使用MATLAB中的字典数据结构存储,其中键是Huffman编码,值是对应的字符。 3. 从比特流中按照位逐个读取,直到找到匹配的编码。找到匹配的编码后,将对应的字符添加到解码序列中,并重置匹配编码的搜索。 4. 重复步骤3,直到比特流被完全解码。 5. 将解码序列输出或保存。 以下是一个简单的MATLAB实现示例: ```matlab function decodedData = huffmanDecode(huffmanCode, bitStream) % 构建解码表 decodeTable = containers.Map(huffmanCode.Value, huffmanCode.Key); % 解码比特流 decodedData = ""; code = ""; for i = 1:length(bitStream) code = code + bitStream(i); % 逐位读取比特流 if isKey(decodeTable, code) decodedData = decodedData + decodeTable(code); % 找到匹配的编码,添加对应的字符 code = ""; % 重置编码 end end end ``` 需要注意的是,上述示例仅适用于Huffman编码和比特流的解码过程,并不包括压缩编码的解析和生成Huffman编码的步骤。若需要实现完整的Huffman压缩解压功能,还需要编写相应的编码和解码函数。 ### 回答2: Huffman算法是一种常用于数据压缩的算法,能够根据数据的出现频率对其进行编码和解码。下面是一个用MATLAB实现Huffman算法解码的简单示例。 首先,我们需要准备好Huffman编码表和待解码的数据。Huffman编码表是由Huffman算法生成的,其中包含了各个字符对应的二进制编码。待解码的数据是用Huffman编码表进行编码后的二进制序列。 接下来,我们需要通过读取Huffman编码表,将二进制序列逐个字符地进行解码。具体的解码过程如下: 1. 创建一个空字符串变量decodingStr作为解码结果的累计变量。 2. 从待解码的二进制序列中读取一个字符。 3. 将这个字符与已解码的字符串进行匹配,查找出对应的字符值。 4. 如果找到了对应的字符值,将这个字符值添加到解码结果的字符串中,同时将已解码的字符串清空,以便下一次匹配。 5. 如果没找到对应的字符值,继续从待解码的二进制序列中读取下一个字符,然后重复第3步和第4步的操作,直到找到字符值或者将二进制序列全部解码完毕。 6. 最后,将得到的解码结果输出。 需要注意的是,在解码过程中,为了提高效率,可以使用一些数据结构来快速地进行查找操作,比如哈希表。 以上就是用MATLAB实现Huffman算法解码的简单示例。具体的实现过程和代码细节可以根据实际情况进行调整和优化。 ### 回答3: Huffman算法是一种数据压缩算法,用于将数据流进行编码和解码。在Huffman编码中,出现频率越高的字符被赋予较短的编码,而出现频率较低的字符被赋予较长的编码。 要使用Huffman算法进行解码,首先需要获取Huffman编码表。这可以通过统计每个字符在编码前的数据流中出现的频率来生成。然后按照Huffman的规则生成编码表,将每个字符及其对应的编码记录在表中。在解码过程中,需要根据编码表将编码后的数据流恢复为原始的数据。 在MATLAB中,可以使用以下步骤进行Huffman解码: 1. 定义编码表:将编码表以特定的数据结构(如cell数组或字典)保存起来。编码表中需要包含每个字符及其对应的Huffman编码。 2. 读取编码后的数据流:将Huffman编码后的数据流读入MATLAB中。 3. 解码过程:根据编码表,逐个读取数据流中的比特位。从数据流中读取的比特位逐渐与编码表进行匹配,直到找到对应的字符。然后将该字符记录下来,并继续匹配下一个字符。 4. 迭代直到数据流结束:重复上述步骤,直到读取完所有的比特位,并找到每个字符。 5. 恢复原始数据:由于解码过程中记录了每个字符的顺序,可以根据顺序将解码得到的字符逐个连接起来,从而恢复原始的数据。 需要注意的是,编码表的生成和解码步骤需要基于相同的字符频率统计。因此,在进行Huffman编码和解码之前,需要确保编码表与编码数据的频率统计一致。 通过以上步骤,可以在MATLAB中使用Huffman算法进行解码,将编码后的数据流恢复为原始的数据。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值