注:本博客为个人根据教材内容进行整理,有不足之处敬请指正。
教材函数整理
8.2 编码冗余
entropy函数:计算矩阵的一阶熵估计
function h = entropy( x,n )
%ENTROPY 计算了一个矩阵熵的一阶估计
% h = entropy( x,n )返回具有N个符号(N=256)的矩阵X的一阶估计
%该估计假设一个统计独立的来源,其特征在于X中元素的相对出现频率。
error(nargchk(1,2,nargin)); %check input arguments
if nargin < 2
n =256;
end
x = double(x); %make input double
xh = hist(x(:),n); %计算N-bin直方图
figure; imshow(xh);
xh = xh / sum(xh(:)); %计算概率
%make mask to eliminate 0's since log2(0) = -inf
i = find(xh);
h = -sum(xh(i) .* log2(xh(i))); %计算熵
end
8.2.1
Huffman函数
huffman.m
function CODE = huffman( p )
%HUFFMAN 为一个符号资源构建一个可变长的huffman编码
% code = huffman(p)对于输入符号概率向量P以二值字符串的形式返回一个哈夫曼编码
%check the input arguments for reasonableness
error(nargchk(1,1, nargin));
if (ndims(p) ~= 2) | (min(size(p))>1) | ~isreal(p) | ~isnumeric(p)
error('P must be a real numeric vector.');
end
%global varibale surviving all recursions of function 'makecode'
global CODE
CODE = cell(length(p), 1); %初始化全局元胞数组
if length(p) > 1 %when mor than one symbol...
p = p / sum(p); %归一化输入概率
s = reduce(p); %do huffman source symbol reductions
makecode(s,[]); %递归生成编码
else
CODE = {'1'}; %else, trivial one symbol case!
end
%--------------------------------------------------------------------------------------%
function s = reduce(p);
%通过执行源符号缩减在单元结构中创建霍夫曼源减少树,
%直到只剩下两个减少的符号
s = cell(length(p),1);
%生成具有符号节点1,2,3,...的起始树以引用符号概率
for i = 1:length(p)
s{i} = i;
end
while size(s) > 2
[p,i] = sort(p); %符号概率分类
p(2) = p(1) +p(2); %合并两个最低概率
p(1) = []; %丢弃最低值
s = s(i); %对新的概率重新排列树
s{2} = {s{1} , s{2}}; %并且合并和简化他的节点
s(1) = []; %以匹配概率
end
end
end
makecode.m
function makecode(sc, codeword)
%以递归方式扫描霍夫曼源简化树的节点以生成指示的可变长度码字
%global variable surviving all recursive calls
global CODE
if isa(sc,'cell') %对于元胞数组节点,
makecode(sc{1}, [codeword 0]); %如果是第1个元素,增加一个0
makecode(sc{2}, [codeword 1]); %如果是第2个元素,增加一个1
else %对于叶子(数字)节点,
CODE{sc} = char('0' + codeword); %创建一个字符编码字符串
end
end
一个问题是,我是按照课本上编写的,但是运行之后的Huffman编码里面有几项为空,修改之后也不知道是什么问题
运行代码和结果如下:
p = [0.1875 0.5 0.125 0.1875];
c = huffman(p);