function c = shannon(p)
% p = [0.2 0.15 0.15 0.1 0.1 0.1 0.1 0.1]
% shannon(p)
[p , index] = sort(p) ;%让p中的元素升序排列
p = fliplr(p) ;% 让p中的元素倒序排列
n = length(p) ;%计算p中元素的个数
pa = 0 ; %累加概率的计算
for i = 2:n
pa(i) = pa(i - 1) + p(i - 1) ;
end
k = ceil(-log2(p)) ; %对子信息量的向上取整,计算的是码长
c = cell(1,n) ;
for i = 1:n
c{i} = '' ;
tmp = pa(i) ;
for j = 1:k(i)
tmp = tmp * 2 ;
if tmp >= 1
tmp = tmp -1 ;
c{i}(j) ='1' ;
else
c{i}(j) ='0' ;
end
end
end
c = fliplr(c) ;
c(index) = c ;
functionc = fano(p)
% p= [0.25 0.25 0.20 0.15 0.10 0.05]
% c= fano(p)
n =size(p , 2) ;
%已经编码完成
if n ==1
c= cell(1,1);
c{1}= '' ;
return
end
[p ,index] = sort(p);%按概率排序
p =fliplr(p) ;
total= sum(p) ;%总概率
acc= 0 ;%累积概率
flag= 0 ;%是否到达尾部的标志
for i =1:n-1
newacc= acc + p(i) ;
if abs(total- 2 * newacc) >= abs(total - 2 * acc)
flag= 1 ;
break;
end
acc= newacc ;
end
if ~flag
i= n ;
end
split= i ;
%从分界点对两边的码递归做fano
c1 =fano(p(1:split-1)) ;
c2 =fano(p(split:n)) ;
c =cell(1,n) ;
%添加前缀0,1
for i =1:split-1
c{i}= strcat('0' , c1{i}) ;
end
for i =split:n
c{i}= strcat('1' , c2{i - split + 1} ) ;
end
%将顺序调整回去
c =fliplr(c) ;
c(index)= c ;
function c = huffman(p)
% p = [0.2 0.15 0.15 0.1 0.1 0.1 0.1 0.1]
n = size(p , 2) ;%给出p中元素个数
if n == 1 %信源是不是缩减到一个元素,若if为真
c = cell(1,1) ;
c{1} = '' ;%开始回溯
return
end
[p1 , i1] = min(p) ;%把p中最小元素给p1,i1记录p1的位置
index = [(1:i1-1) , (i1+1:n)] ;%找到第一个最小概率并剔除
p = p(index) ;
n = n - 1 ;
[p2 , i2] = min(p) ;
index2 = [(1:i2-1) , (i2+1:n)] ;
p = p(index2);
i2 = index(i2) ;
index = index(index2) ;
p(n) = p1 + p2 ; %在信源中添加新符号概率为最小概率相加
c = huffman(p) ; %递归调用huffman函数,进一步的进行信源缩减,直到信源元素为一
c{n+1} = strcat(c{n} , '1') ;
c{n} = strcat(c{n} , '0') ;
index = [index , i1 , i2] ;
c(index) = c ;%在回溯过程中重新建立编码
image1=imread('C:\Program Files\MATLAB71\work\1\girl.jpg'); %读入图像
imshow(image1); %显示原图像(右图)
% 以下程序是将原图像转换为二值图像
image2=image1(:); %将原始图像写成一维的数据并设为 image2
image2length=length(image2); % 计算image2的长度
for i=1:1:image2length % for 循环,目的在于转换为二值图像
if image2(i)>=127
image2(i)=255;
else image2(i)=0;
end
end
image3=reshape(image2,146,122); % 重建二维数组图像,并设为image3
figure,imshow(image3);%(右图)
% 以下程序为对原图像进行游程编码,压缩
X=image3(:); %令X为新建的二值图像的一维数据组
x=1:1:length(X); % 显示游程编码之前的图像数据
figure,
plot(x,X(x));
j=1;
image4(1)=1;
for z=1:1:(length(X)-1) % 游程编码程序段
if X(z)==X(z+1)
image4(j)=image4(j)+1;
else
data(j)=X(z); % data(j)代表相应的像素数据
j=j+1;
image4(j)=1;
end
end
data(j)=X(length(X)); % 最后一个像素数据赋给data
image4length=length(image4); % 计算游程编码后的所占字节数,记为image4length
y=1:1:image4length ; % 显示编码后数据信息
figure,
plot(y,image4(y));
CR=image2length/image4length; % 比较压缩前于压缩后的大小
% 下面程序是游程编码解压
l=1;
for m=1:image4length
for n=1:1:image4(m);
rec_image(l)=data(m);
l=l+1;
end
end
u=1:1:length(rec_image); % 查看解压后的图像数据
figure,plot(u,rec_image(u));
rec2_image=reshape(rec_image,146,122); % 重建二维二维图像数组
figure,imshow(rec2_image); % 显示解压恢复后的图像
functionf = acl(p , c)
%f =acl(p,c)
%p:probability, c:code
%return :average code length
c =fano(p);
f =0 ;
r =0 ;
for i =1:length(p)
f= f + p(i) * length(c{
i
});
end
for i =1:length(p)
r= r - p(i)* log2(p(i)) ;
end
H =r
L =f
P =H/L