JPEG实验及程序参考.docx
《JPEG实验及程序参考.docx》由会员分享,可在线阅读,更多相关《JPEG实验及程序参考.docx(18页珍藏版)》请在冰豆网上搜索。
JPEG实验及程序参考
实验一JPEG图像压缩编码
一实验原理
1.数据分块
对图像进行编码前,将每个分量图像分割成不重叠的8×8像素块,每一个8×8像素块称为一个数据单元(DU)。
在彩色图像中,JPEG分别压缩图像的每个彩色分量。
虽然JPEG可以压缩通常的红绿蓝分量,但在YCbCr空间的压缩效果会更好。
这是因为人眼对色彩的变化不如对亮度的变化敏感,因而对色彩的编码可以比对亮度的编码粗糙些,这主要体现在不同的采样频率和量化精度上。
因此,编码前一般先将图像从RGB空间转换到YCbCr空间,再把各分量图像分割成8×8数据块。
对图像采样时,可以采用不同的采样频率,称为二次采样。
由于亮度比色彩更重要,因而对Y分量的采样频率可高于对Cb、Cr的采样频率,有利于节省存储空间。
常用的采样方案有YUV422和YUV411。
把采样频率最低的分量图像中一个DU所对应的像区上覆盖的所有各分量上的DU按顺序编组为一个最小编码单元(MCU)。
对灰度图像而言,只有一个Y分量,MCU就是一个数据单元。
对彩色图像而言,以4:
1:
1的采样方案为例,一个MCU由4个Y分量的DU、1个Cb分量的DU和1个Cr分量的DU组成。
2.DCT处理
图像数据块分割后,即以MCU为单位顺序将DU进行二维离散余弦变换。
对以无符号数表示的具有P位精度的输入数据,在DCT前要减去2P-1,转换成有符号数,而在IDCT后,应加上2P-1,转换成无符号数。
对每个8×8的数据块DU进行DCT后,得到的64个系数代表了该图像块的频率成分,其中低频分量集中在左上角,高频分量分布在右下角。
系数矩阵左上角的叫做直流(DC)系数,它代表了该数据块的平均值,其余63个叫交流(AC)系数。
3.系数量化
在DCT处理中得到的64个系数中,低频分量包含了图像亮度等主要信息。
在从空间域到频域的变换中,图像中的缓慢变化比快速变化更易引起人眼的注意,所以在重建图像时,低频分量的重要性高于高频分量。
因而在编码时可以忽略高频分量,从而达到压缩的目的,这也是量化的根据和目的。
在JPEG标准中,用具有64个独立元素的量化表来规定DCT域中相应的64个系数的量化精度,使得对某个系数的具体量化阶取决于人眼对该频率分量的视觉敏感程度。
理论上,对不同的空间分辨率、数据精度等情况,应该有不同的量化表。
不过,一般采用下图所示的量化表,可取得较好的视觉效果。
之所以用两张量化表,是因为Y分量比Cb和Cr更重要些,因而对Y采用细量化,而对Cb和Cr采用粗量化。
量化就是用DCT变换后的系数除以量化表中相对应的量化阶后四舍五入取整。
由于量化表中左上角的值较小,而右下角的值较大,因而起到保持低频分量、抑制高频分量的作用。
亮度量化表
色度量化表
4.Z型扫描
DCT系数量化后,构成一个稀疏矩阵,用Z(Zigzag)形扫描将其变成一维
数列,将有利于熵编码。
Z形扫描的顺序如图:
5.DC系数编码
DC系数反映了一个8×8数据块的平均亮度,一般与相邻块有较大的相关性。
JPEG对DC系数作差分编码,即用前一数据块的同一分量的DC系数作为当前块的预测值,再对当前块的实际值与预测值的差值作哈夫曼编码。
若DC系数的动态范围为-1024~+1024,则差值的动态范围为-2047~+2047。
如果为每个差值赋予一个码字,则码表过于庞大。
因此,JPEG对码表进行了简化,采用“前缀码(SSSS)+尾码”来表示。
前缀码指明了尾码的有效位数B,可以根据DIFF从表10-8中查出前缀码对应的哈夫曼编码。
尾码的取值取决于DC系数的差值和前缀码。
如果DC系数的差值DIFF大于等于0,则尾码的码字为DIFF的B位原码;否则,取DIFF的B位反码。
6.AC系数编码
经Z形排列后的AC系数,更有可能出现连续0组成的字符串,从而对其进行行程编码将有利于压缩数据。
JPEG将一个非零DC系数及其前面的0行程长度(连续0的个数)的组合称为一个事件。
将每个事件编码表示为“NNNN/SSSS+尾码”,其中,NNNN为0行程的长度,SSSS表示尾码的有效位数B(即当前非0系数所占的比特数),如果非零AC系数大于等于0,则尾码的码字为该系数的B位原码,否则,取该系数的B位反码。
由于只用4位表示0行程的长度,故在JPEG编码中,最大0行程只能等于15。
当0行程长度大于16时,需要将其分开多次编码,即对前面的每16个0以“F/0”表示,对剩余的继续编码。
二实验内容
实现基本JPEG的压缩和编码分三个步骤:
(1)首先通过DCT变换去除数据冗余;
(2)使用量化表对DCT系数进行量化;
(3)对量化后的系数进行Huffman编码。
三实验结果
实验图片:
Lena.bmpLenaRGB.bmp 都是512*512
灰度图像压缩比:
12:
115
彩色图像压缩比:
28:
171
程序:
%%AC_Huffman.m
functionACH=AC_Huffman(AC,n);
%亮度AC系数码表
T1={'1010''00''01''100''1011''11010''1111000''11111000'
'1111110110''1111111110000010''1111111110000011';
'1100''11011''1111001''111110110''11111110110'
'1111111110000100''1111111110000101''1111111110000110'
'1111111110000111''1111111110001000''0';
'11100''11111001''1111110111''111111110100'
'1111111110001001''1111111110001010''1111111110001011'
'1111111110001100''1111111110001101''1111111110001110''0';
'111010''111110111''111111110101''1111111110001111'
'1111111110010000''1111111110010001''1111111110010010'
'1111111110010011''1111111110010100''1111111110010101''0';
'111011''1111111000''1111111110010110''1111111110010111'
'1111111110011000''1111111110011001''1111111110011010'
'1111111110011011''1111111110011100''1111111110011101''0';
'1111010''11111110111''1111111110011110'
'1111111110011111''1111111110100000''1111111110100001'
'1111111110100010''1111111110100011''1111111110100100'
'1111111110100001''0';
'1111011''111111110110''1111111110100110'
'1111111110100111''1111111110101000''1111111110101001'
'1111111110101010''1111111110101011''1111111110101100'
'1111111110101101''0';
'11111010''111111110111''1111111110101110'
'1111111110101111''1111111110110000''1111111110110001'
'1111111110110010''1111111110110011''1111111110110100'
'1111111110110101''0';
'111111000''111111111000000''1111111110110110'
'1111111110110111''1111111110111000''1111111110111001'
'1111111110111010''1111111110111011''1111111110111100'
'1111111110111101''0';
'111111001''1111111110111110''1111111110111111'
'1111111111000000''1111111111000001''1111111111000010'
'1111111111000011''1111111111000100''1111111111000101'
'1111111111000110''0';
'111111010''1111111111000111''1111111111001000'
'1111111111001001''1111111111001010''1111111111001011'
'1111111111001100''1111111111001101''1111111111001110'
'1111111111001111''0';
'1111111001''1111111111010000''1111111111010001'
'1111111111010010''1111111111010011''1111111111010100'
'1111111111010101''1111111111010110''1111111111010111'
'1111111111011000''0';
'1111111010''1111111111011001''1111111111011010'
'1111111111011011''1111111111011100''1111111111011101'
'1111111111011110''1111111111011111''1111111111100000'
'1111111111100001''0';
'11111111000''1111111111100010''1111111111100011'
'1111111111100100''1111111111100101''1111111111100110'
'1111111111100111''1111111111101000''1111111111101001'
'1111111111101010''0';
'1111111111101011''1111111111101100''1111111111101101'
'1111111111101110''1111111111101111''1111111111110000'
'1111111111110001''1111111111110010''1111111111110011'
'1111111111110100''0';
'11111111001''1111111111110101''1111111111110110'
'1111111111110111''1111111111111000''1111111111111001'
'1111111111111010''1111111111111011''1111111111111100'
'1111111111111101''1111111111111111'};
%色度AC系数码表
T2={'00''01''100''1010''11000''11001''111000''1111000'
'111110100''1111110110''111111110100';
'1011''111001''11110110''111110101''11111110110'
'111111110101''1111111110001000''1111111110001001'
'1111111110001010''1111111110001011''0';
'11010''11110111''1111110111''111111110110'
'111111111000010''1111111110001100''1111111110001101'
'1111111110001110''1111111110001111''1111111110010000''0';
'11010''111110111''1111110111''11111110110'
'1111111110010001''1111111110010010''1111111110010011'
'1111111110010100''1111111110010101''1111111110010110''0';
'111010''111110110''1111111110010111''1111111110011000'
'1111111110011001''1111111110011010''1111111110011011'
'1111111110011100''1111111110011101''1111111110011110''0';
'111011''1111111001''1111111110011111''1111111110100000'
'1111111110100001''1111111110100010''1111111110100011'
'1111111110100100''1111111110100101''1111111110100010''0';
'1111001''11111110111''1111111110100111'
'1111111110101000''1111111110101001''1111111110101010'
'1111111110101011''1111111110101100''1111111110101101'
'1111111110101110''0';
'1111010''11111111000''1111111110101111'
'1111111110110000''1111111110110001''1111111110110010'
'1111111110110011''1111111110110100''1111111110110101'
'1111111110110110''0';
'11111001''1111111110110111''1111111110111000'
'1111111110111001''1111111110111010''1111111110111011'
'1111111110111100''1111111110111101''1111111110111110'
'1111111110111111''0';
'111110111''1111111111000000''1111111111000001'
'1111111111000010''1111111111000011''1111111111000100'
'1111111111000101''1111111111000110''1111111111000111'
'1111111111001000''0';
'111111000''1111111111001001''1111111111001010'
'1111111111001011''1111111111001100''1111111111001101'
'1111111111001110''1111111111001111''1111111111010000'
'1111111111010001''0';
'111111001''1111111111010010''1111111111010011'
'1111111111010100''1111111111010101''1111111111010110'
'1111111111010111''1111111111011000''1111111111011001'
'1111111111011010''0';
'111111010''1111111111011011''1111111111011100'
'1111111111011101''1111111111011110''1111111111011111'
'1111111111100000''1111111111100001''1111111111100010'
'1111111111100011''0';
'11111111001''1111111111100100''1111111111100101'
'1111111111100110''1111111111100111''1111111111101000'
'1111111111101001''1111111111101010''1111111111101011'
'1111111111101100''0';
'11111111100000''1111111111101101''1111111111101110'
'1111111111101111''1111111111110000''1111111111110001'
'1111111111110010''1111111111110011''1111111111110100'
'1111111111110101''0';
'1111111010''111111111000011''1111111111110110'
'1111111111110111''1111111111111000''1111111111111001'
'1111111111111010''1111111111111011''1111111111111100'
'1111111111111101''1111111111111111'};
%RLC行程编码
k=0;
j=1;
fori=1:
63
ifAC(i)==0&&k<15%非零系数前的零个数小于15
k=k+1;
else
ifk==15%非零个数为15
RLC(j)=15;
RLC(j+1)=0;
else%没有零在前面
RLC(j)=k;
RLC(j+1)=AC(i);
end
k=0;
j=j+2;
end
end
%最后一个数是零
ifAC(63)==0
RLC(j)=0;
RLC(j+1)=0;
end
%之前有若干组15个连零
while(length(RLC)>2)
if((RLC(length(RLC))==0)&&(RLC(length(RLC)-2)==0))
RLC=RLC(1:
length(RLC)-2);
RLC(length(RLC)-1)=0;
else
break
end
end
ACH='';
fori=1:
2:
length(RLC)
NNNN=RLC(i);
ifRLC(i+1)==0
SSSS=0;
elseifabs(RLC(i+1))==1
SSSS=1;
elseif(abs(RLC(i+1))>=2&&abs(RLC(i+1))<=3)
SSSS=2;
elseif(abs(RLC(i+1))>=4&&abs(RLC(i+1))<=7)
SSSS=3;
elseif(abs(RLC(i+1))>=8&&abs(RLC(i+1))<=15)
SSSS=4;
elseif(abs(RLC(i+1))>=16&&abs(RLC(i+1))<=31)
SSSS=5;
elseif(abs(RLC(i+1))>=32&&abs(RLC(i+1))<=63)
SSSS=6;
elseif(abs(RLC(i+1))>=64&&abs(RLC(i+1))<=127)
SSSS=7;
elseif(abs(RLC(i+1))>=128&&abs(RLC(i+1))<=255)
SSSS=8;
elseif(abs(RLC(i+1))>=256&&abs(RLC(i+1))<=511)
SSSS=9;
elseif(abs(RLC(i+1))>=512&&abs(RLC(i+1))<=1023)
SSSS=10;
end
%%求前缀码S1
ifn==1
ifNNNN==0|NNNN==15
S1=char(T1(NNNN+1,SSSS+1));
else
S1=char(T1(NNNN+1,SSSS));
end
else
ifNNNN==0|NNNN==15
S1=char(T2(NNNN+1,SSSS+1));
else
S1=char(T2(NNNN+1,SSSS));
end
end
%%求尾码S2
ifRLC(i)==0&&RLC(i+1)==0
S2='';
else
ifRLC(i+1)>=0
S2=dec2bin(RLC(i+1));
else
S2=dec2bin(abs(RLC(i+1)));
fori=1:
length(S2)
ifS2(i)=='1'
S2(i)='0';
else
S2(i)='1';
end
end
end
end
ACH=[ACHS1S2];
end
%%DC_Huffman.m
functionDCH=DC_Huffman(Z,last_Z,n);
%亮度码字
T1={'00''010''011''100''101''110''1110''11110''111110''1111110''11111110''111111110'};
%色度码字
T2={'00''01''10''110''11