前几天占楼,现在到了周末终于有时间来更新一番。
为了回答楼主的问题,我们先从图像压缩说起。
一. 图像压缩肇始:JPEG
JPEG处理图片的关键步骤包括:
1. 将图片切割成8*8的block;
2. 对每一个block做DCT,得到transform之后的系数;
3. 对每个系数量化;
4. 量化后对每个block zigzag 扫描,得到最终的encoded bit stream。
由于步骤3对JPEG的DCT系数实行的量化,JPEG是有损压缩,同时也因为分块处理,缺乏全局多尺度的考虑,这导致了jpeg压缩后的图像,被暴力压缩时候,容易产生块效应。
二. 小波大法好
考虑到以上问题,人们尝试引入新的正交变换,并以此为基础推出JPEG2000压缩协议。
JPEG2000相对于JPEG主要不同是,JPEG2000使用了多尺度Wavelet Transform(小波变换)进行图像表达。所谓图像表达,就是把二维图像拉成一条以为的vector,再乘以由线性变换系数组成的矩阵,最终得到由图像表达系数(如DCT系数,小波系数)组成的vector。
像素到系数这个过程称为图像表达 (Image Representation),系数到像素过程称为图像重建(Image Reconstruction)。系数到像素过程可以认为是vector乘以逆矩阵之后回到像素空间vector,当系数数目=像素数目,且能完全重建图像时,称为critically sampled系数,这些系数在线性空间上不存在冗余性,是图像压缩的起点。
我们接着讲多尺度变换的好处:
1. 多尺度的有点像是用不同焦段的镜头看同一个景色。广角端可以看到big picture, 中焦看到类似人眼的透视效果,长焦端可以看到压缩透视效果的细节。同理,wavelet representation的低频信号可以看到图像的大概,频率越往高走,图像的细节越多。
多尺度的实现,是通过图像(像素空间)对不同的小波系数做二维卷积实现的。(通常低频小波系数卷积运算系数多,类比广角画面大;高频小波卷积运算系数少,类比长焦看到的画面小)
多尺度的好处是,把鸡蛋(像素)放在多个篮子(频率段/尺度)里面,量化编码的时候,对每个频率段而非整个频率段(如DCT系数)实施量化编码,这样低尺度系数(对应的卷积序列长度>8)量化细致的话,图像最终恢复重建的时候,块效应可以显著减轻。
2. 傅里叶分析的basis是三角函数(exp(1j*theta)),它的support是无限的。而自然图像的边缘常常是宽度有限的,大家知道,当傅里叶级数来逼近step function时候,会产生吉布斯效应:能量误差(L2 norm)asmyptotically收敛到0,但是看shape依旧有跳变,这就是为什么我们看微博文字类的照片时,经常在文字边缘能看到像素明暗的波动(振铃现象)。
小波的好处在于它的basis很灵活。Daubechies 小波系数在时域上是连续,短支撑,且长得像图像边缘。当一个信号用和它长得很像的basis来逼近时,自然图像表达效率很高,需要的系数也就很少很稀疏,我们管这个现象叫efficient。正是因为efficient representation,小波变换用了较少的系数个数(其他的很多都是0)实现了同样的重建效果。
以上两点好处,让JPEG2000实现了相对JPEG15%的进步:节省了15%的压缩空间。
三. DPCM大法好
做完了JPEG2000之后,人们发现,JPEG2000 并没有完全消除图像的空间冗余性。为什么这么说呢?小波变换虽然特别efficient,但是它的support毕竟是很短的,而空间上很长的线条首尾虽然跨度上千像素,我们在视觉上认为它们是一体的,结构近似,存在很多冗余。但是JPEG2000处理此类长边缘,对应的系数其实是独立编码,没有充分利用其冗余性的特点。
这个时候,随着互联网的发达,大家对于视频压缩的研究变得火热,大家都在想怎么来去除相关性,想来想去无非有两大源头。
1. inter-frame redundancy
视频内固定的风景,走动的人,前后帧关联巨大(时间冗余性)。
2. intra-frame redundancy
每一帧图像内的窗户,瓷砖,蓝天,白云的块之间关联性很大(空间冗余性)。
考虑消除1和2后节省bits的巨大好处,大家搞出来了H.264 (Advanced Video Coding)。 这里的1由于和这个问题无关,以后可以找时间细说。
处理2的过程是使用相邻block来predict我们要预测的block,这个过程和DPCM的道理是一回事。JPEG2000由于使用小波基不能实现motion compensation被弃用,这里依旧使用JPEG的DCT来压缩。比如我们要预测8*8 block之内的像素值的大小的话,我们可以利用它左上两个方向的最近边的边长(共17个像素值)来预测。
每次编码器都穷举各种mode来找出一种最优最省bits的编码的方法 ,记下这种模式的编号和残余误差,我们来对这个误差编好,这个过程会省出很多bits。
具体预测有很多种mode, H.264了里面大概包括有:
4 x 4 luma blocks -> 9 prediction modes.
8 x 8 luma blocks -> 9 prediction modes.
16 x 16 luma blocks -> 4 prediction modes.
四. 如何更科学地DPCM?
H.264 做好了之后,大家还嫌效果不好,怎么办?于是就做了H.265(Highly Efficient Video Coding简称HEVC)。HEVC就是BPG的算法基础。
BPG用的算法就是HEVC中对于intra-frame block的编码。HEVC 的intra-frame 编码相对AVC比起来聪明了不少。
1. 使用不同size的block来编码,而不是固定size的block。变化平缓的地方可以用32*32大小的block编码,变化剧烈的地方用4*4大小的block编码。这样可以有效减轻块效应。
2. mode扫描的方式提高到35种,等于对180°的角度量化成了35个bin,这样使得predection error明显变小。
基于以上两大原因,BPG超过了AVC的intra-frame编码。
而减少了帧内的相关性,AVC intra-frame 编码能力要强于JPEG2000,JPEG2000编码能力又强于JPEG。
五.总结:
压缩能力比较:
JPEG<JPEG200<AVC Intra-Frame<HEVC Intra-Frame(BPG)
压缩能力提升的主要原因:
1. JPEG->JPEG2000
多尺度分析降低块效应
小波系数更稀疏
2. JPEG2000->AVC Intra-Frame
降低空间结构冗余
3. AVC Intra-Frame->BPG
进一步降低空间结构冗余
现在回答题剩下的问题:
1. BPG会是终极的图像压缩方法吗?
毋庸置疑,BPG是先进的图像压缩协议。
但是BPG使用的DCT作为线性变换本身相对多尺度的线性变换在压缩能力上存在先天弱势。之所以BPG和HEVC仍旧使用DCT来做线性变换的原因是因为一般的多尺度变换做不到在像素空间的block化,从而实现不了高效的block by block的预测。如果想在系数空间内block化,小波系数本身不具有shift-invariant的特性。换言之,像素空间整体移动后,小波系数的形状存在差异,根本不可预测。除非我们实现了shift-invariant且能critically sampled的变换,要不然我们就很难做到block化,就得接着用DCT来做。
另外对于的mode的预测,BPG的在180度空间内平均分成30多个等分一个一个试的方法多少让人觉得这种方法是盲人摸象,相对于前人H.264的编码过程,没有根本上得改进。自然图像,诸如边缘的变化角度明显是连续变化的,如果能实现具有边缘角度预测能力的线性变换的话,那么对于周边block的预测就会更加准确,会节省更多的bits。
2. BPG会像JPEG一样被广泛使用吗?
未必。
不是牛逼的压缩协议就能被大量采用的,JPEG2000就是明显的例子,大家目前日常能看到JPEG2000的地方估计只有Photoshop的保存按钮,选择.jpeg2000。(其他可能用到JPEG2000的场合:军用雷达发回的图像,因为军用设备对带宽极其敏感,把带宽提高一个数量级,价格不知道翻了多少倍)。
JPEG2000没有被广泛用的原因是,JPEG2000没有比JPEG好太多(15%)且涉及到专利。
说到专利,这里说一个业界的常识,即便是某一个压缩协议源代码公布了,实际上不同公司的具体算法(尤其是硬件层面的算法)会不同,并且只会比公布的源代码效果更好。这里的原因是,标准委员会的里面的人很多都在例如微软,Google这样的大公司的有职务,他们有不愿告诉别人的更好的压缩想法,打算闷声发大财,但是标准又要公布,所以他们只会在标准里面写表现一般的细节(比如算法较慢,容错率一般)。这样的结果是,各大公司做的算法有好有差,算法差的公司很有可能拿好的公司的算法用,然后做产品卖,然后被发现,打官司要求禁用该算法在该公司产品的使用。连JPEG这么老的协议都有很多公司在为自己拥有这个专利而争执不休,BPG要打破大公司之间的壁垒,而被广泛使用,其实还存在诸多变数。
【注】:利益相关,本人目前在从事图像压缩领域的研究。