28 June 2013

我们或多或少都听说过三原色,就是红绿蓝三种颜色,相互重叠能够组合成各种其他颜色。那么假设我们要实现一幅图像上的各种颜色,就要传输这三种颜色,它们的重要性相同。但是,人类对于亮度的敏感程度远高于色度,实际中,我们使用YCbCr色度空间。

Y这里指亮度,Y = krR + kgG + kbB。而Cb、Cr是指色差。Cb = B - Y, Cr = R - Y, Cg = G - Y。这时你会发现,这里明明有四个变量(Y,Cb,Cr,Cg),比RGB三个变量还多了一个亮度么?其实kr + kg + kb = 1,我们主需要Y,Cb,Cr就能表示Cg,所以我们传输的还是三个变量,这里不具体推导公式了。

这里还需要讲到一个重要的概念——YCbCr采样格式。H.264支持如下三种采样格式:4:4:4, 4:2:2, 4:2:0。

4:2:0则是指水平和垂直都进行二次采样,则4个亮度点对应1个Cb和1个Cr。根据百度百科(YCbCr)的解释:

4:2:0并不意味着只有Y,Cb而没有Cr分量。它指得是对每行扫描线来说,只有一种色度分量以2:1的抽样率存储。相邻的扫描行存储不同的色度分量,也就是说,如果一行是4:2:0的话,下一行就是4:0:2,再下一行是4:2:0…以此类推。对每个色度分量来说,水平方向和竖直方向的抽样率都是2:1,所以可以说色度的抽样率是4:1。对非压缩的8比特量化的视频来说,每个由2x2个2行2列相邻的像素组成的宏像素需要占用6字节内存。

下面八个像素为:

(Y0 U0 V0) (Y1 U1 V1) (Y2 U2 V2) (Y3 U3 V3)
(Y5 U5 V5) (Y6 U6 V6) (Y7 U7 V7) (Y8 U8 V8)

存放的码流为:

Y0 U0 Y1 Y2 U2 Y3
Y5 V5 Y6 Y7 V7 Y8

映射出的像素点为:

(Y0 U0 V5) (Y1 U0 V5) (Y2 U2 V7) (Y3 U2 V7)
(Y5 U0 V5) (Y6 U0 V5) (Y7 U2 V7) (Y8 U2 V7)

由于映射出来的每个像素点,需要该像素点的一个色度分量Cb和该点下面的像素点的一个色度分量Cr,故CbCr采样点画在了两个像素点之间。


好了,我们费了半天劲,大概解释了一下YCbCr和它的采样格式。下面,我们来介绍一下宏块。在H.264中,宏块是图像帧中16×16的像素区域,是运动补偿的基本运算单位。下图是一个4:2:0采样格式下的宏块结构,它由一个包含256个亮度样本的16×16的宏块和64个蓝色度样本(4×4)和64个红色度样本(4×4)组成。

以后我们就直接拿这些宏块说事了。上文(网址)提到了我们要在参考帧中寻找当前宏块的最佳匹配宏块,这个过程叫做运动估计。一般以当前宏块为中心,在参考宏块中各个方向的去寻找最佳匹配宏块。那如何才算最佳呢,直观的认为是能量差最小,常用的匹配准则有均方误差(MSE)最小准则、绝对误差均值(MAD)最小准则。

其实这个参考帧的选取也多有讲究,可以是单向预测、双向预测或者重叠块运动补偿OBMC。单向、双向好理解,参考帧可以选一个方向(过去或将来)的或者两个方向的(过去和将来),后面那个乱七八糟的,我们暂且不管,技术细节以后一点点研究。我们看到这些预测过程都是当前帧与过去帧或者将来帧的比较,这里就引出了一个重要的概念——帧间预测。

预测完就需要运动补偿了。运动补偿就是当前块减去参考块得到残差块,把残差块和运动矢量一起传输过去。运动补偿的块大小越小,残差的能量越小。这好理解,越小越精确的匹配,自然差值就越小了,但是随着块的大小减小,搜索复杂度和运动矢量数目会增加。这就是两个矛盾的量,此消彼长,我们需要权衡各个指标来达到最优效果,鱼与熊掌不可兼得么。我们刚才看到了,宏块有亮度的有色度的,这些宏块都需要运动估计和运动补偿。

再介绍一种技术——半像素运动补偿技术。

顾名思义,我们现在整像素点找到最佳匹配位置,再在该位置周围半像素点寻找匹配更好的位置,我们可以继续在这个找到的半像素点位置附近的1/4像素点寻找最佳匹配位置。再继续可以在1/8的像素点寻找。这个和上面分块的道理一样,分的像素点越细各方面的开销就越大,有时,就算是到了1/4像素运动补偿,效果也不会很明显。



blog comments powered by Disqus