HEVC-熵编码

         HEVC 熵编码 需要理解和学习的内容? 学习的目的还是主要用于回顾,后续如果用到相关的知识,希望能够看到文章之后,能够迅速的了解

1、熵编码是什么?熵编码的目的?熵编码的通用流程?

2、熵编码的方法有哪些?

3、HEVC 中的熵编码的方法有哪些,具体的流程是怎样的?

一、熵编码是什么?熵编码的目的?熵编码的通用流程?

    了解熵编码,首先要了解熵是什么? 熵是衡量某个事件的信息量在编解码中就是码流的信息量。熵跟码流的概率成反比。 码流中某个符号出现的概率越大,那么对应的熵就越小。也就是说在这个符号传输之前我就已经很大概率知道会是传输这个了。所以出现这个符号给我的信息是少的,而如果传输的这个符号是我基本上不会去猜的,那这个符号传递的信息就很多的,对应的熵就很多了。

   熵编码的目的和视频编解码的目的是一致的,都是为了减少码流的数据量,使得能够减少数据传输的带宽。在之前的编解码框架体系中,比如帧内用的是空间上的冗余,帧间利用的是时间上的冗余来达到压缩的目的。 而熵编码是从码流整体的统计特性去考虑的。熵编码通过去除码流中的统计冗余达到对数据的压缩的。

    不同编码的流程不一样,但总的来说编码需要满足唯一可译性。对于使用者来说,只需要知道协议中具体用到的编码方法的流程即可。

二、 熵编码方法有哪些? 

2.1 变长编码(指数哥伦布编码)

        变长编码的特点:对信源输出的消息(一个信源符号或者固定数目的多个信源符号)采用不同长度的码字表示,这种编码方式称为变长编码。为了提高编码效率,需要根据符号出现的概率大小设计码长,即对于大概率符号采用较短的码字表示,小概率符号采用较长的码字表示,以达到平均码长最短的目的。

  • 指数哥伦布编码过程

    指数哥伦布码由前缀和后缀两部分构成,前缀和后缀都跟指数哥伦布码的阶数k有关。非负整数N的k阶指数哥伦布码可用如下步骤生成。

①将数字N以二进制形式写出,去掉最低的k个比特位,之后加1。

②计算①所得到二进制数的比特数,将比特数减一得到需要增加的前缀零的个数n。

然后在①得到的比特串加上n个0。

③将步骤①中去掉的最低k个比特位补回到②得到的比特串尾部就得到最后编码的数据了。

以4的一阶指数哥伦布编码为例:

①4的二进制表示为100, 去掉最低1个比特位0变成10,加1后得到11。

②11的比特数为2,因此前缀中0的个数为1。将0补到11前面 得到011。

③在比特串最低比特位补上步骤①中去掉的0,最终码字为0110。

  • 指数哥伦布解码过程

    解码原理:解析k阶指数哥伦布码时,首先从比特流的当前位置开始寻找第一个非零比特,并将找到的零比特个数记为m,第一个非零比特之后m+k位二进制比特串的十进制值为Value,计算解码值CodeNum。

                codeNum= 2的m+k次方- 2的k次方+ Value

比如0110,m = 1 ,m+k = 1+1 =2, value = 10的十进制为2,codeNum = 4 - 2 + 2 = 4.

2.2  算术编码

    算术编码的原理:算术编码的基本原理是:根据信源可能发生的不同符号序列的概率,把[0,1)区间划分为互不重叠的子区间,子区间的宽度是各符号序列的概率,这样信源发出的不同符号序列将与各子区间一一对应。因此每个子区间内的任意实数都可以用来表示的符号序列,这个数就是该符号序列所对应的码字。    与变长编码不同,算术编码是一种基于递归划分的编解码方法。其本质是给整个输入序列分配一个码字,而不是给每个输入序列中的每个字符都分配码字,平均意义上可以为单个字符分配码长小于1的码字。因此,算术编码可以得到接近最优的编码结果。

  • 算术编码的编码流程

        用一个实例来解释算术编解码过程。假设信源共有A、B、C、D四种符号,且它们的概率分别为A(0.3),B(0.3),C(0.2),D(0.2)。根据它们的概率将[0,1]分成4个子区间,使A、B、C、D四种符号与4个子区间一一对应。图(a)为算术编码过程,若要编码的序列为ABB,第一个符号是A,所以新的子区间为[0,0.3];然后把[0,0.3]当成单位1再按A、B、C、D的概率将其分为4个不重叠的子区间,第二个符号是B,所以新的子区间为[0.09,0.18];重复上述过程,用最后一个间隔中的任意数来表示符号序列编码结果。此处输出选择0.0930为符号序列ABB的编码结果。

        

 

  • 算术编码的解码流程

        其解码过程如图(b)所示,首先,将[0,1]分成4个子区间,将编码结果0.0930与区间大小相比较,选择0.0930所在的区间输出与区间对应的符号。本例子中0.0930在[0,0.3]之间,所以输出第一个符号为A;将[0,0.3]作为新的区间并按概率分成4个子区间,用同样的方法依次判断后续符号,得到解码结果ABB。

 

三、HEVC 中的熵编码

3.1 0阶哥伦布编码

  • 0阶哥伦布编码

    在熵编码中,很多语法元素都采用指数哥伦布码的形式映射为二进制比特流。零阶指数哥伦布码由前缀和后缀串接而成,前缀长度Lpfx 和后缀长度Lsfx 满足Lpx-1=Lstx。

前缀: 具有一元码的形式,即0...001,其中零的个数M为M = [log2(CodeNum+1)], 其中,CodeNum为编码数值索引,对于无符号数V,其索引CodeNum等于V;对于有符号数V,索引CodeNum则为:CodeNum =2V-1, V> 0;-2V,     V≤0;根据待编码数值,可以选择无符号数的指数哥伦布编码ue(v)或是有符号数的指数哥伦布编码se(1)。

后缀:为INFO的十进制值的二进制表示形式:  INFO= CodeNum+1-2的M次方

  • 零阶指数哥伦布的解码

        先读取第一个1前面0的个数M,接着读取第一个1后面M个信息位,根据前面INFO的公式可得CodeNum的计算方式:CodeNum=1-2的M次方 + INFO-1。计算出码字CodeNum,最后根据编码方式ue(v)/ se(v) 中CodeNum 和 V 的关系 由CodeNum反推得到V。

  • 零阶指数哥伦布编码的参数

        零阶指数哥伦布编码方法被用于视频参数集(Video Parameter Set,VPS)、序列参数集( Sequence Parameter Set, SPS )、图像参数集( Picture ParameterSet,PPS)和片头信息等所涉及的大部分语法元素中。具体的语法元素以及它所采用的是无符号数的指数哥伦布编码ue(v)还是有符号数的指数哥伦布编码se(v)。

3.2 cabac 编码

    cabac编码的码流是二进制的,所以cabac的第一个流程就是将非二进制的码流进行二进制化。cabac 是属于算术编码的范畴,也就意味着基本上遵守着算术编码的流程,从上面的算术编码的流程来看,决定某个码流比特在哪个区间的是该码流的概率,所以需要先得到将要编码的这个数据的概率。 但是码流是源源不断的生成,所以在码流没有结束的时候是不可能知道概率。 这个就需要用到上下文建模,通过上下文建模来估计待编码位的概率。

    上下文建模估算概率用的理论是 生成码流的语法元素并不是独立,相互具有相关性,通过这个上下文的相关性能够比较正确的估算出来待编码位的概率。这样估算出来的概率通过编码后能够提高编码性能。

    总的来说就是上下文建模及概率估计更新  这个过程就是进行概率状态索引σ的更新,概率状态索引σ在后续的 编码过程中决定了编码的区间。而编码过程就是根据代编码bin的值来确定编码区间。编码结束后,编码区间的值就是最后编码生成的值。

  • 二进制化

 (1)截断莱斯二进制化。
       截断莱斯由两个参数进行控制分别位门限值cMax、莱斯参数R。跟哥伦布编码类似,截断莱斯也是由前缀和后缀串接而成。

假设要编码的数据为V,截断莱斯的两个参数为位门限值cMax、莱斯参数R。

前缀码:

设P=V>> R,

若P小于值(cMax>> R),则前缀码由P个1和一个0组成,长度为P+1。

若P大于等于值(cMax>> R),则前缀码由(cMax>> R)个1组成,长度为(cMax>> R)。

后缀码:

V小于cMax时,其后缀值S为S=V-(P<< R)后缀码为S的二元化串,长度为R。

V大于等于cMax时,无后缀码。

(2)定长二进制化。

假设某一给定语法元素的值为x, 且0≤x≤Max,则直接利用十进制数转

换为二进制数法则来得到x的定长二值符号串,其长度l2 =[log2 Max]

  • 上下文模型

    上下文模型实际上有两个作用,一个是在编码下一个数据前,输出概率状态索引σ到二进制算法编码中 控制编码的区间。二是当当前数据到底并且编码完成的时候更新概率状态索引σ。

     1、初始化其上下文概率模型

        首先在编码第-一个 二进制符号前要初始化其上下文概率模型。从前面可以知道上下文模型的一个特点就是当前的编码跟之前的编码有关联。所以初始化的时候要设定一个初始的编码值,在HEVC中就是最大概率符号MPS,其表示待编码的Bin很有可能出现的符号,取值为1或0。与之对应的,待编码的Bin 不可能出现的符号即为最小概率符号LPS。

初始化流程:
为每一个上下文模型索引分配了一个初始值V,通过V来计算上下文模型的初始变量MPS和σ。计算方法如下:

其中a、b、c、d和e为中间变量,QPy 为片层亮度量化参数。

2、概率模型更新

       概率模型更新实际上是根据当前编码的二进制通过查表来更新概率状态索引σ。 表如下包括两个表,一个表是当前编码的二进制是最大概率符号MPS,一个是当前编码的二进制是最小概率符号LPS。

概率模型更新方法: 若编码的二元符号值等于MPS,则通过查表变量σ更新为

                  σ更新= transIdxMps(σ)

当编码的二元符号值等于LPS时,如果变量σ值为零,就互换MPS和LPS的值,而且更新变量σ。

否则不互换MPS和LPS,只更新变量σ,通过查表

                σ更新= transIdxLps(σ)

 

  • 二进制算法编码

    二进制算术编码实际也是算术编码,所以编码流程也就是码流不断的进来到编码模块,通过码流确定编码的编码区间的大小和区间的下界。首先是一个[0,510]的区间,然后来一个二进制,输出一个编码区间的size 和区间的下届,在来一个二进制,在前面输出的编码区间内,重新输出编码区间的size 和区间的下届,直到编码结束。

     常规编码模式:  编码器的输入值是上下文模型变量和待编码的Bin值,编码器的状态是当前编码区间大小R和区间下限L。根据给定的概率模型变量对当前区间进行细分。首先计算索引值p:

    ρ=(R>> 6)&3

通过查表得到LPS对应的子区间Rps:RLps=rangeTabLps[σ][p]。对当前MPS的子区间RMps:RMps=R- RLps。

如果当前二进制符号Bin等于MPS,则MPS的编码区间RMps作为下一个二元符号的编码区间R,区间下限L不变;

如果当前二进制符号Bin等于LPS,则LPS的区间RLps作为下一个二元符号的编码区间R,区间下限L要增加RMps的长度。随后根据当前Bin值更新上下文模型。

        旁路编码模式:无须对概率进行自适应更新,而是采用0和1概率各占1/2的固定概率进行编码,因此该编码较为简单。为了使区间划分操作更加简便,不采用直接对区间长度二等分的方法,而采用保存编码区间长度不变,使区间下限L值加倍的方法来实现区间划分,效果是一样的。

 

四、总结

    HEVC中熵编码是去除编码数据的统计冗余来达到编码压缩的目的。这里面利用很多信息论的理论,这些理论都是通过数学公式证明的,对于实际使用者而言,不用深入到具体的公式里头,只需要对使用的方法和具体的步骤了解即可。

   HEVC中使用了指数哥伦布编码以及上下文自适应编码这两种技术对编码参数,残差数据进行熵编码,其中指数哥伦布编码流程简单,通过对编码数据计算前缀值和后缀值即可。

   而上下文自适应二进制编码 流程比较复杂,首先要将非二进制的数据进行二进制化,然后根据一些先验的信息去初始化上下文模型,所谓的上下文模型是体现编码数据的统计信息的,实际就是一个根据编码数据更新编码概率的流程。上下文模型在编码前输出概率状态索引到二进制编码模块。最后进行二进制编码,二进制编码是根据编码数据 和 上下文模型输出的概率状态索引 确定编码区间大小和编码下届的过程。编码完当前的数据后,还需要对上下文模型进行更新,也就是更新概率状态索引。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章