注:本部落格為個人根據教材内容進行整理,有不足之處敬請指正。
教材函數整理
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);