运动估计是在参考帧中为当前编码的宏块寻找最佳匹配快,找到最佳匹配块后,运动估计会输出是运动矢量。
运动估计的下一步是运动补偿(Motion Compensation),即从当前块中减去匹配块得到残差块。在整个编码过程中,运动估计耗时占了整个编码过程的60%-80%不等,因此,对运动估计的优化是实现视频实时应用的关键。
H264 中运动估计的过程分为两步:1. 整数像素精度的估计。2. 分数像素级精度的估计。其中整数像素级的运动估计包括两类算法:全搜索算法、快速搜索算法(DIA/HEX/UMH)。
几个运动估计中用到的缩写:
- MV: 运动矢量。被用来表示一个宏块基于该宏块中的另一个图像的位置。
- MVP:预测运动矢量。
- MVD:两个运动矢量的差值。
- SATD(Sum of Absolute Transformed Difference):即 hadamard 变换后再绝对值求和。
- SSD(Sum of Squared Difference) = SSE(Sum of Squared Error) 即差值的平方和。
- MAD(Mean Absolute Difference) = MAE(Mean Absolute Error) 即平均绝对差值。
- MSD(Mean Squared Difference) = MSE(Mean Squared Error) 即平均平方误差。
整数像素运动估计
钻石搜索算法(Diamond Search Algorithm)
钻石搜索算法有两种搜索模式: 大钻石搜索算法(LDSP)和小钻石搜索算法(SDSP)。大钻石搜索算法有 9 个搜索点,小钻石搜索算法有 5 个搜索点。
钻石搜索的步骤是:先使用 LDSP 进行搜索,直到最佳匹配点位于大菱形的中心位置;之后使用小菱形搜索,直至最佳匹配点位于小菱形的中心位置。
- LDSP:
- 从中心搜索位置开始,设置步长 S = 2
-
使用钻石搜索点图案搜索 8 个位置像素(X, Y), 以使( x + Y = S) 围绕位置 (0, 0) - 从搜索到的 9 个地点中选择,其中一个地点的费用最低
- 如果在搜索窗口的中心找到了最小重量,请转到 SDSP 步骤
- 如果在除中心以为的 8 个位置之一中找到最小重量,则将新的原点设置为此位置
- 重复 LDSP
- SDSP:
- 设置新的搜索原点
- 将新步长设置为 S = S / 2
- 重复搜索过程以找到重量最轻的位置
- 选择权重最小的位置作为运动矢量权重最小的运动矢量位置。
上图可以看出,LDSP 又可分为两种模式,LDSP(1) 中的两个菱形,有 4 个重合点;LDSP(2) 中的两个菱形,有 6 个重合点。不重复计算这些点,可以节省运算复杂度。
SDSP 中, 4 个菱形的角距离中心点距离相等,因此 SDSP(1) 和 SDSP(2) 可以看出是一种模式。两个临近的搜索菱形,有 2 个重合点,不重复计算这些点,同样可以节省运算复杂度。
x264 中只采用了钻石搜索里的小钻石搜索算法, 搜索半径为 1。 具体代码实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
注意:这段代码写的比较 trick,先把 bcost 左移四位,留出的最后四位,每一位都代表一个搜索点,初始化时,默认菱形中心点为最佳匹配点。若菱形周边点 cost 更小,就将该点作为中心点继续进行菱形搜索,直到最佳匹配点确为中心点,跳出循环。
这段代码的速度优化空间,正如上面分析的那样,可以避开两个相邻菱形的搜索重叠搜索点。
六边形搜索算法(Hexagon Search Algorithm)
所谓的六边形搜索算法,不止包括六边形搜索(搜索半径为 2),还有小菱形搜索和正方形搜索(搜索半径为 1)两种。
六边形搜索算法采用 1 个大模板(六边形模板)和 2 个小模板(小菱形模板和小正方形模板),具体步骤如下:
-
以搜索起点为中心,采用上图中左边的六边形模板进行搜索。计算区域中心及周围 6 个点处的匹配误差并比较,如最小 MBD 点位于模板中心点,则转至步骤 2;否则以上一次的 MBD 点作为中心点,以六边形模板为模板进行反复搜索。
-
以上一次的 MBD 点为中心点,采用小菱形模板搜索和小正方形模板搜索,计算各点的匹配误差,找到 MBD点, 即为最优匹配点。
从上图中的六边形搜索可以看出,两个临近的六边形,有三个重叠搜索点,因此,可以通过减少重复计算,来提升搜索性能。事实上,x264 中已经采用了这种优化方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
|
非对称交叉多层次六边形网格搜索算法(Uneven Multi-hexagon-grid Search Algorithm)
运动估计中,起始搜索点和提前终止技术非常重要。
UMH 算法是基于 MV 具有时空相关性,因此可以结合上一帧和上一步中 MV 的方向和角度,来修改多层六边形的形状。
UMH 算法包含四中搜索模式:不均匀交叉搜索、多六边形网格搜索、迭代六边形搜索、菱形搜索。主要流程步骤如下:
-
选取合适的搜索起点。有以下几种起点的选择。
① mvp: 由于还是整像素搜索,所以这里对 MVP 取整,得到的整数的 mv 后采用小菱形搜索以得到比较优秀的 mv。② 原点:即 mv 为0,即当前块的位置。 ③ 上层块 mv。④ 共同位置块 mv,取上一参考图像与当前块相同位置的块为 mv,然后取整。⑤ 共同位置参考 mv 通过参考图像距离计算后得到的 mv,然后取整。
-
小菱形搜索和中菱形搜索。
首先对中值 MV 和(0, 0)点进行小钻石搜索,计算出每个搜索点的 SAD 值,并找出新的 MBD 搜索点。如果新的 MBD 点的 SAD 值比门限1 的值(2000)还要大,就执行 Step4,否则继续。
对搜索点进行中钻石搜索,来找出新的 MBD 搜索点。若 SAD 值小于门限值2(500),停止搜索。否则继续。
-
对称交叉搜索和六边形搜索。
对上一步中找到的新的 MBD 搜索点,执行对称交叉搜索(半径为 7)和六边形搜索(半径为 2),计算这 20 个点的 SAD 值,并且找出本步最新的 MBD 点。
如果该步找到的 MBD 点与上一步中的 MBD 点吻合,停止搜索。否则继续。
-
非对称交叉搜索。执行非对称的交叉搜索,找到最新的 MBD 点。
-
5x5搜索和多六边形网格搜索。执行 5x5 全搜索和多六边形网格搜索。
-
迭代六边形搜索。设置上步中的 MBD 点作为搜索中心,执行迭代六边形搜索。
x264 中关于 UMH 算法的代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
|
UMH 优化思路(The Proposed Algorithm For UMH)
由于视频帧间具有时间相关性,大多数视频序列,当前宏块的方向与上一帧中相同位置宏块的方向高度相关。这意味着连续帧间,运动矢量有高度一致性。因此,当前宏块的运动方向可以通过之前帧对应坐标的方向来预测。基于运动方向预测,不同形状的搜索模式应用到 UMH 搜索模式。目标就是提升估计的运行时间,同时获得相同的质量。
方向可以通过运动矢量的角度来度量,可以使用如下公式:arcsin(-y / sqrt(x^2 + y^2)) * 180 / π 。
下面提出的算法使用上一帧中相同坐标块的运动矢量动态设置搜索非对称搜索模式的搜索长度,决定多六边形网格搜索的四分之一模式。同时,它根据上一步的方向来设计迭代六边形搜索模式。
Search Range Decision for Uneven Cross Pattern
在大多数视频序列中,水平方向上的运动要比垂直方向上的运动更加剧烈。正如上面提到的非对称交叉搜索中,水平方向上的长度是垂直方向上的长度的两倍。
在某些特殊的视频序列中,垂直方向上的运动比水平方向上的运动更加剧烈。因此我们可以动态的设置非对称交叉搜索模式的长度,来确保运动估计的质量。
基于连续帧的相关性,我们可以使用上一帧中相同坐标块的 MV(pmv)来预测当前块的的运动矢量,并且设置非对称交叉搜索模式的长度。如下:
1 2 3 4 5 6 |
|
Optimize for Multi-hexagon-grid Search
多六边形网格搜索包括两部分:5x5 搜索和多六边形网格搜索。
大多数真实世界的视频序列都有中心偏移运动矢量分布。有超过 80% 的运动矢量在 5x5 区域的预测内,而有 70% 的运动矢量在 3x3 区域的预测内。尽管 5x5 的区域,比 3x3 的区域有更高(10%)的预测概率,但是搜索点的数量是它的 3 倍之多。因此我们选择 3x3 搜索而不是 5x5 搜索。
x264 中已经对 5x5 全搜索做了优化,甚至比上面提到的优化,还要更加彻底,x264 中关于 5x5 的全搜索,仅检查 4 个搜索点。它的代码更新迭代过程如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
|
第二部分是多六边形网格搜索,它有 64 个点需要检查。在此步骤中,我们根据当前宏块的运动方向预测,设计了 4 种模式,它有 20 个搜索点需要检查,这回极大的降低计算复杂度。算法描述如下:
计算 pmv(x, y)的角度α:
a) 如果 α = 0-90,寻找 20 个搜索点,如图3(b),并找到新的 MBD,之后处理第 6 步
b) 如果 α = 90-180,寻找 20 个搜索点,如图3(c),并找到新的 MBD,之后处理第 6 步
c) 如果 α = 180-270,寻找 20 个搜索点,如图3(d),并找到新的 MBD,之后处理第 6 步
d) 如果 α = -90-0,寻找 20 个搜索点,如图3(e),并找到新的 MBD,之后处理第 6 步
x264 中并没有进行此项优化,此处可能有一个搜索优化空间。
Optimize for Iterative Hexagon Search
第六步是迭代六边形搜索模式,设置第五步中的 MBD 点作为搜索中心,最开始有 7 个点需要检查。然后在搜索过程中,六边形搜索不断前进,中心移动到六个端点中的任何一个。每次总是有三个新的点出现,而其他三个点是重复的。该算法根据前一步的方向设计新的六边形图案,避免了重复搜索冗余点。对第 6 步的优化过程如下:
步骤6-1:
图4(a) 所示的六边形位于步骤 5 的 MBD 点的中心。如果在本步骤中找到的 MBD 点仍然与在上一步中找到的 MBD 点一致,则转至步骤6-3;否则计算上一步方向的角度,进行下一步处理。
a) 如果 α = 0-90,如图4(b)所示,搜索四个点;并寻找新的 MBD 点并执行步骤 6-2。
b) 如果 α = 90-180,如图4(c)所示,搜索四个点;并寻找新的 MBD 点并执行步骤 6-2。
a) 如果 α = 180-270,如图4(d)所示,搜索四个点;并寻找新的 MBD 点并执行步骤 6-2。
a) 如果 α = -90-0,如图4(e)所示,搜索四个点;并寻找新的 MBD 点并执行步骤 6-2。
步骤6-2:
以上一步搜索的 MBD 点为中心,形成一个新的六边形。检查三个新的候选点,再次确定 MBD 点。如果 MBD 仍然与上一步中发现的 MBD 点重合,则转至步骤6-3;否则,如果 4 所示重复此步骤。
步骤6-3:
将搜索模式从六边形切换到小尺寸的六边形搜索。将检查基于角度评估的两个候选点。先的 MBD 点是运动矢量的最终解。
图 4(f) 显示了该方法的一个例子。
X264 中已经采用了此种优化方法,实现代码就是上一种的 X264_ME_HEX 代码。
分数像素运动估计
亚像素搜索算法
当整数像素搜索算法优化完毕后,亚像素搜索算法的时间占比就会提升,此时对亚像素搜索算法的优化,就不能忽视了。
1 2 3 4 5 |
|