音视频编码技术报告姓名: 学号:学院(系):电子与信息工程学院专业: 电子与通信工程题目: 基于DCT变换的图像压缩技术的仿真1.引言在信息世界迅猛发展的今天, 人们对计算机实时处理图像信息的要求越来越高。
如何在保证图像质量的前提下, 同时兼顾实时性和高效性成了一个值得关注的问题。
于是, 对图像信息进行一定的压缩处理成为了一个不可或缺的环节。
图像压缩是关于用最少的数据量来表示尽可能多的原图像的信息的一个过程。
本文主要研究基于DCT 变换的有损压缩编码技术。
离散余弦变换, 简称DCT , 是一种实数域变换, 其变换核为余弦函数, 计算速度快。
DCT 除了具有一般的正交变换性质外, 它的变换阵的基向量能很好地描述人类语音信号和图像信号的相关特征。
因此, 在对语音信号、图像信号的变换中,DCT 变换被认为是一种准最佳变换。
近年颁布的一系列视频压缩编码的国际标准建议中, 都把DCT 作为其中的一个基本处理模块。
而且对于具有一阶马尔柯夫过程的随机信号,DCT 十分接近于Karhunen -Loeve 变换, 也就是说它是一种最佳近似变换。
2.图像压缩编码的简介从信息论的角度看,图像是一个信源。
描述信源的数据是信息量和信息量冗余之和。
数据压缩实际上就是减少这些冗余量。
图像编码压缩的方法目前有很多,其分类方法根据出发点不同而有差异。
根据解压重建后的图像和原始图像之间是否具有误差(对原图像的保真程度),图像编码压缩分为无误差(亦称无失真、无损、信息保持)编码和有误差(有失真或有损)编码两大类。
无损压缩(冗余度压缩、可逆压缩):是一种在解码时可以精确地恢复原图像,没有任何损失的编码方法,但是压缩比不大,通常只能获得1~5倍的压缩比。
用于要求重建后图像严格地和原始图像保持相同的场合,例如复制、保存十分珍贵的历史、文物图像等。
有损压缩(不可逆压缩):只能对原始图像进行近似的重建,而不能精确复原,适合大数工用于存储数字化了的模拟数据。
压缩比大,但有信息损失,本文采用有损压缩。
DCT图像压缩编码可以概括成图2.1的框图。
图2.1 DCT压缩编码过程简化3.DCT变换最小均方误差下得到的最佳正交变化是K-L变换,而离散余弦变换(DCT)是仅次于K-L变换的次最佳变换,目前已获得广泛应用。
离散预先变换DCT用于图像压缩操作中的基本思路是,将图像分为8×8的子块或16×16的子块,并对每一个子块进行单独的DCT变换,然后对变换结果进行量化、编码。
DCT 压缩编码是一种正交变换,将二维图像变换为空间频谱,按从低频到高频的顺序重排。
由于图像频谱从低到高逐渐衰减,故可以在一定量化等级下进行舍弃,从而达到压缩的目的。
DCT 广泛应用于众多压缩方案的原因在于其理论、算法和硬件相对成熟,去相关性好,计算量不大,易于实现。
3.1. 一维DCT 算法长度为N 的一维序列{x(n):n=0,1,...,N-1}的DCT 定义为:∑-=+πα=10]4)12(2cos[)(2)()(N n Nn k n x N k k X k =0,1..,N-1 其中,⎩⎨⎧===α11021)(k k k 为正交化因子,它是为了保证变换基的规范正交性引入的。
一维DCT 反变换为:1,...,1,0]4)12(2cos[)()(2)(10-=+πα=∑-=N n N n k k X k N n x N k以N 维矢量x 表示原始数据,N 维矢量表示DCT 变换系数,就有: x u X ][=x u x T ][=变换矩阵[u]为:⎥⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎢⎣⎡π--π-π-ππ-π=N N N N N N N N N N N N u 2)1)(1(2cos 2)12(cos 212)1(3cos 23cos 212)1(cos 2cos 212][ 反变换矩阵IDCT 矩阵[u ]T 除了行、列号互换外,形式上与[u ]完全相同。
3.2. 二维DCT 算法二维数据{x(n,m);n=0,1,...,N-1,m=0,1,...,M-1}的DCT 变换定义为:Mm l N n k m n x MN l k l k X N n M m 2)12(cos 2)12(cos ),(2)()(),(1010+π+παα=∑∑-=-=1,,1,0;1,,1,0-=-=M l N k二维IDCT 为:Nn l M m k l k X l k MN n m x M k N l 2)12(cos 2)12(cos ),()()(2),(1010+π+παα=∑∑-=-=1,,1,0;1,,1,0-=-=M m N n其中,)(k α,)(l α定义与一维DCT 变换中的)(k α定义相同,用矩阵的形式表示为:X =[u ]x [v ]Tx =[u ]T X [v ]二维DCT 的变换是可分离的,即二维DCT 可以分解成行方向的一维DCT 和列方向的一维DCT ,可用两次一维DCT 实现二维DCT 。
4. Hilbert 扫描4.1. 概述变换编码一般有二维变换编码和一维变换编码两种方式。
二维变换编码,分别对行列进行变换,不需要扫描,它压缩效果较好,但运算量大,对一个N ×N 块要进行N 8次乘法。
为减少运算量,图像的子块不能太大,但子块越小,压缩比越小;一维变换编码先对图像块矩阵扫描生成一维向量,然后变换,虽然压缩效果没有二维变换的好,但运算量较小。
对一个N ×N 块,一维DCT 变换只要进行N 6次乘法。
在图像较大分块较多时,二维变换比一维变换的压缩和解压花费的时间都要多。
因此需要研究对一维变换编码影响较大的扫描技术。
图像扫描技术中,首先需要尽量减少生成数据的波动性。
由于Zigzag 扫描是一种普遍的扫描方式,本报告中不再详细叙述。
后面将着重介绍Hilbert 扫描。
基于图像存在局部连续性,同步步长平均距离越小,产生的数据波动性越小,因此Hilbert 扫描要由于其他传统扫描。
在DCT 压缩编码中使用这种扫描方式,可以在不减少压缩比,不增加计算量等前提下,达到较好的压缩效果。
4.2. Hilbert 扫描和Zigzag 扫描的比较图4.1、4.2分别是Zigzag 扫描和Hilbert 扫描的方法:图4.1 Z 字形扫描和Hilbert 扫描设m,n 是扫描序列中的两个虚数,}2,,2,1{,2k n m ∈。
称|m-n |为步长。
定义扫描曲线上两点距离为22)()(),(n m n m j j i i n m d -+-=。
L 步长的平均距离定义为:∑∑=-=-=Ln m L n m L n m d d ||||1),(。
它反映了扫描方式对数据波动性的作用。
同步长平均距离小,产生的数据波动性越小。
对于Zigzag 扫描:2)1(22,1)12(22221---=+--=N N d N d 对于Hilbert 扫描:22)2(2,12221---+==N a N a k k ,其中0k 42k 22,201=⎩⎨⎧++==+a a a a N kk k k ,为偶数为奇数。
由此可以看出随着k 的增加,Hilbert 扫描是要优于Zigzag 扫描的。
4.3. Hilbert 曲线的生成图4.2是Hilbert 曲线的生成示意:图4.2 Hilbert 曲线的生成本报告中没有采用传统的迭代算法构造Hilbert 扫描序列,而采用基于矩阵运算的递推算法。
将图4.2中的(a),(b),(c)用图4.3来表示:图4.3 各阶Hilbert 矩阵的形成5.编码仿真对于一幅120×120的图像分别采用二维DCT变化和Hilbert扫描法进行图像压缩编码处理。
进行Hilbert扫描处理时,先将图像分解为8×8的块,然后对每块进行扫描,生成1×64的一维向量,在对其进行一维DCT变换,对变换后获得的频域向量按压缩比保留系数,处理后进行一维反变换,再按反Hilbert扫描顺序重建8×8的块恢复图像。
整个过程如图5.1所示:图5.1 编码过程6.实验结果本次实验从两个角度进行了仿真,一维DCT变换对比了不同的扫描策略。
二维的DCT变换对比了不同的量化系数。
以下为一维DCT变换中采取Zigzag和Hilbert扫描策略处理的结果对比图图6.1 量化系数为3,图6.2 量化系数为16图6.1(a)Hilbert扫描,量化系数为3图6.1(b)Zigzag扫描,量化系数为3图6.2(a)Hilbert扫描,量化系数为16图6.2(b)Zigzag扫描,量化系数为16通过以上实验发现在同样的量化系数下,Hilbert扫描可以更好的保留图像中的细节信息,但代价就是影响了压缩效果。
在量化系数为3的情况下,使用Hilbert 扫描的到的图像大小为75.7K,而使用Zigzag扫描得到的图像为41.9K原始图像大小为116K。
以下为调整二维DCT变换量化系数的结果比较图图6.3结果汇总图6.4是量化系数为1时的效果图图6.4量化系数为1图6.5是量化系数为6的效果图图6.5量化系数为6可以发现细节信息得到了明显的改善。
图6.6是量化系数为28图6.6量化系数为28对比相应的压缩文件发现量化系数为1时图像的大小为23.6K,量化系数为6时图像大小为74.6K,量化系数为28时,图像大小为124K。
通过以上结果发现图像经过DCT变换之后会有大部分的信息是冗余的,仅需较小的量化系数就可以得到较好质量的图像。
通过上面的仿真可知采用一维的DCT变换和采用二维的DCT变换都各有各的优点。
具体使用哪种方式需要根据具体的应用环境进行选择。
7.附录——代码7.1.二维DCT变化主程序clear all;clc;A=imread('chaiquan.jpg');% 量化矩阵m=[16 11 10 16 24 40 51 6112 12 14 19 26 58 60 5514 13 16 24 40 57 69 5614 17 22 29 51 87 80 6218 22 37 56 68 109 103 7724 35 55 64 81 104 113 9249 64 78 87 103 121 120 10172 92 95 98 112 100 103 99];A1=A;A=double(A);t=dctmtx(8);mask=zeros(8);%%%%%%%%%%%%%%%%%%%%%%%%%%创建8*8所有的量化系数masks = zeros(8,8,8);index = zeros(1,8);for i=1:8for j=1:imasks(j,1:i+1-j,i) = 1;index(i) = sum(masks(j,:,i))+index(i);endendchoose_index=[1 3 7];mask1(:,:,1) = masks(:,:,choose_index(1));N_index(1,1)=index(choose_index(1));mask1(:,:,2) = masks(:,:,choose_index(2));N_index(1,2)=index(choose_index(2));mask1(:,:,3) = masks(:,:,choose_index(3));N_index(1,3)=index(choose_index(3));%%for i=1:3mask = mask1(:,:,i);y1=blkproc(A,[8,8],'P1*x*P2',t,t');%DCT变换y2=blkproc(y1,[8 8],'round(x./P1)',m);%量化y3=blkproc(y2,[8 8],'x.*P1.*P2',mask,m);%反量化时mask掉一些DCT系数B=blkproc(y3,[8 8],'P1*x*P2',t',t);%IDCTimwrite(uint8(B),strcat('D:\YB\documents\研究生课程\课设\音视频\M\DCTexample\量化系数',num2str(index(choose_index(i))),'.jpg'));subplot(3,5,(i-1)*5+1);imshow(A1);title('原始图像');% 将8*8的mask矩阵放大64倍后以格子图像的形式显示(可删除)------beginmaskx=mat2gray(mask);maskx=imresize(maskx,64,'nearest');for line=1:512for col=1:512if(mod(line,64)<4 | mod(col,64)<4 | mod(line,64)>60 | mod(col,64)>60)maskx((line-1)*512+col)=bitxor(maskx((line-1)*512+col),1);endendendsubplot(3,5,(i-1)*5+2);imshow(maskx);title('DCT系数mask矩阵');% 将8*8的mask矩阵放大64倍后以格子图像的形式显示(可删除)------endsubplot(3,5,(i-1)*5+3);imshow(mat2gray(B));title('重建图像');%重构图像d=A-B;%原始图像-重构图像subplot(3,5,(i-1)*5+4);imshow(mat2gray(d));title('误差图像');[h,k]=hist(d(:),512);subplot(3,5,(i-1)*5+5);bar(k,h);title('误差直方图');end7.2.一维DCT变换%一维DCT变换主程序clear allclcimg = imread('chaiquan.jpg');[M,N]=size(img);m = M/8;n = N/8;N_index=[3,16,30]; %量化系数image_zigzag = zeros(M,N);image_hilbert = image_zigzag;z = zeros(8,8);for index=1:3for i=1:mfor j=1:nz = img((i-1)*8+1:(i-1)*8+8,(j-1)*8+1:(j-1)*8+8);z_zigzag = zigzagscan(z,N_index(index));z_hilbert = uint8(scanhilbert(z,N_index(index)));image_zigzag((i-1)*8+1:(i-1)*8+8,(j-1)*8+1:(j-1)*8+8) = z_zigzag;image_hilbert((i-1)*8+1:(i-1)*8+8,(j-1)*8+1:(j-1)*8+8) = z_hilbert;endendfiguresubplot(1,2,1),imshow(mat2gray(image_zigzag)),title(strcat('zigzag扫描,量化系数为',num2str(N_index(index))));imwrite(uint8(image_zigzag),strcat('zigzag扫描,量化系数为',num2str(N_index(index)),'.jpg')); subplot(1,2,2),imshow(mat2gray(image_hilbert)),title(strcat('hilbert扫描,量化系数为',num2str(N_index(index))));imwrite(uint8(image_hilbert),strcat('hilbert扫描,量化系数为',num2str(N_index(index)),'.jpg')); End%zigzag扫描function z_idct = zigzagscan(z,N)c_b_idct = zeros(1,64);zigzag = [ 1, 2, 9, 17, 10, 3, 4, 11, ...18, 25, 33, 26, 19, 12, 5, 6, ...13, 20, 27, 34, 41, 49, 42, 35, ...28, 21, 14, 7, 8, 15, 22, 29, ...36, 43, 50, 57, 58, 51, 44, 37, ...30, 23, 16, 24, 31, 38, 45, 52, ...59, 60, 53, 46, 39, 32, 40, 47, ...54, 61, 62, 55, 48, 56, 63, 64];Fq1 = reshape(z,1,64); % 将输入块变成1x64的向量b = Fq1(zigzag); % 对aa 按照查表方式取元素,得到zig-zag 扫描结果b_dct = dct(b);b_dct(1,N:64)=0;b_idct = idct(b_dct);for i=1:64c_b_idct(1,zigzag(i))= b_idct(i);endz_idct=reshape(uint8(b_idct),8,8);end%希尔伯特扫描输入扫描分块输出生成的向量function z_ihilbert = scanhilbert(z,N)[x,y]=size(z);z1=mypeano_hilbert2(x*y);%求出对应大小的分块的扫描方式z2=zeros(1,x*y);for i=1:x*yfor m=1:xfor n=1:yt=z1(m,n);z2(t)=z(m,n);endendendz2_dct=dct(z2);z2_dct(1,N:64) = 0;z2_idct = idct(z2_dct);z_ihilbert = iscanhilbert(z2_idct);end%希尔伯特扫描步进方式输入扫描分块的大小输出扫描的过程function y1=mypeano_hilbert2(k)n=log2(k)/2;y=[1 2;4 3];for j=2:ni=j-1;e=ones(2^(j-1));if rem(i,2)==0y=[y 2^(2*i)*e+y';(2^(2*i+1)+2^(2*i))*e+flipud(fliplr(y)) 2^(2*i+1)*e+y'];elsey=[y (2^(2*i+1)+2^(2*i))*e+flipud(fliplr(y));2^(2*i)*e+y' 2^(2*i+1)*e+y'];endendy1=y;end%输入hilbert扫描的向量输出重拍后对应的分块function z = iscanhilbert(z2)n=log2(length(z2))/2;z=zeros(2^n,2^n);z1=mypeano_hilbert2((2^n)*(2^n));%求出对应大小的分块的扫描方式for i=1:2^nfor j=1:2^nz(i,j)=z2(z1(i,j));endendend%希尔伯特扫描输入扫描分块输出生成的向量%改程序用于输入分块进行希尔伯特扫描然后进行DCT变换量化后调整重拍输出对应分块function z_ihilbert = hilbertscan(z,N)[x,y]=size(z);z1=mypeano_hilbert2(x*y);%求出对应大小的分块的扫描方式z2=zeros(1,x*y);for i=1:x*yfor m=1:xfor n=1:yt=z1(m,n);z2(t)=z(m,n);endendendz2_dct=dct(z2);z2_dct(1,N:64) = 0;z2_idct = idct(z2_dct);z_ihilbert = uint8(iscanhilbert(z2_idct));end。