一种基于MATLAB的JPEG图像压缩具体实现方法Word文件下载.docx

上传人:b****7 文档编号:22095749 上传时间:2023-02-02 格式:DOCX 页数:6 大小:21.44KB
下载 相关 举报
一种基于MATLAB的JPEG图像压缩具体实现方法Word文件下载.docx_第1页
第1页 / 共6页
一种基于MATLAB的JPEG图像压缩具体实现方法Word文件下载.docx_第2页
第2页 / 共6页
一种基于MATLAB的JPEG图像压缩具体实现方法Word文件下载.docx_第3页
第3页 / 共6页
一种基于MATLAB的JPEG图像压缩具体实现方法Word文件下载.docx_第4页
第4页 / 共6页
一种基于MATLAB的JPEG图像压缩具体实现方法Word文件下载.docx_第5页
第5页 / 共6页
点击查看更多>>
下载资源
资源描述

一种基于MATLAB的JPEG图像压缩具体实现方法Word文件下载.docx

《一种基于MATLAB的JPEG图像压缩具体实现方法Word文件下载.docx》由会员分享,可在线阅读,更多相关《一种基于MATLAB的JPEG图像压缩具体实现方法Word文件下载.docx(6页珍藏版)》请在冰豆网上搜索。

一种基于MATLAB的JPEG图像压缩具体实现方法Word文件下载.docx

R_8_8为:

    变换R_DCT=dct2(R_8_8);

使用MATLAB函数dct2进行DCT变换,也可使用DCT变换矩阵相乘的方法,即R_DCT=A*R_8_8*AT,其中A为DCT变换矩阵。

R_DCT为:

    4.量化  R_dct_s=round(R_DCT./S);

    使用JPEG标准亮度量化表S量化并取整,S为:

    R_dct_s为:

    其中第一个数-14为DC系数,剩余63个数为AC系数,左上角低频,右下角高频,可以看出量化后已经将多数高频量丢弃,从而实现数据压缩。

  _Zag扫描  Rdcts_c=reshape(R_dct_s’,1,64);

  Rdcts_c_z=Rdcts_c(zig);

    利用reshape函数将量化后的矩阵转为[1,64]行向量,利用zig向量按位取值,进行Zig_Zag扫描。

其中Rdcts_c为:

  11~64位均为0;

  zig为:

  zig=[0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63];

  Zig_Zag扫描后的向量Rdcts_c_z为:

    可以看出通过zig向量按位取值准确实现了对量化后DC,AC系数的Zig_Zag扫描。

  6.获取DC/AC系数的中间格式r_dc_diff=Rdcts_c_z

(1)-r_dc;

  用当前DC系数减去上一个8*8子块的DC系数得到两DC系数的差值作为DC系数中间值,因为图像相邻像素具有很大的相关性,这样做可以减小DC编码长度,进一步压缩代码,在解码的时候通过该差值依次获得各8*8子块DC系数。

  r_dc=Rdcts_c_z

(1);

  解码之后用该代码将当前DC系数赋给r_dc作为下一次编码时求差值的参考值。

  fori=2:

1:

64;

  ifRdcts_c_z(i)==0&

&

r_n  elseifRdcts_c_z(i)==0&

r_n  r_AC(1,2*r_ac_cnt)=Rdcts_c_z(i);

  r_n=0;

  elseifRdcts_c_z(i)~=0&

r_n==15  r_ac_cnt=r_ac_cnt+1;

  r_AC(1,2*r_ac_cnt-1)=r_n;

  r_AC(1,2*r_ac_cnt)=Rdcts_c_z(i);

  elseifRdcts_c_z(i)==0&

endend  该for循环用来获取AC系数的中间格式,因为第一个数为DC系数,所以循环从2开始。

因为63个AC系数中有很多值为0,所以采用行程编码可以很大的减小编码长度。

行程编码是指记录两个非0数之间0的个数,以及非零数的数值,非零数个数和数值为一组中间格式,这里为了计数方便,连续16个0出现时,用表示,继续获取下一个AC系数中间格式,也就是说行程编码压缩的最大长度设为16bit,例如数列:

1、0、0、-1、0、0、0、0、0、3、0、0、0、0、0、0、0、0、0、0、0、0、0、0、0、0、0、0、0、0、0、2;

对该列数通过形成编码获取中间格式即为:

、、、、。

第一个数为0的个数,第二个数为数值,特殊情况指16个0。

  通过该for循环获取AC系数中间格式并保存在向量Rdcts_c_z中,奇数表示0的个数,偶数表示AC系数数值。

  表示前两个数  是1,后边共有16*3+13=61个0,与量化表相同。

  熵编码  熵编码可以根据Huffman算法对每个量化后的矩阵进行现场编码,但是这样会增加传输数据,所以这里采用标准HuffmanVLI编码表进行编码,VLI编码表如下:

数值位数编码000-1,110,1-3,-2,2,3200,01,10,11-7,-6,-5,-4,4,5,6,73000,001,010,…,101,110,111-15,…,-8,8,…1540000,0001,…,1110,1111-31,…,-16,16,…31500000,00001,…,11110,11111-63,…,-32,32,…636…-127,…,-64,64,…1277…-255,…,-128,128,…2558…-511,…,-256,256,…5119…-1023,…,-512,512,…102310…-2047,…,-1024,1024,…204711……12……13……14……15…熵编码后所得编码即为压缩后的代码,方便存储或者传输。

为了便于硬件实现,这里没有涉及到Huffman亮度表,而是依据VLI编码表,通过DC/AC系数的数值确定位数和编码,熵编码上表中的位数和编码两部分组成,即压缩后的编码包括两部分,然后再依据VLI编码表,通过位数和编码返回DC/AC系数,编码中还包含了AC系数中0的个数。

0的个数和位数均用4bit二进制数表示。

  r_huff=cell(r_ac_cnt+1,3);

%%建立三列矩阵保存压缩后的编码,第一例为0的个数,第二列为编码长度,第三例为编码  forj=0:

r_ac_cnt;

ifj==0  [siz,code]=vli(r_dc_diff);

%%通过vli编码函数对DC差值进行编码,获得DC差值编码长度和编码,vli函数见附录。

  %[siz,code]=vli(r_dc);

%%通过vli函数获取AC系数编码及编码长度  r_huff(1,1)=cellstr(dec2bin(0));

%?

llstr将二进制字符串转为cell格式放入矩阵  r_huff(1,2)=cellstr(dec2bin(siz,4));

%%将哈夫曼编码长度存为4bit  r_huff(1,3)=cellstr(dec2bin(code,siz));

%%将哈夫曼编码转为二进制  r_code_bit=r_code_bit+siz;

  %%计算编码长度else  ifr_AC(2*j)==0  r_huff(j+1,1)=cellstr(dec2bin(r_AC(2*j-1),4));

%%将0的个数写入第一列  r_huff(j+1,2)=cellstr(dec2bin(0));

  r_huff(j+1,3)=cellstr(dec2bin(0));

else  r_huff(j+1,1)=cellstr(dec2bin(r_AC(2*j-1),4));

  [siz,code]=vli(r_AC(2*j));

      r_huff(j+1,2)=cellstr(dec2bin(siz,4));

  %?

编码长度写入第二列  r_huff(j+1,3)=cellstr(dec2bin(code,siz));

编码写入第三列  r_code_bit=r_code_bit+siz;

    %%计算编码长度endendend  压缩后的编码表r_huff如下:

此时已将8*8*8=512bit压缩为4+6*8+2+1+1=56bit。

    /AC系数Huffman熵解码i_n=1;

  fork=1:

r_ac_cnt+1;

  ifk==1  [i_value]=i_vli(r_huff(1,2),r_huff(1,3))  %%i_vli函数解码,i_vli通过编码长度和编码恢复DC/AC系数真值,函数见附录。

  i_Rdcts_c_z(1,i_n)=r_dc+i_value;

  %i_Rdcts_c_z(1,i_n)=r_huff(1,3);

  i_n=i_n+1;

else  ifbin2dec(r_huff(k,1))==15&

bin2dec(r_huff(k,2))==0i_Rdcts_c_z(1,i_n:

i_n+15)=0;

%%出现中间格式返16个0  i_n=i_n+16;

  elseifbin2dec(r_huff(k,1))==0&

bin2dec(r_huff(k,2))==0  i_Rdcts_c_z(1,i_n)=0;

%%出现中间格式反1个0,没有具体分析这种情况到底是否存在,但是如果最后一位恰好为0,此时恰好开始新的中间格式计算,i=64时终止计算,则中间格式为  i_n=i_n+1;

    else  i_Rdcts_c_z(1,i_n:

i_n+bin2dec(r_huff(k,1))-1)=0;

%%哈夫曼编码矩阵r_huff中为二进制数,所以用到了bin2dec  i_n=i_n+bin2dec(r_huff(k,1));

%%通过第一列分解重复的0

  

      i_value=i_vli(r_huff(k,2),r_huff(k,3));

%%通过第二三列,编码长度和编码解出AC系数真值  i_Rdcts_c_z(1,i_n)=i_value;

  %%将解码后的DC/AC系数放入向量i_Rdcts_c_z  i_n=i_n+1;

endendend  9.反Zig_Zag扫描  i_Rdcts_c=i_Rdcts_c_z(i_zig);

  %%反zig_zag扫描i_Rdct_s(1,1:

8)=i_Rdcts_c(1:

  %%变为矩阵形式i_Rdct_s(2,1:

8)=i_Rdcts_c(9:

16);

i_Rdct_s(3,1:

8)=i_Rdcts_c(17:

24);

i_Rdct_s(4,1:

8)=i_Rdcts_c(25:

32);

i_Rdct_s(5,1:

8)=i_Rdcts_c(33:

40);

i_Rdct_s(6,1:

8)=i_Rdcts_c(41:

48);

i_Rdct_s(7,1:

8)=i_Rdcts_c(49:

56);

i_Rdct_s(8,1:

8)=i_Rdcts_c(57:

64);

  通过按位取值的方法进行反Zig_Zag扫描,并将扫描获得的向量转为8*8矩阵,其中:

i_zag为:

  i_zig=[1,2,6,7,15,16,28,29,3,5,8,14,17,27,30,43,4,9,13,18,26,31,42,44,10,12,19,25,32,41,45,54,11,20,24,33,40,46,53,55,21,23,34,39,47,52,56,61,22,35,38,48,51,57,60,62,36,37,49,50,58,59,63,64];

  i_Rdct_s为:

    10.反量化、反DCT变换  i_Rdct=round(i_Rdct_s.*S);

  %%反量化并取整i_R_8_8=round(idct2(i_Rdct));

  %%逆DCT变换其中i_R_8_8为:

    11.解码图像显示  fori_r=1:

37;

      fori_c=1:

50;

  end  end用这样一个嵌套for循环将所有8*8子块进行基于DCT变换的JPEG编码解码处理,i_R(i_r*8-7:

i_r*8,i_c*8-7:

i_c*8)=i_R_8_8;

在循环最后通过该语句将每一个8*8子块放到i_R矩阵中,然后i_R加128得到解码后R色像素矩阵i_RR。

分别对G、B像素矩阵做同样算法处理,得到解码后的像素矩阵i_GG、i_BB。

i_A(:

1)=i_RR;

  i_A(:

2)=i_GG;

3)=i_BB;

%%将解码后三元色矩阵放入三维矩阵u_i_A=uint8(i_A);

将矩阵元素设为无符号整型imshow(u_i_A);

成功!

压缩前后图像对比:

    因为没有直接查询Huffman编码表,增加了0的个数和编码长度的编码,压缩比会稍微降低,该方法所获得的压缩率,即压缩了近5倍。

  附录:

  %%  %%作者:

chengbo  %%功能:

JPEG图像压缩  %%说明:

该程序只是JPEG图像压缩算法的简单验证,为了便于处理,所压缩图像像素为400*296,是8*8的整数倍,使用标准哈夫曼编码表编码和解码,没有进行颜色修正,所以没有进行YUV转换,直接进行RGB编码压缩,R/G/B三原色均使用JPEG标准亮度量化矩阵进行量化clearall;

clc;

  A=imread(‘messi_’);

  %读取BMP图像矩阵  R=int16(A(:

  %读取RGB矩阵,于DCT时输入为正负输入,G=int16(A(:

2))-128;

  %使得数据分布范围-127——127B=int16(A(:

  S=[1611101624405161;

  %JPEG标准亮度量化矩阵  1212141926586055;

  1413162440576956;

  1417222951878062;

  182237566810910377;

  243555648110411392;

  49647887103121120101;

  7292959811210010399];

  zig=[0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,...  %zig_zag扫描向量  12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,...  35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,...  58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63];

  i_zig=[1,2,6,7,15,16,28,29,3,5,8,14,17,27,30,43,...%反zig_zag扫描向量  4,9,13,18,26,31,42,44,10,12,19,25,32,41,45,54,...  11,20,24,33,40,46,53,55,21,23,34,39,47,52,56,61,...  22,35,38,48,51,57,60,62,36,37,49,50,58,59,63,64];

zig=zig+1;

r_dc=0;

r_n=0;

  r_AC=zeros;

r_all_bit=0;

  fori_r=1:

    %@0*296可以分为50*37个8*8子块fori_c=1:

r_ac_cnt=0;

  R_8_8=R(i_r*8-7:

i_c*8);

%取出一个8*8块  R_DCT=dct2(R_8_8);

    %对这一个8*8矩阵进行DCT变化R_dct_s=round(R_DCT./S);

  %量化取整Rdcts_c=reshape(R_dct_s’,1,64);

    Rdcts_c_z=Rdcts_c(zig);

  %zig_zag扫描r_dc_diff=Rdcts_c_z

(1)-r_dc;

  %求DC差值%r_dc=Rdcts_c_z

(1);

    ?

编码中间值,奇数为0的个数,偶数为AC数值ifRdcts_c_z(i)==0&

endend  r_huff=cell(r_ac_cnt+1,3);

  %%根据中间值查VLI标准编码表进行哈夫曼编码r_code_bit=0;

  %%因为编码后的值为二进制,所以建立cell型矩阵存放要发送编码forj=0:

  %%通过vli编码函数对DC差值进行编码%[siz,code]=vli(r_dc);

  r_huff(1,1)=cellstr(dec2bin(0));

llstr将二进制字符串转为cell格式放入矩阵  r_huff(1,2)=cellstr(dec2bin(siz,4));

%%将哈夫曼编码bit数存为4bit  r_huff(1,3)=cellstr(dec2bin(code,siz));

  r_huff(j+1,3)=cellstr(dec2bin(0));

编码长度写入第二例  r_huff(j+1,3)=cellstr(dec2bin(code,siz));

编码写入第三例  r_code_bit=r_code_bit+siz;

    %%计算编码长度endendend  r_all_bit=r_all_bit+r_ac_cnt*8+4+r_code_bit;

  %%计算三原色R压缩后的总编码bit数i_n=1;

  ifk==1  [i_value]=i_vli(r_huff(1,2),r_huff(1,3))  %%i_vli函数解码  i_Rdcts_c_z(1,i_n)=r_dc+i_value;

  i_n=i_n+1;

bin2dec(r_huff(k,2))==0  i_Rdcts_c_z(1,i_n:

  %%出现中间格式反16个0  i_n=i_n+16;

    %%出现中间格式反1个0  i_n=i_n+1;

  %%没有具体分析这种情况到底是否存在,但是如果最后一位恰好为0,  else    %%此时恰好开始新的中间格式计算,i=64时终止计算,则中间格式为  i_Rdcts_c_z(1,i_n:

%%哈夫曼编码矩阵r_huff中为二进制数,所以用到了bin3dec  i_n=i_n+bin2dec(r_huff(k,1));

    %%通过第一列分解重复的0  i_value=i_vli(r_huff(k,2),r_huff(k,3));

  %%通过第二三列,位数和编码解出编码真值  i_Rdcts_c_z(1,i_n)=i_value;

endendend  i_Rdcts_c=i_Rdcts_c_z(i_zig);

    %%反zig_zag扫描i_Rdct_s(1,1:

    %%变为矩阵形式i_Rdct_s(2,1:

  i_Rdct=round(i_Rdct_s.*S);

    %%反

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 农学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1