H264编码器实现-帧内预测之像素值预测

前言

本文所介绍的像素值预测,是指在帧内预测总体流程中的预测块每个像素值的推导过程。当我们已知向量像素的重建值的时候,我们就可以对当前预测块进行像素值预测。该过程得到的结果将与源像素值相减得到残差,为后续变换量化提供数据来源。

温馨提示:本文所讲的内容都有对应的可执行代码,读者可以结合代码理解文章内容。

预测模式

对亮度像素而言,4×4 亮度子块有9 种可选预测模式,适用于带有大量细节的图像编码。16×16 亮度块有4种预测模式,适用于平坦区域图像编码。对于色度像素,只有8x8色度块,其预测也有4 种预测模式,类似于16×16 亮度块预测模式。

4x4亮度块预测

上文说到4x4亮度块有9种预测模式,不同模式预测的角度不同,下面是各个预测模式的描述:

模式名称描述
模式0由A、B、C、D 垂直推出相应像素值
模式1由I、J、K、L 水平推出相应像素值
模式2由A~D 及I~L 平均值推出所有像素值
模式3由45°方向像素内插得出相应像素值
模式4由45°方向像素内插得出相应像素值
模式5由26.6°方向像素值内插得出相应像素值
模式6由26.6°方向像素值内插得出相应像素值
模式7由26.6° 方向像素值内插得出相应像素值
模式8由26.6° 方向像素值内插得出相应像素值

各预测模式
当前块预测
这里对各个预测模式做个解释:
(1)预测模式0(vertical):当前块的十六个像素值由其上方A、B、C、D四个像素值决定,即a=e=i=m=A,b=f=j=n=B,c=g=k=o=C,d=h=l=p=D
模式0
(2)预测模式1(horizontal):当前块的十六个像素值由其左方I、J、K、L四个像素值决定,即a=b=c=d=I,e=f=g=h=J,i=j=k=l=K,m=n=o=p=L。
模式1
(3)预测模式2(DC):十六个像素值完全相等,等于ABCDIJKL这八个像素的平均值。
模式3
(4)预测模式3(diagnal down-left):左下45度方向上的像素相等,由相邻块像素加权平均得到。
即a==(A+2B+C+2)/4,b=e=(B+2C+D)/4,c=f=i=(C+2D+E+2)/4,d=g=j=m=(D+2E+F+2)/4,h=k=n=(E+2F+G+2)/4,l=o=(F+2G+H+2)/4,p=(G+2H+H+2)/4=(G+3H+2)/4。
模式4
(5)预测模式4(diag down-right):右下45度方向上的像素相等,由相邻块像素加权平均得到。
即a=f=k=p=(I+2M+A+2)/4,e=f=o=(J+2I+M)/4,i=n=(K+2J+I+2)/4,m=(L+2K+J+2)/4,b=g=l=(B+2A+M+2)/4,c=h=(C+2B+A+2)/4,d=(D+2C+B+2)/4。
模式4
(6)预测模式5(vertical right):

include <stdio.h>
#include <stdlib.h>
#include <string.h>#define BLK_WIDTH 4 //当前块宽度
#define BLK_HIGHT 4 //当前块高度
#define BLOCK_SIZE 4
#define BLOCK_SHIFT 2// Predictor array index definitions
#define P_X (PredPel[0])
#define P_A (PredPel[1])
#define P_B (PredPel[2])
#define P_C (PredPel[3])
#define P_D (PredPel[4])
#define P_E (PredPel[5])
#define P_F (PredPel[6])
#define P_G (PredPel[7])
#define P_H (PredPel[8])
#define P_I (PredPel[9])
#define P_J (PredPel[10])
#define P_K (PredPel[11])
#define P_L (PredPel[12])typedef unsigned char imgpel;enum {VERT_PRED            = 0,HOR_PRED             = 1,DC_PRED              = 2,DIAG_DOWN_LEFT_PRED  = 3,DIAG_DOWN_RIGHT_PRED = 4,VERT_RIGHT_PRED      = 5,HOR_DOWN_PRED        = 6,VERT_LEFT_PRED       = 7,HOR_UP_PRED          = 8
} I4x4PredModes;
/*!************************************************************************* \brief*    Vertical 4x4 Prediction*************************************************************************/
static inline void get_i4x4_vertical(imgpel **cur_pred, imgpel *PredPel)
{memcpy(cur_pred[0], &PredPel[1], BLOCK_SIZE * sizeof(imgpel));memcpy(cur_pred[1], &PredPel[1], BLOCK_SIZE * sizeof(imgpel));memcpy(cur_pred[2], &PredPel[1], BLOCK_SIZE * sizeof(imgpel));memcpy(cur_pred[3], &PredPel[1], BLOCK_SIZE * sizeof(imgpel));
}
/*!************************************************************************* \brief*    Horizontal 4x4 Prediction*************************************************************************/
static inline void get_i4x4_horizontal(imgpel **cur_pred, imgpel *PredPel)
{int i;for (i=0; i < BLOCK_SIZE; i++){cur_pred[i][0]  =cur_pred[i][1]  =cur_pred[i][2]  =cur_pred[i][3]  = (imgpel) (&P_I)[i];}
}/*!************************************************************************* \brief*    DC 4x4 Prediction*************************************************************************/
static inline void get_i4x4_dc(imgpel **cur_pred, imgpel *PredPel, int left_available, int up_available)
{int i, j, s0 = 0;if (up_available && left_available){// no edges0 = (P_A + P_B + P_C + P_D + P_I + P_J + P_K + P_L + 4) >> (BLOCK_SHIFT + 1);}else if (!up_available && left_available){// upper edges0 = (P_I + P_J + P_K + P_L + 2) >> BLOCK_SHIFT;;}else if (up_available && !left_available){// left edges0 = (P_A + P_B + P_C + P_D + 2) >> BLOCK_SHIFT;}else //if (!up_available && !left_available){// top left corner, nothing to predict froms0 = P_A; // P_A already set to p_Vid->dc_pred_value;}for (j=0; j < BLOCK_SIZE; j++){for (i=0; i < BLOCK_SIZE; i++)cur_pred[j][i] = (imgpel) s0;}
}void get_intrapred_4x4(imgpel *PredPel, imgpel ***curr_mpr_4x4, int i4x4_mode,  int left_available, int up_available)
{switch (i4x4_mode){case VERT_PRED :get_i4x4_vertical(curr_mpr_4x4[VERT_PRED], PredPel);break;case HOR_PRED :get_i4x4_horizontal(curr_mpr_4x4[HOR_PRED], PredPel);break;case DC_PRED :get_i4x4_dc(curr_mpr_4x4[DC_PRED], PredPel, left_available, up_available);break;case DIAG_DOWN_LEFT_PRED :get_i4x4_downleft(curr_mpr_4x4[DIAG_DOWN_LEFT_PRED], PredPel);break;case DIAG_DOWN_RIGHT_PRED :get_i4x4_downright(curr_mpr_4x4[DIAG_DOWN_RIGHT_PRED], PredPel);break;case VERT_RIGHT_PRED :get_i4x4_vertright(curr_mpr_4x4[VERT_RIGHT_PRED], PredPel);break;case HOR_DOWN_PRED :get_i4x4_hordown(curr_mpr_4x4[HOR_DOWN_PRED], PredPel);break;case VERT_LEFT_PRED :get_i4x4_vertleft(curr_mpr_4x4[VERT_LEFT_PRED], PredPel);break;case HOR_UP_PRED :get_i4x4_horup(curr_mpr_4x4[HOR_UP_PRED], PredPel);break;default:printf("invalid prediction mode \n");break;}
}

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

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

相关文章

大模型算法面试题(十二)

本系列收纳各种大模型面试题及答案。 1、领域模型Continue PreTrain数据如何选取 在领域模型的Continue PreTrain&#xff08;持续预训练&#xff09;过程中&#xff0c;数据选取是一个至关重要的步骤&#xff0c;它直接影响模型在特定领域上的性能和泛化能力。以下是一些关于…

探索Linux-1-虚拟机远程登陆XShell6远程传输文件Xftp6

Linux是什么&#xff1f; Linux是一个开源的操作系统内核&#xff0c;由林纳斯托瓦兹&#xff08;Linus Torvalds&#xff09;于1991年首次发布。它基于Unix操作系统&#xff0c;但提供了更多的自由和灵活性。Linux内核是操作系统的核心部分&#xff0c;负责管理系统资源、处理…

vue3利用父子传参将页面展示到另一个页面上

点击左下角传到右边 绑定点击事件&#xff0c;在点击事件里传入参数1&#xff0c;将参数赋值给父组件绑定的tag参数上 props获取父组件参数

【Git】不同区域撤销代码{reset、revert}

工作区【磁盘】 关于GIt&#xff0c;当你在工作区也就是硬盘中修改文件内容&#xff0c;也就是下图的状态。 若你需要撤销此次修改&#xff0c;用到的命令就是 git checkout <changed_file> git restore <changed_file> #推荐 因为checkout在分支中也是切换分…

电子签章-开放签应用

开放签电子签章系统开源工具版旨在将电子签章、电子合同系统开发中的前后端核心技术开源开放&#xff0c;适合有技术能力的个人 / 团队学习或自建电子签章 \ 电子合同功能或应用&#xff0c;避免研发同仁在工作过程中重复造轮子&#xff0c;降低电子签章技术研发要求&#xff0…

找工作准备刷题Day10 回溯算法 (卡尔41期训练营 7.24)

回溯算法今天这几个题目做过&#xff0c;晚上有面试&#xff0c;今天水一水。 第一题&#xff1a;Leetcode77. 组合 题目描述 解题思路 从题目示例来看&#xff0c;k个数是不能重合的&#xff0c;但是题目没有明确说明这一点。 使用回溯算法解决此问题&#xff0c;利用树形…

【iOS】——通知机制及底层原理

通知传值概要 通知传值可以跨越多个界面进行传值&#xff0c;一般用于后一个界面向前一个界面传值。 通知传值支持多个接收者&#xff0c;多个对象可以同时接收同一个通知并进行处理。这样可以实现一对多的通信&#xff0c;方便跨多个对象进行值传递。 使用步骤 1.在发送者中…

0726,没什么用的SELECT和没用的我

目录 select 可恶&#xff01;&#xff01;&#xff01; 一对多聊天室 select&#xff1a;&#xff08;抄抄抄 最怕人类开始思考 补一对一的 select 喵&#xff1a;&#xff08;抄抄抄 &#xff1f;&#xff1f;今天就这么结束了&#xff1f;&#xff1f;&#xff1f; …

CTF-NSSCTF[GKCTF 2021]

[GKCTF 2021]easycms 考察&#xff1a; 用扫描工具扫描目录&#xff0c;扫描到后台登录界面/admin.php 题目提示了密码是五位弱口令&#xff0c;试了试弱口令admin和12345直接成功了 任意文件下载 点击设计-->主题然后随便选择一个主题&#xff0c;点击自定义&#xff0…

队列--顺序队列的表示和实现

#include<stdio.h> #define MAXQSIZE 10 typedef int QElemType; typedef int Status; //顺序队列 (循环队列,有一个空间不用) typedef struct{QElemType *base;int rear;int front; }SqQueue; //初始化队列 Status InitQueue(SqQueue &Q){Q.basenew QElemType[MAX…

MAC地址格式批量转换工具V1.0适用于Windows系统

自己做了个MAC地址格式批量转换工具&#xff0c;方便实用。 一、主要实现下面6种功能&#xff1a; MAC格式&#xff0c;如“AC-09-87-DB-E9-F0”转“AC09-87DB-E9F0” MAC格式&#xff0c;如“AC09-87DB-E9F0”转“AC-09-87-DB-E9-F0” MAC格式&#xff0c;如“AC-09-87-DB-…

Laravel:揭秘PHP世界中最优雅的艺术品

1. 引言 在PHP的世界里&#xff0c;框架如繁星般璀璨&#xff0c;但Laravel以其独特的魅力和优雅&#xff0c;成为了众多开发者心中的艺术品。本文将深入探讨Laravel为何能在众多PHP框架中脱颖而出&#xff0c;成为最优雅的选择。 1.1 Laravel的诞生背景 Laravel的诞生可以…

高清视频,无损音频,LDR6023——打造极致视听与高效充电的双重享受!

Type-C PD&#xff08;Power Delivery&#xff09;芯片是一种支持USB Type-C接口规范的电源管理单元&#xff0c;其主要功能包括&#xff1a; 快速充电&#xff1a;Type-C PD芯片支持高功率传输&#xff0c;能够提供更快的充电速度&#xff0c;使电子设备在短时间内充满电&…

用Postman Flows打造你的专属API:外部公开,轻松上手!

引言 Postman Flows 是一个使用 GUI 进行无代码 API 调用流程创建的服务。这篇文章我尝试使用 Flows 来构建将 Momento Topic 中的数据保存到 TiDB 的保存 API&#xff0c;因此想分享一些使用过程中的技巧等。 实现内容 将从 Momento Topics 配发的 JSON 数据保存到 TiDB 中。…

论文复述:AGTC

论文: Attention-Guided Low-Rank Tensor Completion, 作者为Truong Thanh Nhat Mai, Edmund Y. Lam and Chul Lee.

04。拿捏ArkTS第二天

1&#xff0c;什么是常量&#xff1f; 用来存储不可变的数据。 2&#xff0c;定义常量的基本样式&#xff1f; const con : number 1 const con : string ”我是不可变的字符串“ const con : boolean false ***********************************************************…

我在高职教STM32——串口通信(5)

大家好,我是老耿,高职青椒一枚,一直从事单片机、嵌入式、物联网等课程的教学。对于高职的学生层次,同行应该都懂的,老师在课堂上教学几乎是没什么成就感的。正因如此,才有了借助 CSDN 平台寻求认同感和成就感的想法。在这里,我准备陆续把自己花了很多心思的教学设计分享…

WordPress设置固定连接后提示404

WordPress设置固定链接后出现404错误通常是因为服务器的伪静态规则没有正确设置。以下是几种常见的服务器环境下的解决方案&#xff1a; 宝塔面板&#xff1a;如果服务器安装了宝塔面板&#xff0c;可以在宝塔面板中选择对应的WordPress伪静态规则并保存设置 。 Apache服务器&a…

nacos 2.4.0.1 源码编译,适配达梦dm数据库

一、编译nacos源码&#xff0c;并运行 1. 下载nacos代码 github nacos 仓库地址&#xff1a;nacos 本文以2.4.0.1演示&#xff0c;github操作如下 选择Tags 2.4.0.1 解压nacos-2.4.0.1.zip到nacos-2.4.0.1&#xff0c;并用idea打开 2. 编译代码 maven clean install 如果…

使用大型语言模型进行文档解析(附带代码)

动机 多年来&#xff0c;正则表达式一直是我解析文档的首选工具&#xff0c;我相信对于许多其他技术人员和行业来说也是如此。 尽管正则表达式在某些情况下功能强大且成功&#xff0c;但它们常常难以应对现实世界文档的复杂性和多变性。 另一方面&#xff0c;大型语言模型提供了…