H.264学习笔记3——帧间预测

2023-11-07

帧间预测主要包括运动估计(运动搜索方法、运动估计准则、亚像素插值和运动矢量估计)和运动补偿。

对于H.264,是对16x16的亮度块和8x8的色度块进行帧间预测编码。

A、树状结构分块

  H.264的宏块,对于16x16的亮度宏块,可以分成16x16、16x8、8x16和8x8的子块进行帧间预测。对于8x8的块(亚宏块,亮度和色度),往下又可以分成8x8、8x4、4x8、4x4的子块。在运动估计中,每一种分割都需要尝试,并计算出运动搜索结果的代价,选择最小代价的分割方式进行预测编码。

B、运动估计准则

  运动估计就是在搜索范围内寻找最佳估计块,使得预测块与当前块的残差数据尽量小,这样就保证编码的代价尽量小。对于MxN的像素快,s(x,y)表示当前像素值,z(x,y)表示备选预测像素值,x=1……M,y=1……N。则有下面的运动估计准则:

  1、SAD(sum of absolute difference):绝对误差。MAE:平均绝对差值

    SAD = sum(|s(x,y)-z(x,y)|)    MAE = (1/MN)*SAD

  2、SATD

  3、SSD(sum of squared difference):差值的平方和。MSE:平均平方误差

    SSD = sum((s(x,y)-z(x,y)^2))    MSE = (1/MN)*SSD

  可以选择上面的估计标准,计算出的值越小,说明编码代价越小。

C、运动搜索方法

  运动搜索就是在允许的搜索范围(一般是上下左右各一个子块大小)内查找最佳匹配块的过程,主要有全局搜索和快速搜索。

  1、全局搜索:最简单的将所有可能进行搜索比较,总是能找到搜索范围内的最佳匹配块,但是效率太低。

  2、快搜索算法:每种算法的过程各不相同,主要通过尽量避开不太可能是最佳匹配块的位置,从而提升搜索效率。过程就是:

    》1、确定搜索起始点;

    》2、判断该点有没有达到最佳匹配块的要求和能不能进一步继续搜索。

    》3、按照搜索规则,以起始点周围点为新的起始点进行递归搜索。

    常见的快速搜索算法有:三步法、二维对数法、交叉法、菱形法等,具体每种搜索方法可以参考书籍或者百度。

D、树状分级搜索和亚像素估计

  在运动估计时,为了提高估计精度,通常会采用1/2、1/4和1/8的像素精度进行估计,但是全部估计都这样操作会产生很大的性能开销,所以一般采用树状分级搜索。

  树状分级搜索就是在进行在进行运动估计时,先以整像素精度进行搜索,找到最佳匹配块之后,再在该位置周围进行1/2像素精度的搜索找到最佳匹配点。如果有需要的话,可以继续在1/2像素精度的最佳匹配点周围进行1/4像素精度的搜索,寻找最佳匹配点。

  在H.264中,对亮度和色度块的估计,分别支持1/4和1/8像素精度的运动估计。

  1、亮度的1/2和1/4像素插值:亮度亚像素差值如图一

                  

                            图一:亮度块的亚像素插值                        图二:色度块的亚像素插值

    如图:图中的灰色点是整数像素点,aa,bb,cc,dd,ee,ff,gg,hh和b,h,s,m,j是1/2像素,其他都是1/4像素。计算过程是先用(1,-5,20,20,-5,1)的六抽头滤波器进行1/2像素插值,然后再通过临近像素插值的方法计算1/4像素的插值。具体如下:

    水平半像素:如 b = ( E - 5F + 20G + 20H - 5I + J), b = Clip1((b+16) >> 5);Clip1的作用是限制结果在0~255,右移5相当于除以32,加16是为了结果的四舍五入。

    垂直半像素:如 h = (A - 5C + 20G + 20M - 5R + T), h = Clip1((h+16) >> 5);

    对角半像素:如 j = (cc - 5dd + 20h + 20m - 5ee + ff) = (aa - 5bb + 20b + 20q - 5gg + hh) ,j = Clip1((j+16) >> 5); 即:水平和垂直方向计算结果相同(可以自行展开计算验证)。

    水平1/4像素:如 a = (G + b +1) >> 1;  i = (h + j + 1) >> 1;

    垂直1/4像素:如 d = (G + h +1) >> 1;  f = (b + j + 1) >> 1;

      对角1/4像素:如 e = (h + b +1) >> 1;   g = (b + m + 1) >> 1;  p = ( h + s + 1) >>1;  r = (s + m + 1) >>1;

  2、色度的1/8像素插值:色度块是采用二次线型的1/8像素插值,如图二

    如图:就是利用待查亚像素G周围的整数像素(A、B、C、D)来加权计算G的像素值。整像素点距离G越近,其权值越大。计算如下:

    G = ( (8-dx)*(8-dy)*A + (dx)*(8-dy)*B + (8-dx)*(dy)*C + (dx)*(dy)*D + 32) >> 6;   其中dx、dy分别为G相对A的水平和垂直距离(以1/8像素为单位1距离),取值范围是1~7。

E、B帧的预测

  B帧是双向预测,分别参考List0和List1两个参考帧列表进行前向和后向预测,这里的前和后是针对播放顺序而不是编码顺序。H.264编码是以GOP分组处理,每个GOP的编码结构有III……、IPP……、IBB……P和分层B帧结构。其中第一种一般不使用,编码效率太低;第二种是属于H.264的基本档次。第三、四种属于主要档次和扩展档次。其中第三种(普通B帧)会产生较大的编码延时。

  B宏块预测有4种模式:直接模式(Direct)、双向模式(Bipred)、List0和List1。其中16x8和8x16大小的块只能使用Direct、List0和List1,其他子块大小可以使用所有的模式。

  双向预测:

    从List0和List1两个参考帧列表中选择最佳匹配块进行预测。过程如下:

    》在List0和List1中查找最佳匹配块,得到运动矢量MV(MV1,MV2)。

    》利用临近块的同方向MV,估计当前块的两个方向的MV预测值MVp(MVp1,MVp2,方法见后面:MV的编码)。PS:该步骤可以和上一步对换,即:先估计得到MVp1和MVp2,然后以MVp1和MVp2为起点进行搜索得到运动矢量MV1和MV2。

    》得到MV和MVp,就可以计算两个MVD(MVD1和MVD2),然后对MVD进行编码。

    》得到两个预测参考块和运动矢量后,就可以计算像素块的像素预测值。

      pred(i,j) = (P1 * pred_L0(i,j)  + P2 * (pred_L1(i,j))) / (P1 + P2);  //   其中P1和P2是两个方向的参考帧的权重。

  List0和List1模式:这两种模式和双向模式类似,只不过只进行一个方向的预测 。

  直接模式:直接模式应用于16x16、8x8以及8x8块中的所有子块。直接模式只编码预测残差,而不编码运动矢量(或MVD)和参考帧序列号,运动矢量和参考帧序列号在解码端通过计算前、后向MV,利用前后向MV得到像素预测值。

    有两种计算MV的方法:时间模式和空间模式。

    时间模式:基于假设“被预测的块在前后两个参考块间是均匀运动的”,所以场景切换和非均匀运动的块,预测效果不好。

      运动估计时,假设当前B块在List0和List1中参考帧分别为F0和F1,对应的最佳匹配块(预测块)分别为B0和B1。如果在之前对B1块进行帧间预测时,B0是B1的前向最佳匹配块,即:存在当前块在List0中的参考块B0相对于当前块在List中的参考块B1的运动矢量MV,那么就可以根据这个运动矢量和当前帧与F0、F1之间的帧间隔(记为d0,d1)算出前向和后向的运动矢量MV0和MV1。

      如:MV=(2.5,5),当前帧与F0和F1分别间隔2帧和1帧,即:d0=3,d1=2;于是MV0 = d0/(d0+d1) * MV = (1.5,3),MV1 = -d1 / (d0+d1) * MV =(-1,-2)。 

    空间模式:利用当前帧的相邻块的运动信息估计当前块的MV和参考帧序号,主要过程包括“参考帧选择”和“运动矢量选择”。

    》参考帧选择:利用当前块的邻近块A、B、C(位置见后面MV的编码)的参考帧中非负帧号最小的帧作为当前块的参考帧,这是为了选择离当前块最近的帧作为参考帧。如果有一个方向上A、B、C都没有参考帧,那么就采用单项帧间预测。如果A、B、C在两个方向都没有参考帧(即A、B、C都是帧内预测),那么当前块分别选择两个方向离当前帧最近的参考帧为当前块的参考帧。

    》运动矢量选择:若List1中第一帧(当前帧的播放顺序后一帧)对应位置块的运动适量MV1和MV2小于1/4像素(即:当前块到下一帧运动的比较少),且该帧为短期参考帧,且当前块的某个方向的参考帧帧号为0,则该方向的MV为0。如果不满足,则按照后面MV的编码中描述的方法计算两个方向(A、B、C的运动适量的中值,不是均值)的MVP作为当前块的MV

F、MV的编码 

  通过上面的树状分块结构,针对各种分块大小都进行一次帧间预测。每种分块的帧间预测,通过树状像素精度分级搜索,先按照整像素精度找到最佳匹配块,然后在进一步按照1/2、1/4像素精度寻找更加准确的最佳匹配块。寻找最佳匹配块主要是通过快速搜索算法,按照某种搜索准则判断最佳匹配块。上述操作完成后,找到各种分块结构代价最小的最佳匹配块,从而根据最佳匹配块和当前块的位置,得到运动矢量(MV)。通过运动矢量和运动残差(参考块和当前块的像素差值)就可以在解码端还原图像数据。但是如果之间编码MV会产生很大的码流代价(16x16MB分成多个子块产生多个MV、采用亚像素、MV包含row和col两个参数),因为实际操作中往往是根据周围的块,对MV进行预测得到MVp,然后编码运动矢量的实际值与预测值的差值MVD=MV-MVp。

  

  如上图:当前块(任意子块大小)的运动适量预测值有当前块的左、上、右上的块A、B、C(任意字块大小)进行预测。预测规则如下:

  》对于非16x8和8x16的子块,运动矢量的预测值MVp 为A、B、C的运动矢量的中值。MVp = mid(MVA, MVB, MVC)。

  》对于16x8的子块(即图中的E为上下两个16x8的子块),上面子块的MV预测值是块B的MVB,下面子块的MV预测值设计块A的MVA。

  》对于8x16的子块(即图中的E为左右两个16x8的子块),左边子块的MV预测值是块A的MVA,右边子块的MV预测值设计块C的MVC。

  》在进行上面的MV计算时,还要满足下面的限制条件:

    1、只有当当前块E的参考帧和临近块(A、B、C)的参考帧为同一帧,那么才可以使用MVA、MVB、和MVC进行预测;

    2、如果MVC不可用,则用当前块的左上边块的运动矢量MVD代替MVC;

    3、如果MVA、MVB和MVC中没有可用的,那么不进行运动矢量预测,直接编码当前块的运动矢量MV;

    4、如果MVA、MVB和MVC中只有一个可用的,那么MVP就是该可用的临近块运动矢量;

    5、如果MVA、MVB和MVC中有两个可用的,那么将另一个不可用的当作0,然后按照3个都可用的策略计算MVP。

  Skip模式:H.264中为了降低码率采用的特殊编码模式,是针对宏块(16x16)编码时,“既不传输运动矢量残差(MVD)、也不传输像素块残差”的编码方式。包括P_Skip和B_Skip。

  P_Skip:

    编码时:如果参考帧是List0中的第一帧,运动矢量和运动矢量的预测值相同(MVD为0),且残差系数通过变换量化后成为0或者通过某种策略(率失真优化等)舍弃。那么则只需要标记为P_Skip和传输运动矢量预测值MVP。解码时,就可以的MV=MVP,然后用预测像素值作为解码像素值。

   B_Skip:是B块直接编码的一种特殊形式。

    编码时:如果残差系数通过变化量化后成为0或者通过某种策略舍弃,那么则只需标记为B_Skip模式,也不需要传输MVP。解码时则按照B块的直接模式计算出参考帧号和相应的运动矢量,然后参考像素值作为当前像素的值。

    

转载于:https://www.cnblogs.com/DwyaneTalk/p/4021365.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

H.264学习笔记3——帧间预测 的相关文章

  • 静态测试方法

    本文讨论人工静态测试方法和自动静态测试方法 来帮你理解研发流程上是如何保证代码质量的 以及如何搭建自己的自动静态代码扫描方案 并且应用到项目的日常开发工作中去 人工静态方法 人工静态方法检查代码错误 主要有代码走查 结对编程 以及同行评审这
  • Docker在云平台上的最佳实践:基于容器技术的DevOps探索

    12月9日 在云栖计算之旅线下沙龙上 阿里云容器服务团队的高级研发工程师秦妤嘉分享了 基于容器技术的DevOps探索 首先介绍了DevOps和CD 接着分析了Docker如何打破传统CD壁垒 最后讲解了怎样从零开始搭建一个持续交付系统 视频
  • 软件测试笔记(九)- 兼容性测试

    了解如何针对不同的软件应用程序和操作系统交互的问题进行测试 一 兼容性测试综述 随着用户对来自各个厂商的各种类型程序之间共商数据能力和充分利用空间同时执行多个程序能力的要求 测试程序支架能否写作变得越来越重要 软件兼容性测试 softwar
  • 对java中的List进行深拷贝,并进行删除测试

    List
  • 【ssh】xshell的替代--WindTerm

    目录 WindTerm WindTerm 简介 如何关闭锁屏密码 3 功能 3 1 选中自动复制 右键粘贴复制的内容 3 2 打开软件自动连接 3 4 设置文件下载初始目录 4 可直接编辑bash命令行 5 界面管理 资源管理器 文件管理器
  • MCS-51 汇编指令集(J开头的指令)

    MCS 51系列单片机指令以J开头的指令有8条 分别为 JB bit rel JBC bit rel JC rel JMP A DPTR JNB bit rel JNC rel JNZ rel JZ rel 1 JB bit rel 指令名
  • Cobertura 统计多模块maven项目测试覆盖率

    Cobertura 统计单元测试覆盖率的机制 运行类 并在一个log文件中记录哪一行被执行 然后将源代码和log文件进行比对 1 简单的情况 单模块maven项目 项目结构 源代码 src main java se sigma calcul
  • 常用电子元器件简介

    一 电阻器 电阻器 一般情况下也称电阻 是一种阻碍电流在电路中流动的线性元件 也是组成电子电路的主要元件之一 1 电阻器的作用及电路图形符号 1 电阻器的作用 电阻器主要用于控制电路中的电压和电流 除了具有降压 分压 限流和分流作用外 还具
  • HTTPRunner学习笔记

    HttpRunner 是一款面向 HTTP S 协议的通用测试框架 只需编写维护一份 YAML JSON 脚本 即可实现自动化测试 性能测试 线上监控 持续集成等多种测试需求 在yaml文件中组织测试用例 在命令行执行 参考 HTTPRun
  • 软件测试人员必备的60个测试工具清单,果断收藏了!

    据统计 中国软件外包市场的潜力和机会已远远超过软件王国印度 不过由于软件人才的严重不足致使我国软件发展遭遇 瓶颈 国家为了大力培养软件人才 不断采取积极有效的措施 我国对软件测试人才的需求数量还将持续增加 因此软件测试工程师也就成为了IT职
  • 袁红岗的编程感悟

    我自己知道 近几年也一直在用 但就是说不出来 直到最近几天才能够表达 叫作Think in Code 也就是用代码思考 同时也把代码当成自己思想表达的方式 正如哲学家用文字设计 诠释思想 程序员 说话 用的是代码 这就是一个程序员的境 界
  • ASP.NET Core快速入门(第6章:ASP.NET Core MVC)--学习笔记

    课程链接 http video jessetalk cn course explore 良心课程 大家一起来学习哈 任务40 介绍 任务41 Individual authentication 模板 dotnet new mvc help
  • HeadFirst 设计模式学习笔记10——MVC分析

    1 M V C Model View Controller 模式 视图 控制器 这是一种范型 模型对象正是应用系统存在的理由 你设计的对象 包含了数据 逻辑和其他在你的应用领域创建定制的类 视图通常是控件 用来显示和编辑 控制器位于二者中间
  • IntelliJ IDEA中如何使用JUnit4

    背景 最近参与了一个Anroid医疗项目 其中项目底层有很多基础类及通讯类 而且很多涉及复杂的字节操作还有多线程同步及状态机处理 这样的项目做一下TDD还是必要的 尽量项目前期把风险降低一些 现在的问题是本人使用的是IntelliJ开发的A
  • 金融类测试的总结

    金融测试前后端 前端 执行页面级测试用例 验证应用层基本功能 能是否和需求一致 页面风格是否一致 金额 利息 以及对应的状态是否正确等 后端 通过测试页面 录入测试用例 比对结果 为了看数字金额的准确性 也是确认金融底层的正确性以及逻辑性
  • 自动化测试——接口测试

    一 接口分类 1 内部接口 测试被测系统各个子模块之前的接口 或者测试被测系统提供给内部用户系统使用的接口 2 外部接口 被测系统调用外部的接口 系统对外提供的接口 接口测试重点 检查结论参数传递的正确性 输出结果的正确性及对各种异常情况的
  • 字符串匹配算法总结

    转自 http blog csdn net zdl1016 archive 2009 10 11 4654061 aspx 我想说一句 我日 我讨厌KMP KMP虽然经典 但是理解起来极其复杂 好不容易理解好了 便起码来巨麻烦 老子就是今天
  • [ASP.NET MVC 小牛之路]05 - 使用 Ninject

    在 ASP NET MVC 小牛之路 系列上一篇文章 依赖注入 DI 和Ninject 的末尾提到了在ASP NET MVC中使用Ninject要做的两件事情 续这篇文章之后 本文将用一个实际的示例来演示Ninject在ASP NET MV
  • 软件测试 app自动化02 Appium常用的元素定位工具 元素的属性 元素定位方法

    文章目录 1 Appium常用的元素定位工具 1 1 uiautomatorviewer 1 2 Appium Inspector 1 3 Weditor 2 元素的属性 3 元素定位方法 小结 1 Appium常用的元素定位工具 1 1
  • Mockito3.x详解

    目录 Mockito 1 简单示例 2 打桩测试 3 参数匹配器 4 调用次数验证 5 通过打桩为无返回值函数抛出异常 6 验证调用顺序 7 验证从未发生过的交互

随机推荐

  • 如何用Python创建SQL数据库 ? 学会就非常完美~

    今日份知识你摄入了么 会写SQL很重要 能高效地查询数据库被认为是数据分析师 科学家最基本的技能之一 SQL不仅重要 而且非常常用 根据 2021年Stackoverflow开发者调查 SQL是最常用的五种编程语言之一 所以 我们应该多投入
  • STL实现排序

    使用sort函数对容器内的随机元素进行排序 sort RandomAccessIterator first RandomAccessIterator last Compare comp RandomAccessIterator first
  • Libevent 事件循环(1)

    事件的dispatch int event base loop struct event base base int flags 得到采用的事件模型 epoll epoll select const struct eventop evsel
  • 单元测试,报java.lang.NoClassDefFoundError:org/springframework/test/content/TestContesxtAnnotationUtils

    这里写目录标题 一级目录 1 问题 单元测试 报java lang NoClassDefFoundError org springframework test content TestContesxtAnnotationUtils spri
  • Message: element not interactable错误解决

    1 在定位之前先等待资源加载完毕 sleep 10 element driver find element by xpath input class form control and name username 2 定义隐式等待 drive
  • SQL中grant的用法

    GRANT 名称 GRANT 赋予一个用户 一个组或所有用户访问权限 语法 GRANT privilege ON object TO PUBLIC GROUP group username 输入 privilege 可能的权限有 SELEC
  • Python OpenCV 入门教程

    原文链接 本文只是调整了代码格式 一 Python OpenCV 入门 欢迎阅读系列教程 内容涵盖 OpenCV 它是一个图像和视频处理库 包含 C C Python 和 Java 的绑定 OpenCV 用于各种图像和视频分析 如面部识别和
  • SSIS包配置

    Integrartion Services 包实际上就是一个对象属性的集合 在前面我们开发的所有 Integration Services包 其中的变量 属性 比如 数据库链接 同步文件目录等 我们都直接在包中用一个常量的方式 赋给这些变量
  • 2022亚马逊云科技中国峰会召开 宣布多项举措赋能客户数字化探索与创新

    2022年10月13日 以 自由构建 探索无限 为主题的亚马逊云科技中国峰会于今天在线上召开 在本次为期2天的峰会上 亚马逊云科技发布了云计算技术趋势展望 宣布 连中外 襄百业 携伙伴 促绿色 四大战略举措 进一步利用亚马逊云科技全球优势和
  • [思考进阶]03 每一个成年人都应该掌握的学习技巧

    除了要提升自己的技术能力 思维的学习和成长也非常非常重要 特推出此 思考进阶 系列 进行刻意练习 从而提升自己的认知 这世间有两种人 一种被誉为天之骄子 拥有那种天才的创造能力 这种人极少 另外一种是平凡的普通人 努力地想成功 这种人很多
  • C语言:输出一组数的最大值与最小值

    C语言 输出一组数中的最大值或最小值 如果要输出多个数的最大值只需更改数组大小与循环的限制条件即可 这里以三个数为例 最大值 include
  • [STM32] 关于USART接收中断的BUG和注意事项

    今天在使用USART模块 遇到了一些问题并解决了 于是发贴共享 问题描述 在使用USART做串口通讯时 我只把接收中断打开 并设置抢占优先级为最低一个级别 而接收中断上一个优先级处理事情比较多 可能占用了2ms时间 当我使用9600波特率往
  • 【Jupyter】【Colab】【AutoGluon】测试

    环境 pip install autogluon 测试代码 AutoGluon官网 from autogluon tabular import TabularDataset TabularPredictor train data Tabul
  • 第七章 缺失数据

    文章目录 一 缺失值的统计和删除 1 缺失信息的统计 2 缺失信息的删除 二 缺失值的填充和插值 1 利用fillna进行填充 练一练 END 2 插值函数 NOTE 关于polynomial和spline插值的注意事项 END 三 Nul
  • 用canvas画出可爱的哆啦A梦

    用canvas画出可爱的哆啦A梦 本文就介绍了如何用canvas案例画出哆啦A梦的基础内容 提示 以下是本篇文章正文内容 下面案例可供参考 一 canvas是什么 HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图
  • seata1.3.0 系列学习(二、nacos+seata使用)

    上篇文章讲了如何安装seata 这篇文章主要讲如何使用 分布讲解什么情况回滚 不回滚 一 新建父级maven pom xml文件导入
  • 数据结构-线性表(链表)(c++版)

    目录 1 单链表的基本概念与特点 2 单链表的特点 3 单链表的结构定义及其方法的实现 3 1 单链表结构的定义 3 2 方法的基本实现 3 3 单链表的插入删除操作讲解 3 4 单链表的删除算法 3 5 单链表的顺序访问与尾递归 3 6
  • c++ string 转 char * 出现乱码 内存共用问题

    系统 unbuntu16 04 IDE vscode 一 出现乱码 std string str Hello Word char p1 str c str 出现乱码 char p2 str data 出现乱码 二 出现内存共用 后面的字符串
  • C++的简单FTP客户端实现(二)编程

    基本FTP客户端 QT C 实现的FTP下载客户端 环境说明 FTP服务器 CentOS7 8 vsFTPD 3 0 2 安装设置见博文 CentOS vsftpd设置 客户端 win10 QT 5 15 2 实现的不是一个功能全的FTP客
  • H.264学习笔记3——帧间预测

    帧间预测主要包括运动估计 运动搜索方法 运动估计准则 亚像素插值和运动矢量估计 和运动补偿 对于H 264 是对16x16的亮度块和8x8的色度块进行帧间预测编码 A 树状结构分块 H 264的宏块 对于16x16的亮度宏块 可以分成16x