JPEG 压缩编码笔记

 一大清早醒来,百无聊赖间想到下学期好像是要学图像压缩的说,然后就联系到了JPEG编码,既然想到了就翻开了床头的数据通信原理,翻到编码论部分,貌似以前看这本书的时候都整整把这章给跳掉了,很是枯燥的。记得这章在图书馆翻这本书3e的时候大致浏览了遍,留有少许记忆的,不妨重新整理下做个笔记。

一、JPEG算法概要
JPEG(Joint Photographic Experts Group)是一个由ISO和IEC两个组织机构联合组成的一个专家组,负责制定静态的数字图像数据压缩编码标准,这个专家组开发的算法称为JPEG算法,并且成为国际上通用的标准,因此又称为JPEG标准。JPEG是一个适用范围很广的静态图像数据压缩标准,既可用于灰度图像又可用于彩色图像。
JPEG专家组开发了两种基本的压缩算法,一种是采用以离散余弦变换(Discrete Cosine Transform,DCT)为基础的有损压缩算法,另一种是采用以预测技术为基础的无损压缩算法。使用有损压缩算法时,在压缩比为25:1的情况下,压缩后还原得到的图像与原始图像相比较,非图像专家难于找出它们之间的区别,因此得到了广泛的应用。例如,在VCD和DVD-Video电视图像压缩技术中,就使用JPEG的有损压缩算法来取消空间方向上的冗余数据。为了在保证图像质量的前提下进一步提高压缩比,近年来JPEG专家组正在制定 JPEG2000标准,这个标准中将采用小波变换(Wavelet)算法。
JPEG压缩是有损压缩,它利用了人的视角系统的特性,使用量化和无损压缩编码相结合来去掉视角的冗余信息和数据本身的冗余信息。JPEG算法框图如图:

压缩编码大致分成三个步骤:
1、使用正向离散余弦变换(Forward Discrete Cosine Transform,FDCT)把空间域表示的图变换成频率域表示的图。
2、使用加权函数对DCT系数进行量化,这个加权函数对于人的视觉系统是最佳的。
3、使用霍夫曼可变字长编码器对量化系数进行编码。

译码或者叫做解压缩的过程与压缩编码过程正好相反。

JPEG 算法与彩色空间无关,因此“RGB到YUV变换”和“YUV到RGB变换”不包含在JPEG算法中。JPEG算法处理的彩色图像是单独的彩色分量图像,因此它可以压缩来自不同彩色空间的数据,如RGB, YCbCr和CMYK。

二、JPEG算法的主要计算步骤
JPEG压缩编码算法的主要计算步骤如下:
(1)正向离散余弦变换(FDCT)。
(2)量化(Quantization)。
(3)Z字形编码(Zigzag Scan)。
(4)使用差分脉冲编码调制(Differential Pulse Code Modulation,DPCM)对直流系数(DC)进行编码。
(5)使用行程长度编码(Run-Length Encoding,RLE)对交流系数(AC)进行编码。
(6)熵编码(Entropy Eoding)。

1、正向离散余弦变换
下面对正向离散余弦变换(FDCT)变换作几点说明。
(1)对每个单独的彩色图像分量,把整个分量图像分成若干个8×8的图像块,如图所示,并作为两维离散余弦变换DCT的输入。通过DCT变换,把能量集中在少数几个系数上。
 

(2)DCT变换使用下式计算:

它的逆变换使用下式计算:

上面两式中,
C(u),C(v) = (2)-1/2,当u, v = 0;
C(u),C(v) = 1,其他。
f(i, j)经DCT变换之后,F(0,0)是直流系数,其他为交流系数。

  (3)在计算两维的DCT变换时,可使用下面的计算式把两维的DCT变换变成一维的DCT变换:


2、量化
量化是对经过FDCT变换后的频率系数进行量化。量化的目的是减小非“0”系数的幅度以及增加“0”值系数的数目。量化是图像质量下降的最主要原因。
对于有损压缩算法,JPEG算法使用如下图所示的均匀量化器进行量化,量化步距是按照系数所在的位置和每种颜色分量的色调值来确定。因为人眼对亮度信号比对色差信号更敏感,因此使用了两种量化表:亮度量化值和色差量化值。此外,由于人眼对低频分量的图像比对高频分量的图像更敏感,因此图中的左上角的量化步距要比右下角的量化步距小。下面2个表中的数值对CCIR 601标准电视图像已经是最佳的。如果不使用这两种表,你也可以把自己的量化表替换它们。

亮度量化值表和色度量化值表

3、Z字形编排
量化后的系数要重新编排,目的是为了增加连续的“0”系数的个数,就是“0”的游程长度,方法是按照Z字形的式样编排,如下图所示。这样就把一个8×8的矩阵变成一个1×64的矢量,频率较低的系数放在矢量的顶部。

量化DCT系数序号

 

0

1

5

6

14

15

27

25

2

4

7

13

16

26

29

42

3

8

12

17

25

30

41

43

9

11

18

24

31

40

44

53

10

19

23

32

39

45

52

54

20

22

33

38

46

51

55

60

21

34

37

47

50

56

59

61

35

36

48

49

57

58

62

63

4、直流系数的编码
8×8 图像块经过DCT变换之后得到的DC直流系数有两个特点,一是系数的数值比较大,二是相邻8×8图像块的DC系数值变化不大。根据这个特点,JPEG算法使用了差分脉冲调制编码(DPCM)技术,对相邻图像块之间量化DC系数的差值(Delta)进行编码。
Delta=DC(0,0)k-DC(0,0)k-1

5、 交流系数的编码
量化AC系数的特点是1×64矢量中包含有许多“0”系数,并且许多“0”是连续的,因此使用非常简单和直观的游程长度编码(RLE)对它们进行编码。
JPEG使用了1个字节的高4位来表示连续“0”的个数,而使用它的低4位来表示编码下一个非“0”系数所需要的位数,跟在它后面的是量化AC系数的数值。

6、熵编码
使用熵编码还可以对DPCM编码后的直流DC系数和RLE编码后的交流AC系数作进一步的压缩。
在 JPEG有损压缩算法中,使用霍夫曼编码器来减少熵。使用霍夫曼编码器的理由是可以使用很简单的查表(Lookup Table)方法进行编码。压缩数据符号时,霍夫曼编码器对出现频度比较高的符号分配比较短的代码,而对出现频度较低的符号分配比较长的代码。这种可变长度的霍夫曼码表可以事先进行定义。

7、组成位数据流
JPEG编码的最后一个步骤是把各种标记代码和编码后的图像数据组成一帧一帧的数据,这样做的目的是为了便于传输、存储和译码器进行译码,这样的组织的数据通常称为JPEG位数据流(JPEG bitstream)。

 

MathWork上公开的JPEG编码器代码:下载

Simulink 命令集

仿真命令:
    sim       —
仿真运行一个simulink模块
    sldebug   —
调试一个simulink模块
    simset    —
设置仿真参数
    simget    —
获取仿真参数

线性化和整理命令:
    linmod    —
从连续时间系统中获取线性模型(状态方程)
    linmod2   —
也是获取线性模型,采用高级方法
    dinmod    —
从离散时间系统中获取线性模型
    trim      —
为一个仿真系统寻找稳定的状态参数

构建模型命令:
    open_system   —
打开已有的模型
    close_system  —
关闭打开的模型或模块
    new_system    —
创建一个新的空模型窗口
    load_system   —
加载已有的模型并使模型不可见
    save_system   —
保存一个打开的模型
    add_block     —
添加一个新的模块
    add_line      —
添加一条线(两个模块之间的连线)
    delete_block  —
删除一个模块
    delete_line   —
删除一根线
    find_system   —
查找一个模块
    hilite_system —
使一个模块醒目显示
    replace_block —
用一个新模块代替已有的模块
    set_param     —
为模型或模块设置参数
    get_param     —
获取模块或模型的参数
    add_param     —
为一个模型添加用户自定义的字符串参数
    delete_param  —
从一个模型中删除一个用户自定义的参数
    bdclose       —
关闭一个simulink窗口
    bdroot        —
根层次下的模块名字
    gcb           —
获取当前模块的名字
    gcbh          —
获取当前模块的句柄
    gcs           —
获取当前系统的名字
    getfullname   —
获取一个模块的完全路径名
    slupdate      —
1.x的模块升级为3.x的模块
    addterms      —
为未连接的端口添加terminators模块
    boolean       —
将数值数组转化为布尔值
    slhelp        –simulink
的用户向导或者模块帮助

封装命令:
    hasmask       —
检查已有模块是否封装
    hasmaskdlg    —
检查已有模块是否有封装的对话框
    hasmaskicon   —
检查已有模块是否有封装的图标
    iconedit      —
使用ginput函数来设计模块图标
    maskpopups    —
返回并改变封装模块的弹出菜单项
    movemask      —
重建内置封装模块为封装的子模块

诊断命令:
    sllastdiagnostic  —
上一次诊断信息
    sllasterror       —
上一次错误信息
    sllastwarning     —
上一次警告信息
    sldiagnostics     —
为一个模型获取模块的数目和编译状态

硬拷贝和打印命令:
    frameedit         —
编辑打印画面
    print             —
simulink系统打印成图片,或将图片保存为m文件
    printopt          —
打印机默认设置
    orient            —
设置纸张的方向

杂想

  昨天晚上开始整理搬校区是需要处理掉的书,继而是堆啊摊啊的,弄得2个桌子,发现自己的书还真的是多,装得是满满6袋,貌似2袋杂志的样子,不过很不舍得扔掉,也就等爸爸都带回来然后开始善后,该处理掉的总要处理掉,留下的再说了
  CET4弄的一点感觉也没有,算是完了,老天发慈悲的话让我过好了,不过的话也就是我自己的问题。中间还出了点岔子,手机莫名响起,关机的状态下也就闹钟会响,不过说实话我是没有关机的,一头冷汗,听力。。。
  很多时候总觉得自己一直都在逃避,逃避自己能够承担的责任。常常抱怨学院、班级的这个不好那个不行,然而旦有机会去改变时,总又是推脱其词。这是懦弱吗。。。不得而知,想想以前的自己似乎不是这样的,难道这就是成长。。。
  进入大学之前脑中的大学生活应该是无忧无虑,推开一切羁绊的。但使一进入就开始发现自己的生活和想象近乎是两码事,学业上的压力压得我喘喘窒息的样儿。连连的挂课重修,然后是重修挂课的,进而开始发现自己的学习方法根本上和大学的脱节。只要能收能伸就行,不过明摆着自己不是这样的人,开始强迫自己封闭在学校这个围城中。。。难道这就是我的大学生活。。。
  发现自己的人际关系真的处理得不怎么样,虽说大致可以把学院的人混个脸熟,不过能说上话的也就自己班里那几个人。然后开始感叹着制图彭龙老师可尽数报出学院所有人而且打成一片的架势,自叹不如的说。不过感觉还是维持现在的样子较好的,很多人真的不怎么想认识的。
  拌手细数将要离开新校区的时间,差不多也就50+的样子了,回首这差不多的2年的时间,有股漠然的感觉。应该不再是感叹时光飞逝,惋惜的时候了,从中得到些什么呢,总结会是有的。
  新的一个学年又要开始了,目标依旧是迷茫,或者说是遥远。不过我依旧会继续以远方为目标,总有一天,理想会触手可得。

一年后的回归,有点迷茫

  不知道这一年自己到底做了些什么,时常当掉的free空间,搞得兴趣全无,算算正好也是一年前在这里写了几片blog,然后转去了msn space,后面是自己的blog。发现自己的脑袋给越来越多乱七八糟的东西给杜塞,blog越弄越复杂,掩盖了真正的实质。
  离开这里的原因应该是有很多的算是,最重要的是感觉自己根本配不上这里的氛围。大家都是一心为dotNet事业奋斗的人,我这个小虾米算什么呢。经历了还多外面blog的各种富华,现在开始发现这里的纯洁和宁静。
  一年后的回归,一个新的开始,这个暑假,希望是个好的开始吧,希望,愿望,期盼

K.O.高频

  慌~~~从考完大物就开始干这苦人的高频,做卷子,看笔记,弄得人心惶惶的。然后是昨天早上一清早给轩轩死命的拖起来。。。才6:20啊~~~去侯那里答疑,本来是带着一堆题目去找她的,后来就是给她一堆的数落,说什么做这个没什么用的啦云云的,后面是复习笔记,发现好多东西漏了的,然后是一阵恶补,下午答疑,朱却是是那个好啊,认真解释加上大胆漏题的,佩服佩服。那个wing就是搞笑,硬是说自己是什么啊天才的说,哎~~~自叹不如啊。。。
  今天上午英语是那个easy enough的,三下五除二的解决,开始在床上等着高频的到来。
  考卷发下来就开始发现和做过的历届题是如此的啊~~~咋就不怎么一样那。。。苦命的我们啊,还好凭着电子实习+以前看得通信原理,解决掉了大部分的题目,做完了就开始估算着自己分数,应该及格是没什么问题的了。想想够了,满足了。然后是回来大家都在那个叫啊,被关了的。。。希望自己是幸运的哈

  流水帐完毕

  貌似暑假的竞赛培训的,我们班的好多小朋友给刷掉了的说,哀悼。开始为自己暑期生活开始盘算,应该是会有新本子了,刚看了轩轩的space说是下学期要努力的,不过感觉他是依旧那个哪,嘘小声点别告诉他哈。我依旧努力ing。。。

P.S.若发现有什么读不通的别怪我哦,是aaron在旁边打CS弄得我分神的哈

祝,一切顺利

  凝望着新世纪九幢和十幢间的一棵不知名的树发呆,看着它摇啊摆啊的,耳边动感101中午的天天点播完全给高考的祝愿淹没了,伴着我的未来不是梦,脑中不知是一片空洞还是似水流年的回忆。今年的黄梅天好像是在6月的中旬吧,应该不会提前到过两天高考的吧。
  为今年高考的妹妹祝福,考试一切顺利,当然身体也要当心,考入自己满意的大学吧,至少比我这个哥强多了吧,哈哈,努力。

大物砸了5555~~~复习高频。。。

  说实话真的是没什么心情好好复习大物的,这次大物一被挂是注定的了,靠着叶的选择和填空,不知道怎么样,貌似不错的样子,然后自己做的计算题算是一塌糊涂的,阿弥陀佛~~~老师放过我吧。。。我不奢望78了,60分就好。。。
  耳边伴着大家的讨论,而自己却只能闷着气。拖着疲惫的身体沉沉地倒在寝室那硬梆梆的床上,开始想这学期怎么办,下学期又如何,然后就睡死了
  刚刚醒过来,发现天气又是像前几天那样的晴朗,而如果在家的话可以足足的晒晒身上的霉气,学校不行。准备是要开始复习高频的,不过发现好多复习的东西zero-allen带走了,说是要礼拜天来再给我的。接到这条消息真的有点想摔手机的冲动,然后冲动是魔鬼的教导开始在脑袋中回响,呵呵。想想也好气,怎么办呢。Take things as they come。放平心态,既然没有整理好的东西看,那就书上实实足足从头到尾得好好整一下,加上还有的考卷,应该是可以打发掉这两天的时间了。
  昨天打电话回家和爸妈说了到17号再回家的,他们也只是叮嘱了些当心点身体什么的,感觉一切尽在不言中了。怀念家里的饭菜,家里的床,家里的shining,和家里的爸爸妈妈。不过现在为他们也不能做些什么,依旧是好好读书的份儿,将来也就看我的了。
  努力……要保持住绩点上升的趋势,从1.8到现在也不错,继续ing。。。