openh264 降噪功能源码分析

news2024/11/20 1:48:07

文件位置

openh264/codec/processing/denoise/denoise.cpp
openh264/codec/processing/denoise/denoise_filter.cpp

代码流程

在这里插入图片描述

  • 说明:从代码流程可以看到,实现降噪的核心功能主要就是BilateralDenoiseLumaWaverageDenoiseChroma两个函数。

原理

  • 参数开关控制:(bool) bEnableDenoise

BilateralDenoiseLuma函数

  1. 功能:实现图像亮度分量的双边滤波降噪
  2. 过程
  • 将亮度指针pSrcY向前移动m_uiSpaceRadius行,跳过图像边缘的噪声处理区域;
  • 外层循环遍历图像的高度,从m_uiSpaceRadius开始,到iHeight - m_uiSpaceRadius,跳过边缘区域;
    • 内层循环遍历图像的宽度,从m_uiSpaceRadius开始,每次增加8(为了利用SIMD指令集进行优化),直到iWidth - m_uiSpaceRadius - TAIL_OF_LINE8;
      • 对当前8个像素块使用双边滤波器pfBilateralLumaFilter8函数(指向具体的BilateralLumaFilter8_c函数)进行去噪;
    • for 循环处理剩余的像素,这些像素不能被8整除,因此需要单独处理;
      • 调用Gauss3x3Filter函数对单个像素使用高斯滤波器进行去噪;
    • 将指针pSrcY向下移动一行,准备处理下一行的数据;
  1. 原理图
    在这里插入图片描述
  2. 相关源码
  • BilateralDenoiseLuma函数
void CDenoiser::BilateralDenoiseLuma (uint8_t* pSrcY, int32_t iWidth, int32_t iHeight, int32_t iStride) {
  int32_t w;

  pSrcY = pSrcY + m_uiSpaceRadius * iStride;
  for (int32_t h = m_uiSpaceRadius; h < iHeight - m_uiSpaceRadius; h++) {
    for (w = m_uiSpaceRadius; w < iWidth - m_uiSpaceRadius - TAIL_OF_LINE8; w += 8) {
      m_pfDenoise.pfBilateralLumaFilter8 (pSrcY + w, iStride);
    }
    for (; w < iWidth - m_uiSpaceRadius; w++) {
      Gauss3x3Filter (pSrcY + w, iStride);
    }
    pSrcY += iStride;
  }
}
  • pfBilateralLumaFilter8函数(指向具体的BilateralLumaFilter8_c函数)
void BilateralLumaFilter8_c (uint8_t* pSample, int32_t iStride) {
  int32_t nSum = 0, nTotWeight = 0;
  int32_t iCenterSample = *pSample;
  uint8_t* pCurLine = pSample - iStride - DENOISE_GRAY_RADIUS;
  int32_t x, y;
  int32_t iCurSample, iCurWeight, iGreyDiff;
  uint8_t aSample[8];

  for (int32_t i = 0; i < 8; i++) {
    nSum = 0;
    nTotWeight = 0;
    iCenterSample = *pSample;
    pCurLine = pSample - iStride - DENOISE_GRAY_RADIUS;
    for (y = 0; y < 3; y++) {
      for (x = 0; x < 3; x++) {
        if (x == 1 && y == 1) continue; // except center point
        iCurSample = pCurLine[x];
        iCurWeight = WELS_ABS (iCurSample - iCenterSample);
        iGreyDiff = 32 - iCurWeight;
        if (iGreyDiff < 0) continue;
        else iCurWeight = (iGreyDiff * iGreyDiff) >> 5;
        nSum += iCurSample * iCurWeight;
        nTotWeight +=  iCurWeight;
      }
      pCurLine += iStride;
    }
    nTotWeight = 256 - nTotWeight;
    nSum += iCenterSample * nTotWeight;
    aSample[i] = nSum >> 8;
    pSample++;
  }
  WelsMemcpy (pSample - 8, aSample, 8);
}
  • Gauss3x3Filter函数
/***************************************************************************
edge of y/uv use a 3x3 Gauss filter, radius = 1:
1   2   1
2   4   2
1   2   1
***************************************************************************/
void Gauss3x3Filter (uint8_t* pSrc, int32_t iStride) {
  int32_t nSum = 0;
  uint8_t* pCurLine1 = pSrc - iStride - 1;
  uint8_t* pCurLine2 = pCurLine1 + iStride;
  uint8_t* pCurLine3 = pCurLine2 + iStride;

  nSum =  pCurLine1[0]       + (pCurLine1[1] << 1) +  pCurLine1[2]       +
         (pCurLine2[0] << 1) + (pCurLine2[1] << 2) + (pCurLine2[2] << 1) +
          pCurLine3[0]       + (pCurLine3[1] << 1) +  pCurLine3[2];
  *pSrc = nSum >> 4;
}

WaverageDenoiseChroma函数

  1. 功能:实现图像色度分量的降噪功能
  2. 过程
  • 将指针pSrcUV向前移动UV_WINDOWS_RADIUS行,跳过图像边缘的噪声处理区域;
  • 外层循环遍历图像的高度,从UV_WINDOWS_RADIUS开始,到iHeight - UV_WINDOWS_RADIUS,跳过边缘区域;
    • 内层循环遍历图像的宽度,从UV_WINDOWS_RADIUS开始,每次增加8(为了利用SIMD指令集进行优化),直到iWidth - UV_WINDOWS_RADIUS - TAIL_OF_LINE8,用于确保在处理行尾时不会超出边界;
      • 对当前8个像素块使用加权平均滤波器pfWaverageChromaFilter8函数(指向WaverageChromaFilter8_c函数)进行去噪;
    • 调用Gauss3x3Filter函数处理剩余的像素,这些像素不能被8整除,因此需要单独处理;
    • 将指针pSrcUV向下移动一行,准备处理下一行的数据。
  1. 原理图
    在这里插入图片描述
  2. 相关源码
  • WaverageDenoiseChroma函数
void CDenoiser::WaverageDenoiseChroma (uint8_t* pSrcUV, int32_t iWidth, int32_t iHeight, int32_t iStride) {
  int32_t w;

  pSrcUV = pSrcUV + UV_WINDOWS_RADIUS * iStride;
  for (int32_t h = UV_WINDOWS_RADIUS; h < iHeight - UV_WINDOWS_RADIUS; h++) {
    for (w = UV_WINDOWS_RADIUS; w < iWidth - UV_WINDOWS_RADIUS - TAIL_OF_LINE8; w += 8) {
      m_pfDenoise.pfWaverageChromaFilter8 (pSrcUV + w, iStride);
    }

    for (; w < iWidth - UV_WINDOWS_RADIUS; w++) {
      Gauss3x3Filter (pSrcUV + w, iStride);
    }
    pSrcUV += iStride;
  }
}
  • WaverageChromaFilter8_c函数
/***************************************************************************
5x5 filter:
1   1   2   1   1
1   2   4   2   1
2   4   20  4   2
1   2   4   2   1
1   1   2   1   1
***************************************************************************/
#define SUM_LINE1(pSample)       (pSample[0]     +(pSample[1])    +(pSample[2]<<1)  + pSample[3]     + pSample[4])
#define SUM_LINE2(pSample)       (pSample[0]     +(pSample[1]<<1) +(pSample[2]<<2)  +(pSample[3]<<1) + pSample[4])
#define SUM_LINE3(pSample)      ((pSample[0]<<1) +(pSample[1]<<2) +(pSample[2]*20)  +(pSample[3]<<2) +(pSample[4]<<1))
void WaverageChromaFilter8_c (uint8_t* pSample, int32_t iStride) {
  int32_t sum;
  uint8_t* pStartPixels = pSample - UV_WINDOWS_RADIUS * iStride - UV_WINDOWS_RADIUS;
  uint8_t* pCurLine1 = pStartPixels;
  uint8_t* pCurLine2 = pCurLine1 + iStride;
  uint8_t* pCurLine3 = pCurLine2 + iStride;
  uint8_t* pCurLine4 = pCurLine3 + iStride;
  uint8_t* pCurLine5 = pCurLine4 + iStride;
  uint8_t aSample[8];

  for (int32_t i = 0; i < 8; i++) {
    sum = SUM_LINE1 ((pCurLine1 + i)) + SUM_LINE2 ((pCurLine2 + i)) + SUM_LINE3 ((pCurLine3 + i))
          + SUM_LINE2 ((pCurLine4 + i)) + SUM_LINE1 ((pCurLine5 + i));
    aSample[i] = (sum >> 6);
    pSample++;
  }
  WelsMemcpy (pSample - 8, aSample, 8);
}
  • Gauss3x3Filter 函数
/***************************************************************************
edge of y/uv use a 3x3 Gauss filter, radius = 1:
1   2   1
2   4   2
1   2   1
***************************************************************************/
void Gauss3x3Filter (uint8_t* pSrc, int32_t iStride) {
  int32_t nSum = 0;
  uint8_t* pCurLine1 = pSrc - iStride - 1;
  uint8_t* pCurLine2 = pCurLine1 + iStride;
  uint8_t* pCurLine3 = pCurLine2 + iStride;

  nSum =  pCurLine1[0]       + (pCurLine1[1] << 1) +  pCurLine1[2]       +
         (pCurLine2[0] << 1) + (pCurLine2[1] << 2) + (pCurLine2[2] << 1) +
          pCurLine3[0]       + (pCurLine3[1] << 1) +  pCurLine3[2];
  *pSrc = nSum >> 4;
}

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

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

相关文章

[word] word大括号怎么打两行 #其他#其他#微信

word大括号怎么打两行 Word给用户提供了用于创建专业而优雅的文档工具&#xff0c;帮助用户节省时间&#xff0c;并得到优雅美观的结果。 一直以来&#xff0c;Microsoft Office Word 都是最流行的文字处理程序。 作为 Office 套件的核心程序&#xff0c; Word 提供了许多易…

ChatGPT-4o提示词的九大酷炫用法,你知道几个?

ChatGPT-4o提示词的九大酷炫用法&#xff0c;你知道几个&#xff1f;&#x1f680; 博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典…

android antirollback verno 获取方法

ReadRollbackIndex.exe 获取 调查avbVBMeta结构体 typedef struct AvbVBMetaImageHeader { /* 0: Four bytes equal to "AVB0" (AVB_MAGIC). */ uint8_t magic[AVB_MAGIC_LEN]; /* 4: The major version of libavb required for this header. */ uint32_t…

rtl8723DU移植 android4.4 4418 (第二部分蓝牙部分)

使用的代码&#xff1a; HMI &#xff08;8723bu&#xff09;源码 567_RTL8723DU_WiFi_linux_v5.6.5.3_35502_COEX20181130-2e2e.20191025.zip 由于之前写的所有笔记没有保存&#xff0c;这里只能是部分。 0、 前置知识 1 、kernel 的移植 2、hardwire的移植 将 驱动中的 h…

大功率回馈式负载:行业竞争态势

随着科技的不断发展&#xff0c;大功率回馈式负载在各个行业中的应用越来越广泛。大功率回馈式负载是一种能够将电能回馈到电网的设备&#xff0c;具有节能、环保、高效等优点。然而&#xff0c;随着市场竞争的加剧&#xff0c;大功率回馈式负载行业也面临着诸多挑战。 首先&am…

QSqlDatabase、QSqlQuery、QSqlRecord、Sqlite用法

使用QSqlDatabase、QSqlQuery、QSqlRecord、Sqlite数据库实现一个简单的界面查询 1. 创建Sqlite数据库&#xff0c;表 mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h" #include "QSqlDatabase" #include "QSqlQuery&q…

AVL树【C++实现】

文章目录 AVL树的概念AVL树节点的定义AVL树的插入AVL树的旋转新节点插入较高右子树的右侧---右右&#xff1a;左单旋新节点插入较高左子树的左侧---左左&#xff1a;右单旋新节点插入较高左子树的右侧---左右&#xff1a;先左单旋再右单旋新节点插入较高右子树的左侧---右左&am…

springboot停车微信小程序小程序-计算机毕业设计源码92714

摘 要 在信息飞速发展的今天&#xff0c;网络已成为人们重要的信息交流平台。每天都有大量的农产品需要通过网络发布&#xff0c;为此&#xff0c;本人开发了一个基于springboot停车微信小程序小程序。 对于本停车微信小程序的设计来说&#xff0c;它主要是采用后台采用java语…

因你而变 共赴新程 | AidLux全新版本震撼发布!

历经400多个日夜&#xff0c;AidLux 2.0&#xff08;基础版&#xff09;终于要与大家见面了。 开发者们问过无数次&#xff0c;新版本何时发布&#xff0c;期待的功能何时上线……在此&#xff0c;让我先真诚地感谢大家长期以来的期待与关心&#xff01; 一年多以来&#xff…

k8s-部署对象存储minio

环境信息 minio版本 :最新 k8s 版本1.22 使用nfs作为共享存储 一.单节点安装包部署 脚本部署&#xff0c;一键部署&#xff0c;单节点应用于数据量小&#xff0c;一些缓存存储&#xff0c;比如gitlab-runner的产物数据&#xff0c;maven的打包依赖数据 #!/bin/bash# 步骤…

019、有序集合_命令

它保留了集合不能有重复,有序集合中的元素可以排序。 但是它和列表使用索引下标作为排序依据不同的是,它给每个元素设置一个分数(score)作为排序的依据。如图 该有序集合包含kris、mike、frank、tim、martin、tom,它们的分数分别是1、91、200、220、250、251,有序集合提…

【C++】STL中List的基本功能的模拟实现

前言&#xff1a;在前面学习了STL中list的使用方法&#xff0c;现在我们就进一步的讲解List的一些基本功能的模拟实现&#xff0c;这一讲博主认为是最近比较难的一个地方&#xff0c;各位一起加油。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; …

紧急通知!Win10将于2025年终止支持,快来升级Win11吧!

近期&#xff0c;微软更新了官方支持页面&#xff0c;我们可以看到微软官方在2025年10月14日之后&#xff0c;不再为 Win10系统提供安全更新或技术支持。到这个时间&#xff0c;Win10用户的电脑仍可正常工作&#xff0c;但建议Win10用户都升级为Win11版本&#xff0c;接下来小编…

分水岭算法分割和霍夫变换识别图像中的硬币

首先解释一下第一种分水岭算法&#xff1a; 一、分水岭算法 分水岭算法是一种基于拓扑学的图像分割技术&#xff0c;广泛应用于图像处理和计算机视觉领域。它将图像视为一个拓扑表面&#xff0c;其中亮度值代表高度。算法的目标是通过模拟雨水从山顶流到山谷的过程&#xff0…

工具-金舟投屏软件: 手机如何投屏到电脑上 / Wi-Fi / USB

金舟安卓/iOS苹果投屏-正版软件下载中心 方法一、金舟投屏软件-wifi 1.1、准备工作 确保苹果手机和Windows电脑都连接到同一个Wi-Fi网络。 在Windows电脑上安装并打开金舟投屏软件。 1.2、操作步骤 在金舟投屏软件上选择“苹果手机投屏”功能。 在苹果手机上下滑屏幕&am…

Parallels Desktop for Mac 19.4.0更新了哪些内容?有什么改进?

带来了重新设计的共享 Mac 文件夹版本&#xff0c;这些文件夹现在是符号链接&#xff0c;像指针一样指向您的 Mac 文件夹中的文件&#xff0c;同时仍然显示在 Windows 的本地磁盘上。 修复了由于共享文件夹问题导致 NinjaTrader 无法正常启动的问题。 修复了由于共享文件夹问…

C++ AVL树 详细讲解

目录 一、AVL树的概念 二、AVL树的实现 1.AVL树节点的定义 2.AVL树的插入 3.AVL树的旋转 4.AVL树的验证 三、AVL树的性能 四、完结撒❀ 一、AVL树的概念 二叉搜索树虽可以缩短查找的效率&#xff0c;但 如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查 …

【多目标跟踪】《FlowMOT: 3D Multi-Object Tracking by Scene Flow Association》论文阅读笔记

0.论文 论文地址链接:https://arxiv.org/pdf/2012.07541v1 通过流的方式跟踪是一个比较新颖的点,所以这里比较关注运动跟踪,是如果做到流的跟踪来预测目标的位置以及ID绑定的。 FlowMOT的框架结构如下所示,本中会主要关注下运动跟踪、数据关联、ID分配、新生/消亡…

python基础实例

下一个更大的数 定义一个Solution类&#xff0c;用于实现next_great方法 class Solution: def next_great(self, nums1, nums2): # 初始化一个空字典answer&#xff0c;用于存储答案 answer {} # 初始化一个空列表stack&#xff0c;用于存储待比较的数字 stack [] # 遍历nu…

香橙派Orange AI Pro / 华为昇腾310芯片 部署自己训练的yolov8模型进行中国象棋识别

香橙派Orange AI Pro / 华为昇腾310芯片 部署自己训练的yolov8模型进行中国象棋识别 一、香橙派简介1.1、香橙派 AI Pro 硬件资源介绍1.2、华为昇腾310&#xff08;Ascend310&#xff09; 简介1.3、 昇腾310AI能力和CANN 简介昇腾310 NPU简介 二、远程环境配置2.1、ssh2.2、vnc…