Chinaunix首页 | 论坛 | 博客
  • 博客访问: 849000
  • 博文数量: 168
  • 博客积分: 5431
  • 博客等级: 大校
  • 技术积分: 1560
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-22 11:56
文章存档

2015年(2)

2014年(1)

2013年(12)

2012年(12)

2011年(15)

2010年(5)

2009年(16)

2008年(41)

2007年(64)

分类: C/C++

2007-11-26 16:47:05

4.直流系数的差分编码

把所有的颜色分量单元按颜色分量(YCrCb)分类。每一种颜色分量内,相邻的两个颜色分量单元的直流变量是以差分来编码的。也就是说,通过步骤3解码出来的直流变量数值只是当前颜色分量单元的实际直流变量减去前一个颜色分量单元的实际直流变量。也就是说,当前直流变量要通过前一个颜色分量单元的实际(非解码)直流分量来校正:

DCn=DCn-1+Diff

其中Diff为差分校正变量,也就是直接解码出来的直流系数。但如果当前颜色分量单元是第一个单元,则解码出来的直流数值就是真正的直流变量。

再次提醒的是,3个颜色分量的直流变量是分开进行差分编码的。也就是说,为1张图片解码时应设置3个独立的直流校正变量。另一个问题是,当数据流中出现标记RSTn,则3个颜色分量的直流差分校正变量Diff都需要重新复位到0

 

5.反量化

不同的颜色分量使用不同的量化表,这个可以从标记段SOF中的颜色分量信息字段查得。一般是Y分量使用量化表0,而CrCb两个分量共同使用量化表1

反量化的过程比较简单。只需要对8*8的颜色分量单元的64个值逐一乘以对应的量化表内位置相同的值则可。图像内全部的颜色分量单元都要进行反量化。

 

6Zig-zag编码

如果将反量化后的每个8*8颜色分量单元的每个元素编号,如下图4,那么各反Zig-zag编码的过程就是把矩阵元素按图5重新排列。

       

4 将颜色分量单元元素编码                          5 Zig-zag编码

 

关于量化和反Zig-zag编码的先后顺序,笔者查阅的几份资料有不同的见解。经过实践试验,解码的过程中,是应该直接用文件提供的量化表反量化矩阵数据,再将其反Zig-zag编码才能正确解码。

 

7.隔行的正负纠正

这个问题比较特别,因为在笔者认真阅读的几份资料中都没有提及此问题。而是笔者通过对已知图像进行JPEG编码压缩,然后和该图的JPEG文件数据对比发现的问题。具体原因不明。

实际上,就是必须对每个颜色分量单元的奇数行(每个颜色分量单元有8行,假设把它按01、……、67编出行号),即1357行,进行取相反数操作(正的变负,负的变正)。

 

8.反离散余弦变换

之前提到,文件中的数据是在编码时通过正向离散余弦变换(FDCT)进行时空域向频率域变换而得到的结果,所以现在解码就必须将其反向离散余弦变换(IDCT),就是把颜色分量单元矩阵中的频率域数值向时空域转换。并且,原来的频率域的矩阵大小为8*8,则经过反向离散余弦变换后,时空域的矩阵仍然是8*8

设正负纠正后的频率域矩阵为F[u][v],而反向离散余弦变换后的矩阵为f[i][j],其中0u,v,i,j7。具体使用的公式如下:

,其中

Cu= (当u=0),Cu=1(当u0);

Cv= (当v=0),Cu=1(当v0);

 

另外补充一下正向离散余弦变换的公式,用于编码:

 

9YCrCbRGB转换

要在屏幕上显示图像,就必须以RGB模式表示图像的颜色。所以,解码时需要把YCrCb模式向RGB模式转换。

正如前面提到,并不是每种颜色分量的采样因子都一样,所以转换时需要注意。如果采样因子是111,则每一个像素点的3个颜色分量都被采样,所以没有问题。但411的采样因子就不一样了。由“初步了解图像数据流的结构”一节中对411的采样因子的分析,可以知道一个MCU里有4Y分量单元,而Cr分量和Cb分量各自只有1个分量单元。以图2为例,仅有的一个Cr分量单元(红色的64个采样点)应该平铺用于4Y分量单元,即左上角16个值用于Y1,右上角16个值用于Y2,左下角16个值用于Y5,右下角16个值用于Y6。换句话说,一个Cr采样点服务于4Y采样点。对于Cb分量,道理一样。

另外,由于离散余弦变化要求定义域的对称,所以在编码时把RGB的数值范围从[0255]统一减去128偏移成[-128127]。因此解码时必须为每个分量加上128。具体公式如下:

R=Y                       +1.402*Cb     +128;

G=Y-0.34414*Cr    -0.71414*Cb   +128;

B=Y                       +1.772*Cb     +128;

还有一个问题,通过变换得出的RGB值可能超出了其定义域,所以要作出检查。如果大于255,则截断为255;如果小于0,则截断为0

 

下面补充RGB模式向YCrCb模式的公式:

Y =0.299*R            +0.587*G       +0.114*B    ;

Cr=   -0.1687*R      - 0.3313*G     +0.5*B  +128;

Cb=0.5 *R              - 0.4187*G     - 0.0813*B+128;

 

至此,每个MCU的解码已经完成。而每一个MCU如何组成一幅完整的图像,请参考初步了解图像数据流的结构分析。


参考文献

[1] 李才伟,中山大学计算机系多媒体课程教学课件.

[2]     张益贞,Visual C++实现MPEG/JPEG编解码技术.北京:人民邮电出版社

[3] CCITInformation Technology-digital Compression and Conding of Continuous-ton Still Images-requirements and Guidelines (访问日期:2007-1-1

[4] 公子御风,JFIF文件格式即JPEG文件交换格式(JPEG File Interchonge Format) (访问日期:2006-12-29

[5] 云风,JPEG 简易文档 V2.11 (访问日期:2006-12-30


附录:JPEG定义的标记

标记名

标记代码

说明

帧开始标记,Start of Frame,非层次哈夫曼编码

SOF0

0xFFC0

基线离散余弦变换

SOF1

0xFFC1

扩展顺序离散余弦变换

SOF2

0xFFC2

递进离散余弦变换

SOF3

0xFFC3

空间顺序无损

帧开始标记,Start of Frame,层次哈夫曼编码

SOF5

0xFFC5

差分离散余弦变换

SOF6

0xFFC6

差分层次离散余弦变换

SOF7

0xFFC7

差分空间无损

帧开始标记,Start of Frame,非层次算术编码

JPEG

0xFFC8

JPEG扩展保留

SOF9

0xFFC9

扩展顺序离散余弦变换

SOF10

0xFFCA

递进离散余弦变换

SOF11

0xFFCB

空间顺序无损

帧开始标记,Start of Frame,层次算术编码

SOF13

0xFFCD

差分离散余弦变换

SOF14

0xFFCE

差分层次离散余弦变换

SOF15

0xFFCF

差分空间无损

其他标记

DHT

0xFFC4

定义哈夫曼树表

DAC

0xFFCC

定义算术编码表

RST0

OxFFD0

差分编码累计复位,共8

……

……

RST7

OxFFD7

SOI

OxFFD8

图像开始

EOI

OxFFD9

图像结束

SOS

0xFFDA

开始扫描,图像数据开始

DQT

0xFFDB

定义量化表

DNL

0xFFDC

定义线数

DRI

0xFFDD

定义差分编码累计复位的间隔

DHP

0xFFDE

定义层次级数

EXP

0xFFDF

展开参考图像

APP0

0xFFE0

为应用程序保留,共15

……

……

APP15

0xFFEE

JPG0

0xFFF0

JPEG扩展保留,共14

……

……

JPG13

0xFFFD

COM

0xFFFE

注释

TEM

0xFF01

算术编码中作临时之用

RES

0xFF02

保留,共189

……

……

RES

0xFFBF

 

阅读(3668) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~