实验四-DCT变换HUFFman编码图像压缩
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验四图像压缩
姓名:学号:邮箱:
一、实验目的
1.掌握DCT变换的原理
2.了解DCT变化在图像压缩中的应用
3.掌握图像压缩的基本原理及方法
4.了解霍夫曼编码原理
5.熟悉图像压缩的MATLAB编程
二、实验原理
DCT是目前比较好的图像变换,它有很多优点。DCT是正交变换,它可以将8x8图像空间表达式转换为频率域,只需要用少量的数据点表示图像;DCT产生的系数很容易被量化,因此能获得好的块压缩;DCT算法的性能很好,它有快速算法,如采用快速傅立叶变换可以进行高效的运算,因此它在硬件和软件中都容易实现;而且DCT算法是对称的,所以利用逆DCT算法可以用来解压缩图像。
由于DCT主要应用在数据和图像的压缩,因此希望原信号的能量在变换后能尽量集中在少数系数上,且这些大能量的系数能处在相对集中的位置,这将有利于进一步的量化和编码。但是如果对整段的数据或整幅图像来做DCT,那就很难保证大能量的系数能处在相对集中的位置。因此,在实际应用中,一般都是将数据分成一段一段来做,一般分成8x8或16x16的方块来做。
二维DCT正交变换的公式为:
二维DCT逆变换公式:
其中
三、实验要求
利用DCT变换对图像进行压缩,对比不同压缩比下的结果,对比不同压缩比下图像大小的变化。压缩过程如下图所示:
四、实验过程与结果
实验程序如下:(先给出主程序,然后给出各功能子函数的程序)
主程序:
clear
load('lena.mat')%调入170*170大小的一幅彩色lena图像
l=imresize(lena,[256 256]);%将图像变换为8的整数倍大小
X=rgb2gray(l);
Y1=double(X);%读入图像数据
lianghua=[16 11 10 16 24 40 51 61;%量化矩阵,量化的程度序决定压缩比
12 12 14 19 26 58 60 55;
14 13 16 24 40 57 69 56;
14 17 22 29 51 87 80 62;
18 22 37 56 68 109 103 77;
24 35 55 64 81 104 113 92;
49 64 78 87 103 121 120 101;
72 92 95 98 112 100 103 99];
ilianghua=lianghua;%------------------------------------
----------------------
%图像压缩
%------------------------------------
----------------------
t=dctmtx(8);
J=blkproc(Y1,[8 8],'P1*x*P2',t,t'); %
分成8*8块进行DCT变换
M=blkproc(J,[8
8],'round(x./P1)',lianghua); %量化
u=abs(min(min(M1));
M=(M1./u)+1;
data=uint8(M);%Huffman编码要求为无符
号整形数组
M2=M-double(data);
[zipped,info]=huffencode(data);
%调用Huffman编码程序进行压缩
unzipped=huffdecode(zipped,info,data) ; %调用Huffman解码程序进行解压缩
k=1;
for i=1:256
for j=1:256
unzippedray(i,j)=unzipped(k);
k=k+1;
end
end
unzippedray= unzippedray';%对解压缩后得到的一维数组进行变换,得到无损的量化后
%二维数组,其值与data数组值是一致的,体现了Huffman编码是一种无损编码unzippedray=(double(unzippedray)-1+M2 ).*u;
T=blkproc(unzippedray,[8
8],'x.*P1',ilianghua); %反量化
I=blkproc(T,[8
8],'P1*x*P2',t',t); %8*8DCT反变换
%----------------------------------------------------------
%调用Huffman编码程序进行解码
%显示原始图像和经编码后的图像,显示压缩比,并计算均方根误差得erms=0,表示是Huffman是无失真编码
figure
subplot(221);imshow(Y1,[]);axis square;xlabel('原256*256灰度图像'); subplot(222);imshow(I,[]);axis square;xlabel('Huffman解压缩后图像'); subplot(223);imshow((Y1-I),[]);axis square;xlabel('量化后损失的图像部分');
[h,k]=hist((Y1-I),256);%生成直方图数据
subplot(224);bar(k,h,'k');title('误差图像直方图');
%subplot(224);imshow(I,[]);axis square;xlabel('压缩图像');
%erms=compare(data(:),unzipped(:))
cr=info.ratio whos data unzipped zipped
%huffencode函数对输入矩阵vector进行Huffman编码,返回%编码后的向量(压缩后数据)及相关信息
Huffman编码子程序:
function
[zipped,info]=huffencode(vector)
%输入和输出都是unit8格式
%info返回解码需要的机构信息
%info.pad是添加的比特数
%info.huffcodes是Huffman码字
%info.rows是原始图像行数
%info.cols是原始图像行数
%info.length是原始图像数据长度
%info.maxcodelen是最长码长
if ~isa(vector,'uint8')
error('input argument must be a uint8 vector');
end
[m,n]=size(vector);
vector=vector(:)';
f=frequency(vector); %计算各符号出现的概率
symbols=find(f~=0);
f=f(symbols);
[f,sortindex]=sort(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));
codeword_tmp(index2)=addnode(codeword _tmp(index2),uint8(1));
f=[sum(f(1:2)) f(3:end)];
symbols_index=[{[index1,index2]} symbols_index(3:end)];