jpeg编码学习笔记

各种图片格式目的是在网络传输和存储的时候使用更少的字节,即起到压缩的作用。在图片格式解码后,无论图片的格式,图片数据都是像素数组。
本文将尝试通过JPEG这种图片编码格式的学习,了解图片编码的秘密。


JPEG简介

一张100X100大小的普通图片,如果未经压缩,大概在100*100*4*8bits=0.3MB左右,这也是图片在内存中占用的内存大小。
通常JPEG文件相对于原始图像,能够得到1/8的压缩比,如此高的压缩率是如何做到的呢?

JPEG能够获得如此高的压缩比是因为使用了有损压缩技术,所谓有损压缩,就是把原始数据中不重要的部分去掉,以便可以用更小的体积保存。

JPEG编码是基于两个idea,第一个是基于相邻的像素信息是相近的,即空间冗余性,尽量少记录重复的数据来达到压缩的效果。第二个是基于图像信号的频谱特性,图像包含各种频率,大部分为低频频谱,少部分为高频频谱。可以保留包含图像信息较多的低频频谱,舍去包含图像信息较少的高频频谱。而达到图片质量没有可察觉的损伤,又能达到压缩的效果。这也说明了JPEG是有损编码。

JPEG的编码过程

编码流程如下图:

1.色彩空间转换

将RGB色彩空间转换到其他色彩空间,比如YUV色彩空间。
出现YUV,主要有两个原因,一个是为了让彩色信号兼容黑白电视机,另外一个原因是为了减少传输的带宽。
下图为老电视后面的色差接口。

YUV中,Y表示亮度,U和V表示色度,总之它是将RGB信号进行了一种处理,根据人对亮度更敏感些,增加亮度的信号,减少颜色的信号,以这样“欺骗”人的眼睛的手段来节省空间。YUV的格式也很多,不过常见的就是422和420格式。

下图为420格式,每四个Y共用一组UV分量,每个YUV分量和RGB一样都用8位来表示,YUV色彩空间就比RGB色彩空间所需的存储空间少一半,数据就被压缩到了一半。

2.离散余弦变换DCT

简单地说,DCT是傅里叶变换的一种,变换后会得到一个系数。
有关DCT的详细介绍可以看这个视频。

在JPEG压缩过程中,经过颜色空间的转换,每一个色值表示成8X8的图像块,下图为一个色彩域取样块,转化为频率域的DCT系数块:

图片经过此步骤会输出一个频率系数矩阵,左上的系数幅度值最大,越往右下,系数的幅度值越小,频率越高。大部分图片信息都在频率域矩阵左上区域,右下几乎不含有图片信息,甚至只含杂波。
注意:转换后的DCT系数块矩阵(x,y)处的值并不和转换前的颜色空间矩阵(x,y)处的像素值直接对应。

这一步骤没有压缩作用,它目的是为下一步骤找低频和高频区域,也就是找出留下的区域和舍去的区域。

3.量化

此步是将上步求得的DCT系数的简化的过程,利用人眼对高频部分不敏感的特性来舍去高频部分。
这里有两张表分别对亮度和色度做量化处理。

标准亮度量化表:

标准色度量化表:

量化表是控制 JPEG 压缩比的关键。
DCT系数矩阵中的不同位置的值代表了图像数据中不同频率的分量,这两张表中的数据是根据人眼对不同频率的敏感程度的差别所积累下的经验制定的。这个步骤除掉了一些高频量, 损失了很多细节。
但事实上人眼对高空间频率远没有低频敏感.所以处理后的视觉损失很小。
另一个重要原因是所有的图片的点与点之间会有一个色彩过渡的过程。大量的图象信息被包含在低空间频率中。 经过量化处理后, 在高空间频率段, 将出现大量连续的零。

把上面的DCT系数块通过量化后的结果如下图,其中第一个数-26是直流DC部分,它是一块图象样本的平均值,包含了原始8x8图像块中的很多能量,其余的是交流AC部分。
计算方法为:频率系数矩阵的数值除以对应量化表位置上的数值,并四舍五入到最近的整数。

解码的时候,反量化步骤会乘回量化表相应值,但是四舍五入导致低频有所损失,高频0字段被舍弃。此步为有损运算,会导致图像质量变低。所以说JPEG是有损编码。

4.zig-zag游程编码

量化后的数据还可以进行简化,更大程度的去压缩。

根据上面的zig-zag表重排数据的过程:

根据ZigZag表的规则对量化后的数据进行重排后的结果中可以看到出现连续的多个0,这样有利于进行游程编码。

5.范式Huffman编码

基本原理

huffman编码的基本原理是根据数据中元素的使用频率,调整元素的编码长度,以得到更高的压缩比。
举个例子,比如下面这段数据

AABCBABBCDBBDDBAABDBBDABBBBDDEDBD

这段数据里面包含了33个字符,每种字符出现的次数统计如下

字符 A B C D E
次数 6 15 2 9 1

如果我们用我们常见的定长编码,因为有5个文字,可以用3个bit表示,那么这段文字共需要3*33 = 99个bit来保存

字符 A B C D E
编码 001 010 011 100 101

如果根据字符出现的概率,使用如下的编码

字符 A B C D E
编码 100 0 1110 10 1111

那么这段文字共需要3x6 + 1x15 + 4x2 + 2x9 + 4x1 = 63bit,压缩比为63%。 是较短的编码不能够是较长编码的前缀,比如上面这个编码,就是由下面的这颗二叉树生成的。
哈弗曼编码一般都是使用二叉树来生成的,频率会高的数据对应的树节点的位置越高。这样得到的编码符合前缀规则,也就是较短的编码不能够是较长编码的前缀。

Huffman编码在JPEG中

假设在JPEG量化处理后的数据为:
35,7,0,0,0,-6,-2,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,…,0

根据RLE编码(游程编码)规则
1、用固定的4位来存储重复的数量,所以最多重复内容可以记录数量为15,超过15次要进行分段处理;
2、只将0作为重复的内容,每个数值记录前面有多少重复的0,末尾如果都是0用EOB作为代表;
3、此步不包含第一个数值,第一个数为直流系数,此步只处理交流系数。
得到处理结果:

为了提高储存效率, JPEG 里并不直接保存数值, 而是将数值按位数分成 16 组,JPEG提供了一张标准的码表用于对这些数字编码

举例来说,第3个单元中的“-6”这个数字,在表中的位置是长度为3的那组,所对应的bit码是“001”,由于这种编码附带长度信息,所以我们的数据变成了如下的格式。

对于括号前面的数字的编码,分成DC编码和AC编码。
下表是针对直流(DC)部分即第一个数字的哈弗曼表,由于直流部分没有前置的0,所以取值范围在0~15之间。

对于其余的交流(AC)部分,取值范围在0~255,哈夫曼表如下:

完整个编码过程如下表,最终的数据使用10个字节保存了原本长度为64字节的数据,JPEG的压缩算法完成。

参考

  • http://blog.mrriddler.com/2016/07/20/%E5%9B%BE%E7%89%87%E4%B9%8B%E6%97%85/
  • http://thecodeway.com/blog/?p=69
  • http://www.impulseadventure.com/photo/jpeg-huffman-coding.html
  • 《数字图像处理编程入门》
  • http://www.ibm.com/developerworks/cn/linux/l-cn-jpeg/index.html

jpeg编码学习笔记相关推荐

  1. 硬编码学习笔记(二)—— 经典变长指令

    硬编码学习笔记(二)-- 经典变长指令 前言 指令结构 符号说明 寻址符号 操作数符号 上标符号 One-Byte Opcode Map 变长指令 ModR/M 例:0x88 例:0x89 例:0x8 ...

  2. 硬编码学习笔记(一)—— 经典定长指令

    硬编码学习笔记(一)-- 经典定长指令 前言 指令结构 符号说明 寻址符号 操作数符号 上标符号 One-Byte Opcode Map 经典定长指令:修改寄存器 0x40~0x47 0x48~0x4 ...

  3. JPEG压缩学习笔记

    JPEG压缩学习及其C语言实现笔记 JPEG压缩流程 1.颜色转换(RGB->YUV) 2.DCT变换 (分块8*8进行DCT变换) 3.量化(-996, 19, 0, 2,0, 0, 0, 0 ...

  4. 零基础HTML编码学习笔记

    任务目的 了解HTML的定义.概念.发展简史 掌握常用HTML标签的含义.用法 能够基于设计稿来合理规划HTML文档结构 理解语义化,合理地使用HTML标签来构建页面 任务描述:完成一个HTML页面代 ...

  5. l2范数求导_稀疏编码学习笔记(二)L2范数

    L2范数 除了L1范数,还有一种更受宠幸的规则化范数是L2范数: ||W||2.它也不逊于L1范数,它有两个美称,在回归里面,有人把有它的回归叫"岭回归"(Ridge Regres ...

  6. 编码学习笔记,变量,类的命名规则

    命名规则: 1.直观可读,望文生义,最好用英文单词组合,切忌汉语拼音 2.标识符:形容词+名词,"min_length && max_num" 3.命名与所用的操作 ...

  7. gstreamer学习笔记---编码videoencoder

      既上一节的<gstreamer学习笔记-v4l2src>之后,我们这一次,学习gstreamer的编码流程.稍微了解gstreamer的小伙伴都知道,gstreamer具备强大的音视频 ...

  8. haxe php,Haxe学习笔记(一) Haxe:一次编码全平台编译的神话

    Haxe学习笔记(一) Haxe:一次编码全平台编译的神话 一 Haxe是什么? Haxe是开源的,它作为一门语言,基础语法和ActionScript3基本一致.所以任何做过Flash开发的人都可以很 ...

  9. 学习笔记(一)(x264编码流程)

    学习笔记(一)(x264编码流程) 作者 张士辉 11月 2, 2007 <script type=text/javascript></script> <script s ...

最新文章

  1. 在redhat6.4下安装 Oracle® Database 11g Release 2
  2. 12月18日云栖精选夜读 | Java 中创建对象的 5 种方式!...
  3. PHP编译安装时常见错误解决办法,php编译常见错误
  4. 试图执行系统不支持的操作
  5. mysql命令巧记_MYSQL常用命令大全(三)【值得收藏】
  6. 面试必会系列 - 3.1 Redis知识点大汇总(数据类型,内存模型,持久化,缓存击穿,集群,一致性哈希等等)
  7. linux 统计 程序运行时间
  8. 天勤2022数据结构(一)线性表
  9. 使用PyTorch实现CNN
  10. IntelliJ IDEA 破解
  11. GitHub上README.md文件的图片大小尺寸
  12. Unity3D移动平台简单实现
  13. 新动态视频壁纸微信小程序源码_支持多种分类短视频-也有静态壁纸
  14. 系分 - 案例分析 - 需求分析
  15. 关于mysql数据库回表的粗浅理解
  16. 青藤《关键信息基础设施增强保护安全实践》论文入选中国科技核心期刊
  17. Fatal error: Uncaught Error: Call to undefined function mysql_connect() in C:\tniuwamp\Apache24\htdo
  18. laradock 安装swoole
  19. 百度云盘BT服务器,百度网盘磁链、BT离线停用,官方称服务器优化,非永久下线...
  20. 我的世界java版地图结构_我的世界地图种子竟然有42亿个 那些神奇的建筑都是怎么生成的...

热门文章

  1. 吴恩达机器学习(十二)—— 机器学习系统的设计
  2. 封装一个简单showToast组件 / 自定义toast组件
  3. Google推出移动搜索 80亿网页、8亿图片尽在掌中
  4. [Excel知识技能] 将数值格式数字转换为文本格式
  5. 【编译原理】语言认知之Java、Python、C++快速排序三者运行效率与开发效率比较
  6. 编译flink1.9.0 报flink-fs-hadoop-shaded找不到
  7. ubuntu 16.04 桌面版 双击自动删除文字 解决方案
  8. stm32cube 和 RTX v5一起用的方法
  9. Unicode码和ASCII码及其转换
  10. 浅谈大型互联网的企业入/侵及防护策略