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

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

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

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

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

%使得数据分布范围-127——127

B=int16(A(:

3))-128;

通过imread函数获取BMP图像的R、G、B三原色矩阵,因为下一步做DCT转换,二DCT函数要求输入为正负值,所以减去128,使得像素点分布范围变为-127~127,函数默认矩阵A的元素为无符号型(uint8),所以如果直接相减差值为负时会截取为0,所以先用int16将像素点的值转为带符号整数。

网上很多都提到了第一步的YUV转换,但是由于MATLAB在实验时YUV转换后色差失真比较严重,这里没有进行YUV转换。

个人理解为YUV转换后经过非R/G/B原理显示器显示效果可能会比较好,或者如果图像有色差可以选择YUV调整。

为了方便,读入的图像像素为400*296,是8*8的50*37倍,所以代码里没有进行8*8的整数倍调整。

2.8*8分块

R_8_8=R(1:

8,1:

8);

%取出一个8*8块

这里以R色压缩解码为例,后边解释均为R色编码解码过程,最后附全部代码。

R_8_8为:

3.DCT变换

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系数,左上角低频,右下角高频,可以看出量化后已经将多数高频量丢弃,从而实现数据压缩。

5.Zig_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<

15&

i~=64

r_n=r_n+1;

elseifRdcts_c_z(i)==0&

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;

elseifRdcts_c_z(i)~=0&

15

r_n==15

end

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

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

行程编码是指记录两个非0数之间0的个数,以及非零数的数值,非零数个数和数值为一组中间格式,这里为了计数方便,连续16个0出现时,用(15,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,1)、(2,-1)、(5,3)、(15,0)、(5,2)。

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

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

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

7.Huffman熵编码

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

数值

位数

编码

-1,1

1

0,1

-3,-2,2,3

2

00,01,10,11

-7,-6,-5,-4,4,5,6,7

3

000,001,010,…,101,110,111

-15,…,-8,8,…15

4

0000,0001,…,1110,1111

-31,…,-16,16,…31

5

00000,00001,…,11110,11111

-63,…,-32,32,…63

6

-127,…,-64,64,…127

7

-255,…,-128,128,…255

8

-511,…,-256,256,…511

9

-1023,…,-512,512,…1023

10

-2047,…,-1024,1024,…2047

11

12

13

14

熵编码后所得编码即为压缩后的代码,方便存储或者传输。

为了便于硬件实现,这里没有涉及到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));

%%cellstr将二进制字符串转为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

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

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

%%AC编码长度写入第二列

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

%%AC编码写入第三列

end

压缩后的编码表r_huff如下:

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

8.DC/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;

r_dc=Rdcts_c_z

(1);

else

ifbin2dec(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;

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

i_Rdcts_c_z(1,i_n)=0;

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

else

i_n+bin2dec(r_huff(k,1))-1)

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

当前位置:首页 > 工程科技 > 能源化工

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

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