1.霍夫曼编码和解码
clear
clc
I=imread('lena.bmp');
I=im2double(I)*255;
[height,width]=size(I); %求图像的大小
HWmatrix=zeros(height,width);
Mat=zeros(height,width); %建立大小与原图像大小相同的矩阵HWmatrix和Mat,矩阵元素为0。
HWmatrix(1,1)=I(1,1); %图像第一个像素值I(1,1)传给HWmatrix(1,1)
for i=2:height %以下将图像像素值传递给矩阵Mat
Mat(i,1)=I(i-1,1);
end
for j=2:width
Mat(1,j)=I(1,j-1);
end
for i=2:height %以下建立待编码的数组symbols和每个像素出现的概率矩阵p
for j=2:width
Mat(i,j)=I(i,j-1)/2+I(i-1,j)/2;
end
end
Mat=floor(Mat);HWmatrix=I-Mat;
SymPro=zeros(2,1); SymNum=1; SymPro(1,1)=HWmatrix(1,1); SymExist=0;
for i=1:height
for j=1:width
SymExist=0;
for k=1:SymNum
if SymPro(1,k)==HWmatrix(i,j)
SymPro(2,k)=SymPro(2,k)+1;
SymExist=1;
break;
end
end
if SymExist==0
SymNum=SymNum+1;
SymPro(1,SymNum)=HWmatrix(i,j);
SymPro(2,SymNum)=1;
end
end
end
for i=1:SymNum
SymPro(3,i)=SymPro(2,i)/(height*width);
end
symbols=SymPro(1,:);p=SymPro(3,:);
[dict,avglen] = huffmandict(symbols,p); %产生霍夫曼编码词典,返回编码词典dict和平均码长avglen
actualsig=reshape(HWmatrix',1,[]);
compress=huffmanenco(actualsig,dict); %利用dict对actuals来编码,其结果存放在compress中
UnitNum=ceil(size(compress,2)/8);
Compressed=zeros(1,UnitNum,'uint8');
for i=1:UnitNum
for j=1:8
if ((i-1)*8+j)<=size(compress,2)
Compressed(i)=bitset(Compressed(i),j,compress((i-1)*8+j));
end
end
end
NewHeight=ceil(UnitNum/512);Compressed(width*NewHeight)=0;
ReshapeCompressed=reshape(Compressed,NewHeight,width);
imwrite(ReshapeCompressed,'Compressed Image.bmp','bmp');
Restore=zeros(1,size(compress,2));
for i=1:UnitNum
for j=1:8
if ((i-1)*8+j)<=size(compress,2)
Restore((i-1)*8+j)=bitget(Compressed(i),j);
end
end
end
decompress=huffmandeco(Restore,dict); %利用dict对Restore来解码,其结果存放在decompress中
RestoredImage=reshape(decompress,512,512);
RestoredImageGrayScale=uint8(RestoredImage'+Mat);
imwrite(RestoredImageGrayScale,'Restored Image.bmp','bmp');
figure;
subplot(1,3,1);imshow(I,[0,255]); %显示原图
subplot(1,3,2);imshow(ReshapeCompressed); %显示压缩后的图像
subplot(1,3,3);imshow('Restored Image.bmp'); %解压后的图像
2.行程编码方法对二值图像进行编解码
clear
clc
I1=imread('lena.bmp'); %读入图像
I2=I1(:); %将原始图像写成一维的数据并设为 I2
I2length=length(I2); %计算I2的长度
I3=im2bw(I1,0.5); %将原图转换为二值图像,阈值为0.5
%以下程序为对原图像进行行程编码,压缩
X=I3(:); %令X为新建的二值图像的一维数据组
L=length(X);
j=1;
I4(1)=1;
for z=1:1:(length(X)-1) %行程编码程序段
if X(z)==X(z+1)
I4(j)=I4(j)+1;
else
data(j)=X(z); % data(j)代表相应的像素数据
j=j+1;
I4(j)=1;
end
end
data(j)=X(length(X)); %最后一个像素数据赋给data
I4length=length(I4); %计算行程编码后的所占字节数,记为I4length
CR=I2length/I4length; %比较压缩前于压缩后的大小
%下面程序是行程编码解压
l=1;
for m=1:I4length
for n=1:1:I4(m);
decode_image1(l)=data(m);
l=l+1;
end
end
decode_image=reshape(decode_image1,512,512); %重建二维图像数组
figure,
x=1:1:length(X);
subplot(131),plot(x,X(x));%显示行程编码之前的图像数据
y=1:1:I4length ;
subplot(132),plot(y,I4(y));%显示编码后数据信息
u=1:1:length(decode_image1);
subplot(133),plot(u,decode_image1(u));%查看解压后的图像数据
subplot(121);imshow(I3);%显示原图的二值图像
subplot(122),imshow(decode_image); %显示解压恢复后的图像
disp('压缩比: ')
disp(CR);
disp('原图像数据的长度:')
disp(L);
disp('压缩后图像数据的长度:')
disp(I4length);
disp('解压后图像数据的长度:')
disp(length(decode_image1));
3.对图像进行JPEG编码
clear
clc
ORIGIN=imread('lena.bmp'); %读入原始图像
%步骤1:正向离散余弦变换(FDCT)
fun=@DCT_Measure;
%步骤2:量化
B=blkproc(ORIGIN,[8,8],fun); %得到量化后的系数矩阵,与原始图像尺寸相同,需要进一步处理
n=length(B)/8; %对每个维度分成的块数
C=zeros(8); %初始化为8×8的全0矩阵
for y=0:n-1
for x=0:n-1
T1=C(:,[end-7:end]); %取出上一组数据做差分,T1的所有8行和最后8列组成的8*8
T2=B(1+8*x:8+8*x,1+8*y:8+8*y);
T2(1)=T2(1)-T1(1); %直流系数做差分
C=[C,T2]; %将C和T2矩阵串联
end
end
C=C(:,[9:end]); %去除C的前8列,就是前面的全0
%步骤4:利用Code_Huffman( )函数实现上述JPEG算法步骤中的步骤3、4、5和6步
JPGCode={''}; %存储编码的元胞初始化为空的字符串
for a=0:n^2-1
T=Code_Huffman(C(:,[1+a*8:8+a*8]));
JPGCode=strcat(JPGCode,T);
end
sCode=cell2mat(JPGCode); %将元胞转化为数组
Fid=fopen('JPGCode.txt','w'); %用变量fid标记I/O流,打开文本文件
fprintf(Fid,'%s',sCode); %将压缩码sCode保存到文本文件中。添加而不是覆盖
fclose(Fid); %关闭I/O流
[x y]=size(A);
b=x*y*8/length(sCode);
v=8/b; %计算压缩比和压缩效率
disp('JPEG压缩数据已保存至JPGCode.txt中!');
disp(['压缩比为:',num2str(b),';压缩效率:',num2str(v)]);
最后:
如果你想要进一步了解更多的相关知识,可以关注下面公众号联系~会不定期发布相关设计内容包括但不限于如下内容:信号处理、通信仿真、算法设计、matlab appdesigner,gui设计、simulink仿真......希望能帮到你!