一种基于MATLAB的JPEG图像压缩具体实现方法(2)

2019-01-10 12:09

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; end end end

9.反Zig_Zag扫描

i_Rdcts_c=i_Rdcts_c_z(i_zig); %%反zig_zag扫描 i_Rdct_s(1,1:8)=i_Rdcts_c(1:8); %%变为矩阵形式 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为:(可见与DCT变换前差别不大)

11.解码图像显示

for i_r=1:1:37;

for i_c=1: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;

i_A(:,:,3)=i_BB;%%将解码后三元色矩阵放入三维矩阵 u_i_A=uint8(i_A);将矩阵元素设为无符号整型 imshow(u_i_A);成功!!! 压缩前后图像对比:

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

附录:

%%

%%作者:chengbo

%%功能:JPEG图像压缩

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

A=imread('messi_b.bmp'); %读取BMP图像矩阵

R=int16(A(:,:,1))-128; %读取RGB矩阵,由于DCT时输入为正负输入, G=int16(A(:,:,2))-128; %使得数据分布范围-127——127 B=int16(A(:,:,3))-128;

S=[16 11 10 16 24 40 51 61; %JPEG标准亮度量化矩阵 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];

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;

for i_r=1:1:37; %@0*296可以分为50*37个8*8子块 for i_c=1:1:50; r_ac_cnt=0;

R_8_8=R(i_r*8-7:i_r*8,i_c*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);

for i=2:1:64; ?编码中间值,奇数为0的个数,偶数为AC数值 if Rdcts_c_z(i)==0&&r_n<15&&i~=64 r_n=r_n+1;

elseif Rdcts_c_z(i)==0&&r_n<15&&i==64 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); r_n=0;

elseif Rdcts_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); r_n=0;

elseif Rdcts_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); r_n=0;

elseif Rdcts_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); r_n=0; end end

r_huff=cell(r_ac_cnt+1,3); %%根据中间值查VLI标准编码表进行哈夫曼编码 r_code_bit=0; %%因为编码后的值为二进制,所以建立cell型矩阵存放要发送编码 for j=0:1:r_ac_cnt; if j==0

[siz,code]=vli(r_dc_diff); %%通过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_code_bit=r_code_bit+siz; %%计算编码长度 else

if r_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; %%计算编码长度 end end end

r_all_bit=r_all_bit+r_ac_cnt*8+4+r_code_bit; %%计算三原色R压缩后的总编码bit数 i_n=1;

for k=1:1:r_ac_cnt+1; if k==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_Rdcts_c_z(1,i_n)=r_huff(1,3);

i_n=i_n+1;

r_dc=Rdcts_c_z(1); else

if bin2dec(r_huff(k,1))==15&&bin2dec(r_huff(k,2))==0

i_Rdcts_c_z(1,i_n:i_n+15)=0; %%出现中间格式(15,0)反16个0 i_n=i_n+16;

elseif bin2dec(r_huff(k,1))==0&&bin2dec(r_huff(k,2))==0

i_Rdcts_c_z(1,i_n)=0; %%出现中间格式(0,0)反1个0 i_n=i_n+1; %%没有具体分析这种情况到底是否存在,但是如果最后一位恰好为0,

else %%此时恰好开始新的中间格式计算,i=64时终止计算,则中间格式为(0,0)

i_Rdcts_c_z(1,i_n:i_n+bin2dec(r_huff(k,1))-1)=0;%%哈夫曼编码矩阵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; i_n=i_n+1; end end end

i_Rdcts_c=i_Rdcts_c_z(i_zig); %%反zig_zag扫描 i_Rdct_s(1,1:8)=i_Rdcts_c(1:8); %%变为矩阵形式 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);

i_Rdct=round(i_Rdct_s.*S); %%反量化并取整 i_R_8_8=round(idct2(i_Rdct)); %%逆DCT变换

i_R(i_r*8-7:i_r*8,i_c*8-7:i_c*8)=i_R_8_8; %%将一个8*8子块放回R色新矩阵中 end end

i_RR=i_R+128; %%范围调回至0——255 %后边同理依次为G、B编码和解码 g_dc=0;


一种基于MATLAB的JPEG图像压缩具体实现方法(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:天津市建设工程设计合同(房屋建筑工程) GF-2015-071

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: