博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入剖析H.264的1/2像素(无代码,无真相,彻底弄清分数像素)
阅读量:4141 次
发布时间:2019-05-25

本文共 9649 字,大约阅读时间需要 32 分钟。

        H.264的亮度块预测时,支持分数像素,如1/2像素、1/4像素、1/8像素(1/8像素作用不是特别大,现逐渐在取消).开始学习时,对分数像素的理解颇为困难. 其实,分数像素并不是说像素的值是分数形式的,而是说像素的位置是通过插值得来的,认为它的位置在分数位置,体现在运动矢量上就是分数形式的运动矢量. 1/4像素和1/2像素的本质是相同的,为了简便起见,下面仅讨论1/2像素. (视频序列为foreman, 用JM8.6的baseline将其头三帧编码为IPP,分析工具为H.264visa, 插值代码是在VC++6.0中写的.)

 

      用H.264visa打开码流,选择第二帧(P帧)的一个宏块,该宏块信息为:

 

==== MB 30(8, 2) ====

    Location : (128, 32),
    Slice No. : 0
    Slice Type : P Slice
    MB Type : (4)P_8x8ref0
    NumMbPart : 4
    MbPartSize : (8, 8)
    Subblock Type:
       +-----------------+----------------+
       |    (0)P_L0_8x8  |    (3)P_L0_4x4 |
       +-----------------+----------------+
       |    (0)P_L0_8x8  |    (1)P_L0_8x4 |
       +-----------------+----------------+

****** Inter Info ******

Block(0, 0):

  (0,0) L0=MV(-2, 0),POC: 0,refIdx:0,DecNo: 1

Block(1, 0):

  (0,0) L0=MV(14,14),POC: 0,refIdx:0,DecNo: 1
  (1,0) L0=MV(-1, 1),POC: 0,refIdx:0,DecNo: 1
  (0,1) L0=MV(-1, 1),POC: 0,refIdx:0,DecNo: 1
  (1,1) L0=MV( 0, 1),POC: 0,refIdx:0,DecNo: 1

Block(0, 1):

  (0,0) L0=MV(-16, 1),POC: 0,refIdx:0,DecNo: 1

Block(1, 1):

  (0,0) L0=MV(-2, 1),POC: 0,refIdx:0,DecNo: 1
  (0,1) L0=MV(-15, 1),POC: 0,refIdx:0,DecNo: 1

 

       由  (0,0) L0=MV(-2, 0),POC: 0,refIdx:0,DecNo: 1可知:该小块的实际运动矢量为(-1/2, 0). 从H.264visa中得到该宏块的预测值为:

 

====================== Y Data ======================

+----------------+----------------+----------------+----------------+
|204,204,204,206,|206,205,204,201,|143,113,118,115,|115,129,176,206,|
|204,204,204,204,|203,201,207,214,|199,142,111,122,|130,115,130,172,|
|204,203,203,203,|200,200,204,199,|210,199,148,114,|118,125,112,120,|
|204,203,203,203,|199,199,201,192,|205,215,203,151,|118,118,120,107,|
+----------------+----------------+----------------+----------------+
|203,203,202,202,|204,205,194,174,|197,205,204,213,|157,117,114,124,|
|202,202,202,202,|202,203,203,202,|203,203,204,204,|203,160,123,117,|
|203,203,203,203,|203,204,204,208,|206,204,204,203,|212,206,166,124,|
|203,203,204,204,|204,204,204,202,|201,203,204,205,|204,216,209,171,|
+----------------+----------------+----------------+----------------+
|204,204,204,204,|204,205,204,204,|202,201,202,204,|205,206,207,219,|
|204,203,203,203,|204,205,206,206,|203,201,201,203,|204,204,206,205,|
|213,211,209,208,|208,207,206,206,|203,201,200,202,|203,203,205,206,|
|214,213,213,212,|211,209,209,209,|203,201,200,202,|203,204,204,206,|
+----------------+----------------+----------------+----------------+
|183,186,188,190,|197,199,204,210,|211,207,204,204,|203,201,201,201,|
|170,169,170,172,|183,185,189,192,|198,202,204,204,|204,202,201,200,|
|179,178,177,177,|180,181,185,187,|184,193,200,203,|204,203,202,200,|
|177,178,180,181,|182,183,185,186,|184,185,194,204,|203,203,202,200,|
+----------------+----------------+----------------+----------------+

 

        意料之中的是,在第一帧(I帧)的重建值中并不能找到上面那个8*8小块,因为,运动矢量是分数形式的,所以上面的预测值是通过对第一帧的重建值进行插值而得到的.  根据H.264中1/2像素的插值原理可知,当运动矢量为 (-1/2, 0)时,要插出8*8个像素值,需要8*13个像素(竖直方向分量为0,不用插值),详细解释如下:

        假设像素横排为:x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x 12 x13, 那么x1 x2 x3 x4 x5 x6可以插出y1, 即x1 x2 x3y1 x4 x5 x6, 同理x2 x3 x4 x5 x6 x7可以插出y2, 即x2 x3 x4y2 x5 x6 x7, 依次类推,x8 x9 x10 x11 x 12 x13可出插出y8,即x8 x9 x10y8 x11 x 12 x13.

       

        根据运动矢量(-1/2, 0),  选择对应的8*13个像素值来插值,这8 * 13个像素值为第一帧中对应的宏块和它左边的宏块的重建值,如下:

 

Frame: 1, MB Position: 8, 2

====================== Y Data ======================

+----------------+----------------+----------------+----------------+
|204,204,205,206,|206,205,203,183,|118,107,122,131,|113,152,193,210,|
|204,204,204,203,|202,203,212,208,|171,123,115,133,|121,119,151,191,|
|203,203,203,202,|199,202,203,202,|222,184,128,107,|126,118,114,144,|
|203,203,203,202,|198,201,198,189,|200,216,186,128,|115,123,115,103,|
+----------------+----------------+----------------+----------------+
|203,203,202,203,|205,201,184,176,|205,205,205,205,|143,112,115,123,|
|202,202,202,202,|202,203,202,202,|202,203,205,205,|195,146,117,118,|
|203,203,203,203,|203,204,205,209,|205,204,204,204,|214,198,151,119,|
|203,203,204,204,|204,204,203,201,|202,203,204,204,|204,217,203,153,|
+----------------+----------------+----------------+----------------+
|204,204,204,204,|205,203,202,202,|201,201,203,204,|205,208,212,214,|
|204,205,205,205,|205,205,203,203,|202,201,202,203,|204,205,207,208,|
|205,206,206,206,|206,206,203,203,|202,200,201,202,|203,204,206,206,|
|212,209,207,206,|206,208,204,203,|202,200,201,202,|203,204,205,205,|
+----------------+----------------+----------------+----------------+
|201,203,208,213,|213,208,204,204,|203,200,201,201,|203,204,204,205,|
|185,187,191,195,|201,205,203,203,|204,202,201,200,|201,203,205,205,|
|180,181,185,187,|184,192,203,203,|204,203,202,200,|201,203,205,205,|
|181,182,185,186,|184,183,190,203,|204,203,202,200,|201,203,205,205,|
+----------------+----------------+----------------+----------------+

       

Frame: 1, MB Position: 7, 2   (该宏块在MB Position: 8, 2 的左边)

====================== Y Data ======================

+----------------+----------------+----------------+----------------+
|233,233,232,232,|230,229,227,223,|218,212,208,206,|205,205,204,204,|
|233,233,232,232,|230,229,227,223,|219,215,209,206,|205,205,205,204,|
|233,233,232,232,|230,229,227,224,|221,217,210,205,|205,205,204,204,|
|233,233,232,232,|230,230,227,225,|223,220,212,206,|205,205,204,204,|
+----------------+----------------+----------------+----------------+
|233,233,232,232,|231,230,228,227,|224,220,211,202,|205,204,203,203,|
|233,233,232,232,|231,230,229,228,|227,221,210,202,|204,203,202,202,|
|232,232,231,231,|230,230,229,229,|229,226,215,207,|204,203,202,202,|
|232,231,230,230,|230,230,230,231,|230,228,220,212,|205,204,203,203,|
+----------------+----------------+----------------+----------------+
|232,232,231,231,|230,230,230,231,|231,229,223,215,|204,204,204,204,|
|233,233,232,232,|231,231,231,232,|232,230,223,220,|203,203,203,203,|
|235,234,233,233,|233,233,233,234,|233,231,225,218,|209,207,206,205,|
|206,205,204,204,|204,204,206,207,|217,225,225,221,|218,216,215,214,|
+----------------+----------------+----------------+----------------+
|159,160,165,170,|173,172,174,176,|178,180,184,186,|191,194,196,197,|
|145,150,155,159,|162,163,165,167,|166,166,167,167,|168,168,169,172,|
|128,131,136,140,|151,157,166,173,|176,177,177,178,|178,177,176,176,|
|113,115,120,122,|123,128,139,145,|175,175,176,176,|177,177,178,179,|
+----------------+----------------+----------------+----------------+

          

        所以,待插值的8*13的像素值为:

205,204,204,204,204,205,206,206,205,203,183,118,107,

205,205,204,204,204,204,203,202,203,212,208,171,123,
205,204,204,203,203,203,202,199,202,203,202,222,184,
205,204,204,203,203,203,202,198,201,198,189,200,216,
204,203,203,203,203,202,203,205,201,184,176,205,205,
203,202,202,202,202,202,202,202,203,202,202,202,203,
203,202,202,203,203,203,203,203,204,205,209,205,204,
204,203,203,203,203,204,204,204,204,203,201,202,203,

 

        根据H.264的1/2像素的插值原理可知,横向1/2插值的最终结果为:(以第一行为例)

205, 204, 204, y1, 204, y2 ,204, y3, 205, y4, 206, y5, 206, y6, 205, y7, 203, y8, 183, 118, 107

 

      具体插值的代码如下:

#include
using namespace std;// H.264中6抽头系数的1/2像素插值int tap6Interpolate(int a[], int start){ return int((a[start] - 5 * a[start + 1] + 20 * a[start + 2] + 20 * a[start + 3] - 5 * a[start + 4] + a[start + 5])/32.0 + 0.5);}int main(){ // 待插值的像素值 int ref[8][13] = { 205,204,204,204,204,205,206,206,205,203,183,118,107, 205,205,204,204,204,204,203,202,203,212,208,171,123, 205,204,204,203,203,203,202,199,202,203,202,222,184, 205,204,204,203,203,203,202,198,201,198,189,200,216, 204,203,203,203,203,202,203,205,201,184,176,205,205, 203,202,202,202,202,202,202,202,203,202,202,202,203, 203,202,202,203,203,203,203,203,204,205,209,205,204, 204,203,203,203,203,204,204,204,204,203,201,202,203 }; // 插值后的像素值(实际上就是预测矩阵) int predict[8][8]; int i, j; for(i = 0; i < 8; i++) { for(j = 0; j < 8; j++) { // 插值 predict[i][j] = tap6Interpolate(ref[i], j); } } for(i = 0; i < 8; i++) { for(j = 0; j < 8; j++) { // 输出矩阵 cout << predict[i][j] << "\t"; } cout << endl; } return 0;}

       结果为:

 

204     204     204     206     206     205     204     201

204     204     204     204     203     201     207     214
204     203     203     203     200     200     204     199
204     203     203     203     199     199     201     192
203     203     202     202     204     205     194     174
202     202     202     202     202     203     203     202
203     203     203     203     203     204     204     208
203     203     204     204     204     204     204     202

 

        回头再看第二帧对应宏块的预测值:

====================== Y Data ======================

+----------------+----------------+----------------+----------------+
|204,204,204,206,|206,205,204,201,|143,113,118,115,|115,129,176,206,|
|204,204,204,204,|203,201,207,214,|199,142,111,122,|130,115,130,172,|
|204,203,203,203,|200,200,204,199,|210,199,148,114,|118,125,112,120,|
|204,203,203,203,|199,199,201,192,|205,215,203,151,|118,118,120,107,|
+----------------+----------------+----------------+----------------+
|203,203,202,202,|204,205,194,174,|197,205,204,213,|157,117,114,124,|
|202,202,202,202,|202,203,203,202,|203,203,204,204,|203,160,123,117,|
|203,203,203,203,|203,204,204,208,|206,204,204,203,|212,206,166,124,|
|203,203,204,204,|204,204,204,202,|201,203,204,205,|204,216,209,171,|
+----------------+----------------+----------------+----------------+
|204,204,204,204,|204,205,204,204,|202,201,202,204,|205,206,207,219,|
|204,203,203,203,|204,205,206,206,|203,201,201,203,|204,204,206,205,|
|213,211,209,208,|208,207,206,206,|203,201,200,202,|203,203,205,206,|
|214,213,213,212,|211,209,209,209,|203,201,200,202,|203,204,204,206,|
+----------------+----------------+----------------+----------------+
|183,186,188,190,|197,199,204,210,|211,207,204,204,|203,201,201,201,|
|170,169,170,172,|183,185,189,192,|198,202,204,204,|204,202,201,200,|
|179,178,177,177,|180,181,185,187,|184,193,200,203,|204,203,202,200,|
|177,178,180,181,|182,183,185,186,|184,185,194,204,|203,203,202,200,|
+----------------+----------------+----------------+----------------+

 

         一切一目了然.

       

      

转载地址:http://ldzti.baihongyu.com/

你可能感兴趣的文章
88. Merge Sorted Array(easy)
查看>>
leetcode刷题191 位1的个数 Number of 1 Bits(简单) Python Java
查看>>
leetcode刷题198 打家劫舍 House Robber(简单) Python Java
查看>>
NG深度学习第一门课作业2 通过一个隐藏层的神经网络来做平面数据的分类
查看>>
leetcode刷题234 回文链表 Palindrome Linked List(简单) Python Java
查看>>
NG深度学习第二门课作业1-1 深度学习的实践
查看>>
Ubuntu下安装Qt
查看>>
Qt札记
查看>>
我的vimrc和gvimrc配置
查看>>
hdu 4280
查看>>
禁止使用类的copy构造函数和赋值操作符
查看>>
C++学习路线
查看>>
私有构造函数
查看>>
组队总结
查看>>
TitledBorder 设置JPanel边框
查看>>
DBCP——开源组件 的使用
查看>>
抓包工具
查看>>
海量数据相似度计算之simhash和海明距离
查看>>
DeepLearning tutorial(5)CNN卷积神经网络应用于人脸识别(详细流程+代码实现)
查看>>
DeepLearning tutorial(6)易用的深度学习框架Keras简介
查看>>