openh264解码h264视频帧主流程
一 解析一帧的入口
int32_t WelsDecodeSlice (PWelsDecoderContext pCtx, bool bFirstSliceInLayer, PNalUnit pNalCur) {
// 解码slice
PDqLayer pCurDqLayer = pCtx->pCurDqLayer;
PFmo pFmo = pCtx->pFmo;
int32_t iRet;
int32_t iNextMbXyIndex, iSliceIdc;
PSlice pSlice = &pCurDqLayer->sLayerInfo.sSliceInLayer;
PSliceHeaderExt pSliceHeaderExt = &pSlice->sSliceHeaderExt;
PSliceHeader pSliceHeader = &pSliceHeaderExt->sSliceHeader;
int32_t iMbX, iMbY;
const int32_t kiCountNumMb = pSliceHeader->pSps->uiTotalMbCount; //need to be correct when fmo or multi slice
uint32_t uiEosFlag = 0;
PWelsDecMbFunc pDecMbFunc;
pSlice->iTotalMbInCurSlice = 0; //initialize at the starting of slice decoding.
if (pCtx->pPps->bEntropyCodingModeFlag) { //cabac 熵编码
if (pSlice->sSliceHeaderExt.bAdaptiveMotionPredFlag ||
pSlice->sSliceHeaderExt.bAdaptiveBaseModeFlag ||
pSlice->sSliceHeaderExt.bAdaptiveResidualPredFlag) {
WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR,
"WelsDecodeSlice()::::ILP flag exist, not supported with CABAC enabled!");
pCtx->iErrorCode |= dsBitstreamError;
return dsBitstreamError;
}
if (P_SLICE == pSliceHeader->eSliceType) //P Slice帧解析
pDecMbFunc = WelsDecodeMbCabacPSlice;
else if (B_SLICE == pSliceHeader->eSliceType) // B slice解析
pDecMbFunc = WelsDecodeMbCabacBSlice;
else //I_SLICE. B_SLICE is being supported
pDecMbFunc = WelsDecodeMbCabacISlice; // I Slice解析
} else { //
if (P_SLICE == pSliceHeader->eSliceType) {
pDecMbFunc = WelsDecodeMbCavlcPSlice;
} else if (B_SLICE == pSliceHeader->eSliceType) {
pDecMbFunc = WelsDecodeMbCavlcBSlice;
} else { //I_SLICE
pDecMbFunc = WelsDecodeMbCavlcISlice;
}
}
二 解析P slice函数
int32_t WelsDecodeMbCabacPSlice (PWelsDecoderContext pCtx, PNalUnit pNalCur, uint32_t& uiEosFlag) {
PDqLayer pCurDqLayer = pCtx->pCurDqLayer; //当前解码上下文
PSlice pSlice = &pCurDqLayer->sLayerInfo.sSliceInLayer; // slice上下文
PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader; // slice header
PPicture* ppRefPic = pCtx->sRefPic.pRefList[LIST_0]; //参考帧上下文
uint32_t uiCode;
int32_t iMbXy = pCurDqLayer->iMbXyIndex;
int32_t i;
SWelsNeighAvail uiNeighAvail;
pCurDqLayer->pCbp[iMbXy] = 0; //code block parttern信息
pCurDqLayer->pCbfDc[iMbXy] = 0;
pCurDqLayer->pChromaPredMode[iMbXy] = C_PRED_DC;
pCurDqLayer->pNoSubMbPartSizeLessThan8x8Flag[iMbXy] = true;
pCurDqLayer->pTransformSize8x8Flag[iMbXy] = false;
GetNeighborAvailMbType (&uiNeighAvail, pCurDqLayer); //填充邻居mb_type 为当前宏块解码做准备
WELS_READ_VERIFY (ParseSkipFlagCabac (pCtx, &uiNeighAvail, uiCode)); //解析是否为skip块
if (uiCode) {
int16_t pMv[2] = {0};
pCurDqLayer->pDec->pMbType[iMbXy] = MB_TYPE_SKIP;
ST32 (&pCurDqLayer->pNzc[iMbXy][0], 0);
ST32 (&pCurDqLayer->pNzc[iMbXy][4], 0);
ST32 (&pCurDqLayer->pNzc[iMbXy][8], 0);
ST32 (&pCurDqLayer->pNzc[iMbXy][12], 0);
ST32 (&pCurDqLayer->pNzc[iMbXy][16], 0);
ST32 (&pCurDqLayer->pNzc[iMbXy][20], 0);
pCurDqLayer->pInterPredictionDoneFlag[iMbXy] = 0;
memset (pCurDqLayer->pDec->pRefIndex[0][iMbXy], 0, sizeof (int8_t) * 16);
bool bIsPending = GetThreadCount (pCtx) > 1;
pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (ppRefPic[0] && (ppRefPic[0]->bIsComplete
|| bIsPending));
//predict mv
PredPSkipMvFromNeighbor (pCurDqLayer, pMv); //通过周围块的信息,计算得到当前块的mvp
for (i = 0; i < 16; i++) {
ST32 (pCurDqLayer->pDec->pMv[0][iMbXy][i], * (uint32_t*)pMv);
ST32 (pCurDqLayer->pMvd[0][iMbXy][i], 0);
}
//if (!pSlice->sSliceHeaderExt.bDefaultResidualPredFlag) {
// memset (pCurDqLayer->pScaledTCoeff[iMbXy], 0, 384 * sizeof (int16_t));
//}
//reset rS
pCurDqLayer->pLumaQp[iMbXy] = pSlice->iLastMbQp; //??????????????? dqaunt of previous mb 前一个qp,当前
//解码得到 delta + 这里的qp就是实际qp
for (i = 0; i < 2; i++) {
pCurDqLayer->pChromaQp[iMbXy][i] = g_kuiChromaQpTable[WELS_CLIP3 (pCurDqLayer->pLumaQp[iMbXy] +
pSliceHeader->pPps->iChromaQpIndexOffset[i], 0, 51)];
//计算得到chromaqp,和lumaqp有对应关系
}
//for neighboring CABAC usage
pSlice->iLastDeltaQp = 0;
WELS_READ_VERIFY (ParseEndOfSliceCabac (pCtx, uiEosFlag));
return ERR_NONE;
}
WELS_READ_VERIFY (WelsDecodeMbCabacPSliceBaseMode0 (pCtx, &uiNeighAvail, uiEosFlag)); //实际解析slice 中MB列表
return ERR_NONE;
三 解析Bslice过程
int32_t WelsDecodeMbCabacBSlice (PWelsDecoderContext pCtx, PNalUnit pNalCur, uint32_t& uiEosFlag) {
//解析B slice
PDqLayer pCurDqLayer = pCtx->pCurDqLayer; //当前帧上下文
PSlice pSlice = &pCurDqLayer->sLayerInfo.sSliceInLayer; //Slice指针
PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader; //当前slice头指着
PPicture* ppRefPicL0 = pCtx->sRefPic.pRefList[LIST_0]; //前向参考列表
PPicture* ppRefPicL1 = pCtx->sRefPic.pRefList[LIST_1]; //后向参考列表
uint32_t uiCode; //
int32_t iMbXy = pCurDqLayer->iMbXyIndex;
int32_t i;
SWelsNeighAvail uiNeighAvail;
pCurDqLayer->pCbp[iMbXy] = 0; //
pCurDqLayer->pCbfDc[iMbXy] = 0;
pCurDqLayer->pChromaPredMode[iMbXy] = C_PRED_DC;
pCurDqLayer->pNoSubMbPartSizeLessThan8x8Flag[iMbXy] = true;
pCurDqLayer->pTransformSize8x8Flag[iMbXy] = false;
GetNeighborAvailMbType (&uiNeighAvail, pCurDqLayer); //填充周围宏块信息
WELS_READ_VERIFY (ParseSkipFlagCabac (pCtx, &uiNeighAvail, uiCode)); //解析 skip标记
memset (pCurDqLayer->pDirect[iMbXy], 0, sizeof (int8_t) * 16);
bool bIsPending = GetThreadCount (pCtx) > 1;
if (uiCode) {
int16_t pMv[LIST_A][2] = { {0, 0}, { 0, 0 } };
int8_t ref[LIST_A] = { 0 };
pCurDqLayer->pDec->pMbType[iMbXy] = MB_TYPE_SKIP | MB_TYPE_DIRECT;
ST32 (&pCurDqLayer->pNzc[iMbXy][0], 0);
ST32 (&pCurDqLayer->pNzc[iMbXy][4], 0);
ST32 (&pCurDqLayer->pNzc[iMbXy][8], 0);
ST32 (&pCurDqLayer->pNzc[iMbXy][12], 0);
ST32 (&pCurDqLayer->pNzc[iMbXy][16], 0);
ST32 (&pCurDqLayer->pNzc[iMbXy][20], 0);
pCurDqLayer->pInterPredictionDoneFlag[iMbXy] = 0;
memset (pCurDqLayer->pDec->pRefIndex[LIST_0][iMbXy], 0, sizeof (int8_t) * 16);
memset (pCurDqLayer->pDec->pRefIndex[LIST_1][iMbXy], 0, sizeof (int8_t) * 16);
pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (ppRefPicL0[0] && (ppRefPicL0[0]->bIsComplete
|| bIsPending)) || ! (ppRefPicL1[0] && (ppRefPicL1[0]->bIsComplete || bIsPending));
if (pCtx->bMbRefConcealed) {
SLogContext* pLogCtx = & (pCtx->sLogCtx);
WelsLog (pLogCtx, WELS_LOG_ERROR, "Ref Picture for B-Slice is lost, B-Slice decoding cannot be continued!");
return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_DATA, ERR_INFO_REFERENCE_PIC_LOST);
}
SubMbType subMbType;
if (pSliceHeader->iDirectSpatialMvPredFlag) { //Direct 块类型判断
//predict direct spatial mv
int32_t ret = PredMvBDirectSpatial (pCtx, pMv, ref, subMbType);
if (ret != ERR_NONE) {
return ret;
}
} else {
//temporal direct mode
int32_t ret = PredBDirectTemporal (pCtx, pMv, ref, subMbType);
if (ret != ERR_NONE) {
return ret;
}
}
//reset rS
pCurDqLayer->pLumaQp[iMbXy] = pSlice->iLastMbQp; //??????????????? dqaunt of previous mb
for (i = 0; i < 2; i++) {
pCurDqLayer->pChromaQp[iMbXy][i] = g_kuiChromaQpTable[WELS_CLIP3 (pCurDqLayer->pLumaQp[iMbXy] +
pSliceHeader->pPps->iChromaQpIndexOffset[i], 0, 51)];
}
//for neighboring CABAC usage
pSlice->iLastDeltaQp = 0;
WELS_READ_VERIFY (ParseEndOfSliceCabac (pCtx, uiEosFlag));
return ERR_NONE;
}
WELS_READ_VERIFY (WelsDecodeMbCabacBSliceBaseMode0 (pCtx, &uiNeighAvail, uiEosFlag)); //实际解析BSlice中的mb
return ERR_NONE;
}
四 解析ISlice过程
int32_t WelsDecodeMbCabacISliceBaseMode0 (PWelsDecoderContext pCtx, uint32_t& uiEosFlag) {
//解析I slice
PDqLayer pCurDqLayer = pCtx->pCurDqLayer; //当前帧解码上下文
PBitStringAux pBsAux = pCurDqLayer->pBitStringAux;
PSlice pSlice = &pCurDqLayer->sLayerInfo.sSliceInLayer; //slice上下文
PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
SWelsNeighAvail sNeighAvail;
int32_t iScanIdxStart = pSlice->sSliceHeaderExt.uiScanIdxStart;
int32_t iScanIdxEnd = pSlice->sSliceHeaderExt.uiScanIdxEnd;
int32_t iMbXy = pCurDqLayer->iMbXyIndex;
int32_t i;
uint32_t uiMbType = 0, uiCbp = 0, uiCbpLuma = 0, uiCbpChroma = 0;
ENFORCE_STACK_ALIGN_1D (uint8_t, pNonZeroCount, 48, 16);
pCurDqLayer->pNoSubMbPartSizeLessThan8x8Flag[iMbXy] = true;
pCurDqLayer->pTransformSize8x8Flag[iMbXy] = false;
pCurDqLayer->pInterPredictionDoneFlag[iMbXy] = 0;
pCurDqLayer->pResidualPredFlag[iMbXy] = pSlice->sSliceHeaderExt.bDefaultResidualPredFlag;
GetNeighborAvailMbType (&sNeighAvail, pCurDqLayer);
WELS_READ_VERIFY (ParseMBTypeISliceCabac (pCtx, &sNeighAvail, uiMbType)); //解析mb类型
if (uiMbType > 25) { //非法的mb类型
return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_MB_TYPE);
} else if (!pCtx->pSps->uiChromaFormatIdc && ((uiMbType >= 5 && uiMbType <= 12) || (uiMbType >= 17
&& uiMbType <= 24))) { //如果没有色度信息,这里mb类型不合法的类型判断
return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_MB_TYPE);
} else if (25 == uiMbType) { //I_PCM
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "I_PCM mode exists in I slice!");
WELS_READ_VERIFY (ParseIPCMInfoCabac (pCtx)); //解析PCM 信息,cabac
pSlice->iLastDeltaQp = 0;
WELS_READ_VERIFY (ParseEndOfSliceCabac (pCtx, uiEosFlag));
if (uiEosFlag) {
RestoreCabacDecEngineToBS (pCtx->pCabacDecEngine, pCtx->pCurDqLayer->pBitStringAux);
}
return ERR_NONE;
} else if (0 == uiMbType) { //I4x4 16个4x4的帧内块
ENFORCE_STACK_ALIGN_1D (int8_t, pIntraPredMode, 48, 16);
pCurDqLayer->pDec->pMbType[iMbXy] = MB_TYPE_INTRA4x4;
相关文章:
openh264解码h264视频帧主流程
一 解析一帧的入口int32_t WelsDecodeSlice (PWelsDecoderContext pCtx, bool bFirstSliceInLayer, PNalUnit pNalCur) {// 解码slicePDqLayer pCurDqLayer pCtx->pCurDqLayer;PFmo pFmo pCtx->pFmo;int32_t iRet;int32_t iNextMbXyIndex, iSliceIdc;PSlice pSlice &a…...
【个人笔记】C语言位域
一句话解释位域:指定结构体内变量的的位宽,从而节省空间 例子: #include <stdio.h> struct _test {int bit1:3; // 第一个字节0 ~ 2位 int :0; // 空域:表示第一个字节 3~7都为0int bit2:1; // 第二个字节第0位int :3;…...
ROS笔记(1)——ROS的核心概念
目录 节点与管理器 话题通信 服务通信 参数——全局共享字典 节点与管理器 节点——执行单元 (1)执行具体任务的进程、独立运行的可执行文件 (2)不同节点可使用不同的编程语言,可分布式运行在不同的主机 ÿ…...

动态SQL使用【JavaEE】
动态SQL使用 1. if 标签 判断一个参数是否有值,如果没值,那么就会隐藏 if 中的 sql 语法: <if test"username!null">username#{username} </if>表达式:username 的参数是否为空 如果结果为 true,…...
leetcode刷题
1、stack栈相关 top():返回一个栈顶元素的引用,类型为 T&。如果栈为空,返回值未定义。 push(const T& obj):可以将对象副本压入栈顶。这是通过调用底层容器的 push_back() 函数完成的。 push(T&& obj)࿱…...

移动设备安全管理基础指南
什么是移动安全管理 (MSM) 移动安全管理是指为保护企业中的移动设备和企业数据而采取的行动。这些操作可以进一步被归类为反应性的或主动的,基于该操作是在数据和设备被破坏之前还是之后执行的。除了管理移动设备外,大多数MDM解决…...

【Java|多线程与高并发】 使用Thread 类创建线程的5种方法如何查看程序中的线程
文章目录前言线程创建1.继承Thread类重写run()方法如何查看程序中的线程?2.实现Runnable接口3.使用匿名内部类,继承Thread4.使用匿名内部类,实现Runnable5.⭐使用Lambda表达式,创建线程(重要)Thread 的常见构造方法总结前言 在这里主要补充说明一些问题,方便更好地理解下面的…...

零基础学MySQL(五)-- 详细讲解数据库中的常用函数
目录🎇一、聚合函数1️⃣count 函数(1)基本语法(2)基本练习(3)注意细节2️⃣sum 函数(1)基本语法(2)基本练习(3)注意细节3…...

第4章 流程控制-if-else,Switch,For循环(循环守卫,循环步长,倒叙打印),While循环,多重循环...
第 4 章 流程控制-if-else,Switch,For循环(循环守卫,循环步长,倒叙打印),While循环,多重循环 4.1 分支控制 if-else 让程序有选择的的执行,分支控制有三种:单分支、双分支、多分支 4.1.1 单分支 1)基本语法…...

2.4G-WiFi连接路由器过程
一、概述 WiFi的数据通信基于802.11协议进行,无线AP在工作时会定时向空中发送beacon数据包,基站(STA)从beacon中解析出AP的名称、加密方式等信息,从而发起连接。 二、WiFi连接路由器的详细过程 WiFi连接过程主要可以…...

3. SpringMVC Rest 风格
1. REST 简介 REST(Representational State Transfer),表现形式状态转换,它是一种软件架构风格。 当要表示一个网络资源的时候,可以使用两种方式: 传统风格资源描述形式 http://localhost/user/getById?…...
Python3简介
Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色语法结构。 Python 是面向对象语言: 这意味着P…...

如何学习PMP?
★基础要打牢 方法:“基础不牢,地动山摇”,如果基础不牢那么就很难拿高分,因为连最基础的题目分都不一定能拿到。 可以在针对基础知识,把PMBOK看一两遍,再次加深印象,再把平时做章节练习、每日5…...

【DSP视频教程】第11期:插补算法,曲线拟合丝滑顺畅,统计函数和基础函数加速实现,汇集SIMD,饱和和MAC乘累加应用实战(2023-02-12)
视频教程汇总帖:https://www.armbbs.cn/forum.php?modviewthread&tid110519 DSP视频教程有段时间没有更新了。 当前DSP库从CMSIS软件包里面独立出来,并且更新非常频繁,所以本期视频教程优先给大家简单介绍下新版DSP, 然后为…...

分类模型评估:混淆矩阵、准确率、召回率、ROC
1. 混淆矩阵 在二分类问题中,混淆矩阵被用来度量模型的准确率。因为在二分类问题中单一样本的预测结果只有Yes or No,即:真或者假两种结果,所以全体样本的经二分类模型处理后,处理结果不外乎四种情况,每种…...

算法 ——世界 一
个人简介:云计算网络运维专业人员,了解运维知识,掌握TCP/IP协议,每天分享网络运维知识与技能。个人爱好: 编程,打篮球,计算机知识个人名言:海不辞水,故能成其大;山不辞石…...

2023年3月AMA-CDGA/CDGP数据治理认证考试这些城市可以报名
目前2023年3月5日CDGA&CDGP开放报名的城市有:北京、上海、广州、深圳、杭州、重庆,西安,成都,长沙,济南,更多考场正在增加中… DAMA认证为数据管理专业人士提供职业目标晋升规划,彰显了职业…...

Java变量和数据类型,超详细整理,适合新手入门
目录 一、什么是变量? 二、变量 变量值互换 三、基本数据类型 1、八种基本数据类型 2、布尔值 3、字符串 四、从控制台输入 一、什么是变量? 变量是一种存储值的容器,它可以在程序的不同部分之间共享;变量可以存储数字、字…...

Echarts 设置折线图拐点的颜色,边框等样式,hover时改变颜色
第014个点击查看专栏目录上一篇文章我们讲到了如何设置拐点大小,图形类型,旋转角度,缩放同比,位置偏移等,这篇文章介绍如何设置拐点的颜色、边框大小颜色等样式。hover轴线时候,拐点的填充颜色改变文章目录示例效果示例…...
做 SQL 性能优化真是让人干瞪眼
很多大数据计算都是用SQL实现的,跑得慢时就要去优化SQL,但常常碰到让人干瞪眼的情况。 比如,存储过程中有三条大概形如这样的语句执行得很慢: select a,b,sum(x) from T group by a,b where …; select c,d,max(y) from T grou…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...

Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...