HEVC学习之率失真优化

news2024/11/23 13:07:59

一、理论部分

率失真理论:
在给定失真的前提下如何最大限度第去除冗余。
在视频编码中的率失真理论为在给定码率RT的前提下最大限度的减少视频信息的失真,用数学描述为第一个式子所示,其中m*为取得最小码率时的编码方式,S为编码方式的集合。
在这里插入图片描述
对于该有条件的优化问题,可以采用拉格朗日优化法解决,通过引入拉格朗日系数λ将约束性求最值问题转为非约束性求最值问题,如第二个式子所示。

编码工具集:
如分级预测、帧内预测、帧间预测、44变换、88变换等、UVCL熵编码、CABAC熵编码等,当编码工具集固定时,对于固定的信源来说,一个编码器必然有一个确定的可操作点X的集合,由于集合点的离散型,可以在这个集合中近似出曲线包络,其中最优的一条包络被称为率失真曲线理论值。当编解码中引入了新的工具时,率失真曲线理论值可能会向左下方移动。
在这里插入图片描述

对于给定的R,其失真最小的点在率失真曲线理论值曲线上,上述率失真优化的公式一即让选择到的可操作点尽可能贴近理论值曲线。

编码工具决定了RD曲线的形态,即对于给定的信源,其有可能的(R,D)点集合,然而在每次编码中只能选择一个(R,D)点,通过编码策略进行选择,即怎样利用编码工具:什么时候采用帧内编码,什么时候采用帧间编码,怎样分块等让选择到的(R,D)点贴近理论曲线,这个选择的过程即率失真优化。

由于引入了拉格朗日系数,不再给定码率RT,设D+λR=J,过(R,D)做一条斜率为λ的斜线,其于纵轴截距即为J,让J最小即让截距最小,此时让(R,D)逼近理论曲线的问题可转化为过(R,D)做一条斜率为λ的斜线,让其与y轴截距最小,通过数学推导可知,当该斜线于曲线相切时理论最小,寻找给(R,D)点的过程即HEVC中的率失真优化。

通过引入λ可以更方便地去权衡视频质量与码率的重要性,当λ设置较大时,为了让J更小,就需要控制R的大小,即更注重码率,当λ设置较小时,为了让J更小,就需要控制D的大小,即更注重视频质量。

二、HEVC中帧内预测中的RDO

率失真优化贯穿于视频编解码的整个阶段,这里以帧内预测为例:
在HM中,帧内预测分为三个步骤:模式粗选(rough mode decision,RMD)、最佳可能预测模式(most possible mode,MPM)和率失真优化(RDO)
RMD依次按照35种模式对当前PU进行预测,计算预测像素于原始像素的差,对差值进行阿达玛变换后求和,将最好的几个模式加入备选模式集中
MPM依据相邻PU间的相似性,将待编码PU附近的已编码PU的模式加入备选模式集中
RDO在最终的备选模式集中进行优化,选出最优编码策略,这个过程如下:
01.分层递归遍历所有CU划分
由于HEVC的编码结构为基于CTU的四叉树划分,这个过程的率失真优化流程可以按照如下递归式表式:
在这里插入图片描述
每次递归比较当前深度的率失真代价于下一深度的率失真代价
在递归的过程中确定出能使率失真代价最小的编码策略
02.对每个CU确定PU划分
03.对每个PU进行帧内预测

三、HM中的RDO实现

在TLibCommon中的TComCudata中存在三个成员函数:

  Double&       getTotalCost                  ( )  { return m_dTotalCost;        }
  Distortion&   getTotalDistortion            ( )  { return m_uiTotalDistortion; }
  UInt&         getTotalBits                  ( )   { return m_uiTotalBits;       }

分别为获取总的率失真代价,计算总失真,计算总比特数,这些数据作为该类的成员,可以被其他函数修改,
如总失真m_dTotalCost在CTU的初始化时被设为最大值,在后续递归调用时会被更新为其他值,总失真被初始化为0,总码率被初始化为0:

在这里插入图片描述
在计算某层CU划分结果的总结果时,需要计算其划分的pccu中的数值
在这里插入图片描述

上述计算是对于整体结果的统计,对于每个部分的相关数据计算的代码在TLibCommon中的TComRDcost中:
计算失真的代码如下:

Distortion TComRdCost::getDistPart( Int bitDepth, const Pel* piCur, Int iCurStride,  const Pel* piOrg, Int iOrgStride, UInt uiBlkWidth, UInt uiBlkHeight, const ComponentID compID, DFunc eDFunc )
{
  DistParam cDtParam;
  setDistParam( uiBlkWidth, uiBlkHeight, eDFunc, cDtParam );
  cDtParam.pOrg       = piOrg;
  cDtParam.pCur       = piCur;
  cDtParam.iStrideOrg = iOrgStride;
  cDtParam.iStrideCur = iCurStride;
  cDtParam.iStep      = 1;

  cDtParam.bApplyWeight = false;
  cDtParam.compIdx      = MAX_NUM_COMPONENT; // just for assert: to be sure it was set before use
  cDtParam.bitDepth     = bitDepth;

  if (isChroma(compID))
  {
    return ((Distortion) (m_distortionWeight[compID] * cDtParam.DistFunc( &cDtParam )));
  }
  else
  {
    return cDtParam.DistFunc( &cDtParam );
  }

其中DistParam cDtParam;是存在有关图像失真相关数据的对象,DistFunc为失真函数

enum ComponentID
{
  COMPONENT_Y       = 0,
  COMPONENT_Cb      = 1,
  COMPONENT_Cr      = 2,
  MAX_NUM_COMPONENT = 3
};

由于亮度与色度的失真计算方式不同,需要通过枚举型数据compID进行判断:

通过直接调用熵编码类的getNumberOfWrittenBits()来计算码率

rpcTempCU->getTotalBits() += m_pcEntropyCoder->getNumberOfWrittenBits(); // dQP bits
rpcTempCU->getTotalBins() += ((TEncBinCABAC *)((TEncSbac*)m_pcEntropyCoder->m_pcEntropyCoderIf)->getEncBinIf())->getBinsCoded();
rpcTempCU->getTotalCost()  = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );

计算出的码率getTotalBits()与失真getTotalDistortion一起通过calcRdCost拿去计算总失真:

计算总失真的代码如下:

Double TComRdCost::calcRdCost( Double numBits, Double distortion, DFunc eDFunc )
{
  Double lambda = 1.0;

  switch ( eDFunc )
  {
    case DF_SSE:
      assert(0);
      break;
    case DF_SAD:
      lambda = m_dLambdaMotionSAD[0]; // 0 is valid, because for lossless blocks, the cost equation is modified to compensate.
      break;
    case DF_DEFAULT:
      lambda = m_dLambda;
      break;
    case DF_SSE_FRAME:
      lambda = m_dFrameLambda;
      break;
    default:
      assert (0);
      break;
  }

  if (eDFunc == DF_SAD)
  {
    if (m_costMode != COST_STANDARD_LOSSY)
    {
      return ((distortion * 65536.0) / lambda) + numBits; // all lossless costs would have uiDistortion=0, and therefore this cost function can be used.
    }
    else
    {
      return distortion + (((numBits * lambda) ) / 65536.0);
    }
  }
  else
  {
    if (m_costMode != COST_STANDARD_LOSSY)
    {
      return (distortion / lambda) + numBits; // all lossless costs would have uiDistortion=0, and therefore this cost function can be used.
    }
    else
    {
      return distortion + (numBits * lambda);
    }
  }
}

eDFunc 代表了不同的损失函数,不同损失函数在率失真代价计算中使用的λ有所不同,随后根据不同的模式与不同的代价函数计算出失真。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/508731.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用MASA全家桶从零开始搭建IoT平台(三)管理设备的连接状态

文章目录 前言分析方案1:遗嘱消息演示遗嘱消息的使用实施流程 方案2:使用WebHook开启WebHook演示Webhook编写代码 前言 获取一个设备的在线和离线状态,是一个很关键的功能。我们对设备下发的控制指令,设备处于在线状态才能及时给我们反馈。这里的在线和…

SOLIDWORKS钣金折弯参数设置技巧

折弯系数早期是没有计算方法的,工厂都是根据实际经验确定下来的经验公式。 记录下来一个经验数据表或简单的经验公式。后来才出现的中性层概念,即既不伸长也不压缩的那一层为中性层。可以用来计算展开长度。SOLIDWORKS钣金折弯参数也是整合了所有的计算…

【C++】类和对象(中)---构造函数和析构函数

个人主页:平行线也会相交💪 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【C之路】💌 本专栏旨在记录C的学习路线,望对大家有所帮助🙇‍ 希望我们一起努力、成长&…

【AI大模型】讯飞星火大模型能否超越chatgpt?我们拭目以待!

文章目录 前言你有使用过这种对话式AI吗?你对这类型AI有什么看法或感受?对于“讯飞星火大模型将超越chatgpt?”这个命题你的态度是什么?简要说说原因你认为这类型的人工智能对于现在的社会有哪些意义?对于这类型的人工…

GEE开发之MODIS_MCD12Q1数据分析和获取

GEE开发之MODIS_土地类型分类 0.MCD12Q1介绍1.遥感影像查看2.MCD12Q1分类介绍3.年数据下载(LC_Type1/year/500m) 前言:主要介绍MODIS的MCD12Q1产品,包括MCD12Q1产品的介绍、使用和下载。 0.MCD12Q1介绍 Terra 和 Aqua 组合的中分…

AI 大底座,大模型时代的答卷

文心一言的诞生 “文心一言就是在这个全国 AI 领域规模最大的高性能 GPU 集群上完成训练的。” 早在 2021 年 6 月,为了满足未来的大模型训练任务,百度智能云开始规划全新的高性能 GPU 集群的建设,联合 NVIDIA 共同完成了可以容纳万卡以上规…

华人再次突破芯片技术瓶颈,然而成果归美芯,中国芯可能输了?

外媒报道指华人研发团队已突破芯片的极限,晶体管厚度只有三个原子那么大,达到0.3纳米,打破了此前芯片业界认为的1纳米是硅基芯片技术极限的概念,然而这项技术却是归美国所有。 这次取得技术突破的研发团队是麻省理工研究所&#x…

云服务器安装宝塔Linux面板命令脚本大全

阿里云服务器安装宝塔Linux面板,操作系统不同安装命令脚本也不同,支持CentOS、Alibaba Cloud Linux、Ubuntu/Deepin等Linux系统,阿里云服务器网分享阿里云服务器安装宝塔Linux面板命令脚本大全: 云服务器安装宝塔Linux面板命令 …

无公网IP,公网SSH远程访问家中的树莓派

文章目录 前言如何通过 SSH 连接到树莓派步骤1. 在 Raspberry Pi 上启用 SSH步骤2. 查找树莓派的 IP 地址步骤3. SSH 到你的树莓派步骤 4. 在任何地点访问家中的树莓派4.1 安装 Cpolar内网穿透4.2 cpolar进行token认证4.3 配置cpolar服务开机自启动4.4 查看映射到公网的隧道地址…

多时相遥感深度学习作物提取方法综述(万字长文)

一、 引言 本人研究的方向是遥感作物分布提取,想基于多时相、深度学习和GEE平台展开研究,现对相关文献进行资料调研。深度学习和遥感原本属于2个研究方向,现在已经有越来越多的研究开始将深度学习算法应用到遥感领域。 传统遥感研究人员重视遥感数据本身,善于分析作物生长…

Vector - CAPL - CANoe硬件配置函数 - 03

目录 canFlushTxQueue -- 刷新已定义的Tx队列 代码示例 canSetChannelAcc -- CANoe接收过滤器设置 代码示例 canSetChannelMode -- CAN控制器Tx使能/失能 代码示例 canSetChannelOutput -- Ack自应答使能/失能 代码示例 getCardTypeEx -- CAN控制器类型 canFlushTxQue…

Node.js 与 TypeScript

目录 1、什么是 TypeScript 2、运行TypeScript 3、TypeScript 在Node.js 生态中的情况 1、什么是 TypeScript TypeScript是一种流行的开源语言,由微软维护和开发。它受到了世界各地许多软件开发人员的喜爱和使用。 基本上,它是JavaScript的超集&…

信号完整性基础03:反射与阻抗匹配(1)

说在开头:关于“惰性气体” 英国剑桥大学当时的校长是:威廉.卡文迪许公爵,他的祖上有一位“科学怪人”:亨利.卡文迪许,他一辈子深居简出,淡泊名利,从不靠刷论文来体现自己的学术水平&#xff0…

VMware NSX Advanced Load Balancer (NSX ALB) 22.1.3 - 负载均衡平台

请访问原文链接:https://sysin.org/blog/vmware-nsx-alb-22/,查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org 负载均衡平台 NSX Advanced Load Balancer NSX Advanced Load Balancer (Avi) 可简化应用交付&#xff…

关于儿童急性感染性腹泻

腹泻是一种常见的症状,可导致儿童生长发育迟滞和营养不良。根据世界卫生组织(WHO)发布的数据显示,急性腹泻在5岁以下儿童死亡原因中排第二位,仅次于肺炎。引起儿童腹泻的原因包括感染和非感染因素,后者主要…

C语言CRC-16 XMODEM格式校验函数

C语言CRC-16 XMODEM格式校验函数 CRC-16校验产生2个字节长度的数据校验码,通过计算得到的校验码和获得的校验码比较,用于验证获得的数据的正确性。基本的CRC-16校验算法实现,参考: C语言标准CRC-16校验函数。 不同应用规范通过对…

一文快速入门体验 Hibernate

前言 Hibernate 是一个优秀的持久层的框架,当然,虽然现在说用得比较多的是 MyBaits,但是我工作中也不得不接触 Hibernate,特别是一些老项目需要你维护的时候。所以,在此写下这篇文章,方便自己回顾&#xf…

vue+Nodejs+Koa搭建前后端系统(五)--Nodejs中使用数据库

连接数据库 1.开启mysql服务 以管理员身份运行cmd,输入: net start mysql2.登录 root用户、创建新用户、赋予新用户权限 如果你用root用户作为node的连接用户,这一步可以略过。 (1)登录root: mysql -…

多功能文档应用程序Codex Docs

什么是 Codex Docs ? CodeX Docs 是一个简单的免费应用程序,适用于您的内部、公共或个人文档。它基于Editor.js,允许使用漂亮干净的 UI 处理内容。 官方提供了演示站点:https://docs-demo.codex.so/about-this-demo 安装 在群晖…

CIAA 网络安全模型 — 数据传输安全

目录 文章目录 目录网络传输 CIAA 安全模型机密性(Confidentiality)对称加密非对称加密混合加密 完整性(Integrity)L2 数据链路层的 CRC 强校验L3 网络层的 Checksum 弱校验L4 传输层的 Checksum 弱校验安全层的 Checksum 强校验 …