0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用NVIDIA VPI降低图像的时间噪声

星星科技指导员 来源:NVIDIA 作者:NVIDIA 2022-04-27 10:37 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

在本文中,我们将向您展示如何在 Jetson 产品系列上运行时间降噪( TNR )示例应用程序。

在 Jetson 设备上设置 VPI

通过 SDK 管理器设置 Jetson 设备时,请确保选中 Jetson SDK 组件框。然后在设备闪存时安装 VPI 。

安装完成后,可以在以下路径下找到 VPI :

/opt/nvidia/vpi1/

要验证环境设置是否正确,请将 VPI 示例应用程序复制到主目录中,然后构建 TNR 示例。

$ vpi1_install_samples.sh $HOME
$ cd $HOME/NVIDIA_VPI–samples/09-tnr
$ cmake .
$ make

VPI 在运行离散 GPU 的 x86 机器上也受支持。有关更多信息,请参阅 VPI – Vision 编程接口文档中的 Installation 。

TNR 示例应用程序

VPI 提供了一组 CV 算法,这些算法利用多个后端高效地使用设备的可用计算资源。 TNR 是在 Jetson 设备上运行的计算机视觉应用程序中常用的一种降噪方法。本文使用 TNR 示例应用程序来演示如何使用 VPI 中的一些关键概念和组件来实现自己的应用程序。

我们将在本帖中介绍以下主题:

创建构建 VPI 管道所需的元素

了解如何与 OpenCV 进行互操作

向流提交处理任务

同步流中的任务

锁定图像缓冲区以便可以从 CPU 访问

TNR 样本可在以下路径中找到:

$HOME/NVIDIA_VPI–samples/09-tnr/main.cpp

有关示例应用程序和算法的更多信息,请参阅以下参考资料:

时间降噪示例应用程序

时域降噪算法

算法版本和后端支持

硬件引擎在 VPI 中被命名为 backends 。通过使用 Jetson 设备固有的可用系统级并行性,这些后端使您能够卸载可并行处理阶段并加速应用程序。后端是 CPU 、 CUDA ( GPU )、 PVA 和 VIC 。特定后端引擎的确切可用性取决于应用程序部署到的 Jetson 平台。有关特定平台上可用算法、后端支持和后端可用性的更多信息,请参阅 Algorithms 。

VPI 目前为 TNR 提供了两种不同的实现,每种实现都适合不同的场景和需求。这些版本采用双边滤波平滑平坦区域,同时保留边缘,和时间无限脉冲响应( IIR )滤波与运动检测器的结合,以处理跨帧的时间噪声。

VPI_TNR_V2 – 与 VPI_TNR_V3 相比,该版本提供了更轻的噪音降低,并且具有一定程度的可配置性,即可以调整照明条件以更好地适应给定场景。这个版本有一个减少的计算需求,这转化为速度。它适用于执行时间比降噪质量更重要的用例。

VPI_TNR_V3 —用于需要更好质量的降噪的用例。与 VPI_TNR_V2 相比,使用这个变体,您应该期望计算需求会增加。除此之外,还进一步扩展了可配置性。建议用于具有挑战性的弱光场景。

VPI_TNR_DEFAULT – 您可以使用默认值,而不是指定确切的版本,该值选择给定后端支持的噪声抑制最强的版本。

在决定哪个算法版本适合您的用例时,需要考虑的另一个标准是它对不同后端和设备的支持。下表总结了 TNR 支持。

VPI_TNR_V2 和 VPI_TNR_V3 都允许显式设置要捕获的场景的照明条件,从而启用调整。这在低光场景或以高增益捕获的流的上下文中是重要的,所述低光场景或流可能包含更高的噪声级,并且因此要求更高的噪声降低水平。

较高的强度级别可能会影响帧的纹理区域中的细节数量,从而使其平滑。另一个副作用是在有快速移动物体的场景中重影。支持的场景照明条件在类型(室内、室外)和强度(低、中、高)方面有所不同,如下表所示。

使用不同的版本和相关的照明条件预设,您可以根据用例的具体情况调整 TNR 算法。这可以通过所谓的强度系数进一步定制。它是一个浮动参数,范围从 0 到 1 ,其中较大的值对应于增加的去噪强度。

VPI 应用程序

VPI 的一个关键方面是如何管理和协调在不同后端之间运行应用程序所需的资源。使用 VPI ,可以避免在处理阶段之间浪费内存拷贝。 VPI 为实现高效的内存管理而实施的另一种机制是在其接口处进行内存包装。

利用 VPI 的所有内存管理特性取决于代码的结构。最佳实践是将代码视为三阶段工作流:

Initialization

处理回路

Cleanup

大部分内存分配应该在初始化阶段进行。对于在可用资源受限的设备上运行的嵌入式应用程序,这一点尤为重要。除此之外,还可以更有效、更谨慎地进行内存管理,以避免可能的内存泄漏。

VPI 中的一个好做法是指定使用内存的后端。在这点上,只将 VPI 对象订阅到所需的后端集可以保证在管道在这些后端之间流动时获得最有效的内存路径。

处理循环是执行处理管道的地方。想象一下,一个应用程序在一个包含数百个单独帧的视频文件上迭代。主循环将主要负责对像素信息执行所需的变换,以实现给定计算机视觉任务的预期结果。

最后,清理阶段处理在任务执行期间使用的资源的所有必要释放和释放。坚持这种模式可以使 VPI 尽可能使用最有效的处理管道,并帮助您坚持良好的编码实践。

与 OpenCV 接口

VPI 与 OpenCV 的互操作性是该库的一个显著特征。如果您熟悉 OpenCV ,您可以轻松地将 VPI 与工作流集成,或者扩展现有的数据管道,以便更好地使用 VPI 提供的硬件加速。

TNR 示例中通过以下实用函数演示了这一点,该函数将使用 OpenCV 捕获的输入视频帧包装到 VPI 图像对象中。

 69 // Utility function to wrap a cv::Mat into a VPIImage
 70 static VPIImage ToVPIImage(VPIImage image, const cv::Mat &frame)
 71 {
 72 if (image == nullptr)
 73 {
 74 // Create a VPIImage that wraps the frame
 75 CHECK_STATUS(vpiImageCreateOpenCVMatWrapper(frame, 0, &image));
 76 }
 77 else
 78 {
 79 // reuse existing VPIImage wrapper to wrap the new frame.
 80 CHECK_STATUS(vpiImageSetWrappedOpenCVMat(image, frame));
 81 }
 82 return image;
 83 }

从更深入地研究前面描述的函数开始。它意味着将 OpenCV 矩阵( cv::Mat )对象包装到 VPI 图像对象( VPIImage )。要上下文化, VPI 图像基本上是任何可以用宽度、高度和格式来描述的 2D 数据结构。尽管将图像数据视为 VPIImage 对象是直观的,但它的用法也可以扩展到其他类型的数据,例如二维向量场和热图。

The utility wrapping function invokes two other functions that pertain to the VPI OpenCVInterop.hpp module, which aims to provide useful infrastructure to integrate OpenCV-based code with VPI.

vpiImageCreateOpenCVMatWrapper —一个重载函数,它以两种不同的方式将 cv:Mat 对象包装到 VPIImage 中。第一种方法尝试直接从输入类型推断格式(遵循特定的规则),而第二种方法将显式格式作为其参数之一。

vpiImageSetWrappedOpenCVMat – 重用为特定 cv::Mat 对象定义的包装器来包装新的传入 cv::Mat 对象。这里的重点是避免在第一时间创建包装时产生的内存分配,这样效率更高。传入的 cv::Mat 对象必须呈现与创建时使用的原始对象相同的特征(格式和尺寸)。

流创建

main 函数捕获设置 VPI 管道以完成工作的相关步骤。管道的定义很简单,也很直观。在 VPI 中,管道是一个或多个数据流的组合,这些数据流流经不同的处理阶段。

图 1 以一种通用的方式显示了管道及其构建块(流、缓冲区、算法等)。为了简单起见,省略了一些组件。

图 1 通用 VPI 管道。

流的目的是强制执行一个排队的步骤序列,数据需要通过该序列来完成特定的计算机视觉任务。这些步骤可能包括数据的预处理或后处理,甚至包括 TNR 之类的成熟算法。图 2 显示了 VPIStream 对象的示例。

图 2 VPIStream 对象。

VPI 可适应各种不同的管道复杂性。您可以用一个流实现一个简单的管道,或者用几个不同阶段的并行流实现一个更复杂的实现,并将这些并行流卸载到不同的计算后端。这是 API 的一个强大功能,因为它使您能够获得对 Jetson 设备提供的系统级并行性的更多控制。

下面的代码示例演示如何在 TNR 示例中创建流。

143 VPIStream stream;
144 // PVA backend doesn't have currently Convert Image Format algorithm.
145 // Use the CUDA backend to do that.
146 CHECK_STATUS(vpiStreamCreate(VPI_BACKEND_CUDA | backend, &stream));

选择的后端正在传递到流中。这是一个可选步骤。使用零值将启用所有可用的后端。但是,分配一组特定的后端是推荐的做法,因为它有助于优化内存分配。

TNR 有效载荷

有效负载基本上是管道执行期间所需的临时资源。例如,有效负载可以是中间内存缓冲区,用于存储流的后续阶段之间交换的数据。包括 TNR 在内的许多算法都需要显式地创建有效负载,具体实现如下。

172 // Create a TNR payload configured to process NV12
173 // frames under outdoor low-light scenarios.
174 VPIPayload tnr;
175 CHECK_STATUS(vpiCreateTemporalNoiseReduction(backend, w, h, VPI_IMAGE_FORMAT_NV12_ER, VPI_TNR_DEFAULT,
176 VPI_TNR_PRESET_INDOOR_LOW_LIGHT, 1, &tnr));

对于 TNR 有效负载,请提供以下参数:

图像尺寸(宽度和高度)

Backend

图像数据格式(目前仅支持 NV12 )

TNR 算法版本

照明条件

降噪强度

对算法有效负载的引用

最终,该函数创建一个有效负载并将其绑定到指定的后端。

图像缓冲区

除了创建流和有效负载外,还必须创建 VPI 算法所需的图像缓冲区。在 TNR 中,使用双边和 IIR 滤波器的组合,因此需要三个不同的缓冲器,即当前和先前的图像输入和图像输出。

可以按如下方式创建图像缓冲区:

167 VPIImage imgPrevious, imgCurrent, imgOutput;
168 CHECK_STATUS(vpiImageCreate(w, h,VPI_IMAGE_FORMAT_NV12_ER, 0, &imgPrevious));
169 CHECK_STATUS(vpiImageCreate(w, h,VPI_IMAGE_FORMAT_NV12_ER, 0, &imgCurrent));
170 CHECK_STATUS(vpiImageCreate(w, h,VPI_IMAGE_FORMAT_NV12_ER, 0, &imgOutput));

这将创建具有以下指定特征的空缓冲区:

图像尺寸(宽度和高度)

格式(根据算法要求)

图像标志(当前用于分配后端)

指向返回所创建映像的 VPIImage 句柄的变量的指针

流处理

在构建块已经就位的情况下,您可以转到主处理循环,在那里执行降噪算法。在 TNR 样本上,循环迭代来自视频文件的每个单独帧,并执行必要的连续步骤以获得所需的结果。

当从视频中收集帧时,第一步是使用前面描述的实用程序函数将其包装成 VPIImage 对象。

186 frameBGR = ToVPIImage(frameBGR, cvFrame);

包装完成后, VPI 现在可以对 VPIImage 对象中的像素数据进行操作。因为 TNR 要求帧是 NV12 格式,所以需要一个转换步骤。

188 // First convert it to NV12
189 CHECK_STATUS(vpiSubmitConvertImageFormat(stream,VPI_BACKEND_CUDA, frameBGR, imgCurrent, NULL));

在此阶段,转换图像的特定任务与先前实例化的流相关联。除此之外,任务被设置为在 GPU 上执行。输入帧的图像缓冲区以及刚刚从cv::Mat对象包装的数据都用于此目的。

格式转换完成后,可以将输入缓冲区传递给 TNR 算法进行处理。

191 // Apply TNR
192 // For first frame, you must pass nullptr as the previous frame, this resets the internal
193 // state.
194 CHECK_STATUS(vpiSubmitTemporalNoiseReduction(stream, 0, tnr, curFrame == 1 ? nullptr : imgPrevious,
195 imgCurrent, imgOutput));
196

要调用 TNR 算法,请设置以下参数:

  • 与算法关联的流
  • 后端
  • 算法有效负载,如前面实例化的一样
  • 图像缓冲区:以前和当前的输入和输出

在第一次迭代(curFrame == 1)时,缓冲区上没有有效的前一个映像,而是传递一个空指针。对于下面的迭代,缓冲区将相应地填充。在执行 TNR 算法之后,输出缓冲区可以从 NV12 转换回以前的 BGR 格式。

197 // Convert output back to BGR
198 CHECK_STATUS(vpiSubmitConvertImageFormat(stream,VPI_BACKEND_CUDA, imgOutput, frameBGR, NULL));

在这一点上,必须提到 VPI 对流阶段实施了非阻塞异步范例。这对于作为后端分布在不同协处理器之间的工作负载的平滑和高效的编排是必不可少的。对于进一步的步骤,请确保在继续之前已完成向流发出的所有活动。这时同步功能就派上用场了。

199 CHECK_STATUS(vpiStreamSync(stream));

VPI 现在确保与流相关的所有正在进行的活动在进入管道的下一个阶段之前都已完成。同步完成后,帧就可以在连接到指定后端的输出缓冲区中使用了。为了能够将其写入输出视频流(在这种情况下是一个文件),必须锁定图像,以便 CPU 可以使用缓冲区。

这就解释了为什么在锁定帧之前进行同步是避免处理问题的关键步骤。因为 VPI 是异步操作的,所以在没有同步的情况下,缓冲区会在前一阶段完成之前被锁定。结果是不可预测的。

201 // Now add it to the output video stream
202 VPIImageData imgdata;
203 CHECK_STATUS(vpiImageLock(frameBGR,VPI_LOCK_READ, &imgdata));
204
205 cv::Mat outFrame;
206 CHECK_STATUS(vpiImageDataExportOpenCVMat(imgdata, &outFrame));
207 outVideo << outFrame;
 208
 209             CHECK_STATUS(vpiImageUnlock(frameBGR));

如您所见,锁定的缓冲区由 CPU 处理,以供进一步使用。锁被设置为只读,然后图像缓冲区被映射到 CPU 。锁定时, VPI 无法在缓冲区上工作。在 CPU 将输出帧提供给视频编码器后,缓冲区可以被解锁并被 VPI 进一步使用。

VPI 数据流

TNR 示例应用程序可以概括为以下数据流。其他的小步骤也是应用程序不可分割的一部分,但是为了简单起见,图 3 中只包含了宏步骤。

图 3 TNR 示例应用程序中的数据流。

从视频流或文件中收集输入帧。 OpenCV 已用于此目的。

必要的 VPI 元素被实例化:单个流、 TNR 算法负载以及用于先前和当前输入和输出图像的图像缓冲区。

输入帧被包装到 VPIImage 缓冲区中。

缓冲区上的像素数据被转换成 NV12 ,以便 TNR 算法可以处理它。当算法完成执行时,它会恢复到原始格式。

图像缓冲区被锁定,以便 CPU 可以访问数据。将图像提供给视频输出后,可以解锁缓冲区, VPI 可以进一步处理它。

概括

在本文中,我们向您展示了如何在 Jetson 产品系列上运行 TNR 示例应用程序。

关于作者

Maycon da Silva Carvalho 是 Jetson 的现场应用工程师。他负责与部署基于 Jetson 的应用程序的不同行业的客户进行多学科技术合作。

Rodolfo Schulz de Lima 是 VPI 的首席工程师。他拥有 UFRJ 里约热内卢联邦大学电子工程学士学位,并在巴西里约热内卢的 IMPA (纯数学和应用数学研究所)学习计算机图形学。

审核编辑:郭婷

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5209

    文章

    20645

    浏览量

    336910
  • gpu
    gpu
    +关注

    关注

    28

    文章

    5271

    浏览量

    136059
  • SDK
    SDK
    +关注

    关注

    3

    文章

    1111

    浏览量

    52003
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Sony FCB-ES8230 低噪声图像系统中的线束优化

    Sony FCB-ES8230低噪声图像系统设计中,线束不仅是“连接工具”,更是影响信号质量与系统稳定性的关键环节。通过合理选用与优化极细同轴线束(micro coaxial cable),可以在源头上降低干扰、提升信号完整性,
    的头像 发表于 03-29 18:12 155次阅读
    Sony FCB-ES8230 低<b class='flag-5'>噪声</b><b class='flag-5'>图像</b>系统中的线束优化

    NVIDIA cuDF和cuVS获全球领先数据平台采用

    企业每年产生数百 ZB (Zettabyte) 的数据,并在争相将这些信息转化为洞察。NVIDIA cuDF 和 cuVS 作为基于 NVIDIA CUDA-X 构建的加速数据库,正在被各行业的数据平台所应用,带来至高 5 倍性能提升的同时,可
    的头像 发表于 03-19 15:46 437次阅读

    使用LDO的VIOC特性降低输出噪声并提高热效率

    降低干扰,增强信号完整性。LDO与电压输入至输出控制(VIOC)功能及兼容的开关稳压器配合使用时,可形成一个始终维持最佳输入输出电压差的系统。这种设计不仅能显著降低噪声,实现高电源电压抑制比(PSRR),还能确保系统高效运行、受到保护且具备强大性能。
    的头像 发表于 02-03 08:14 1.2w次阅读
    使用LDO的VIOC特性<b class='flag-5'>降低</b>输出<b class='flag-5'>噪声</b>并提高热效率

    NVIDIA在CES 2026发布新一代Rubin AI平台

    通过跨 NVIDIA Vera CPU、Rubin GPU、NVLink 6 交换机、ConnectX-9 SuperNIC、BlueField-4 DPU 和 Spectrum-6 以太网交换机的极致协同设计,大幅缩短训练时间降低
    的头像 发表于 01-09 10:23 795次阅读

    超擎数智为您深度解析NVIDIA Quantum-X800 InfiniBand平台

    NVIDIA
    专精特新
    发布于 :2026年01月08日 19:47:03

    降低LDO功耗延长运行时间

    能有效帮助LDO提升散热能力。降低功耗是现在各种电源芯片都重点设计的一个环节,降低静态电流是行之有效的一个办法,但前提是静态电流的降低不会降低整体设备的系统性能。LDO如果能提供低的待
    发表于 01-08 07:13

    基于FPGA的CLAHE图像增强算法设计

    CLAHE图像增强算法又称为对比度有限的自适应直方图均衡算法,其算法原理是通过有限的调整图像局部对比度来增强有效信号和抑制噪声信号。
    的头像 发表于 10-15 10:14 793次阅读
    基于FPGA的CLAHE<b class='flag-5'>图像</b>增强算法设计

    物流机器人“货架识别”错误:图像传感器供电电容噪声抑制

    本文通过分析贴片电容在物流机器人图像传感器供电电路中的噪声抑制作用,探讨其如何解决货架识别错误问题并拓展至冷链、医疗及新零售等跨界场景,体现平尚科技元件的技术适配性与稳定性。
    的头像 发表于 10-09 17:01 730次阅读
    物流机器人“货架识别”错误:<b class='flag-5'>图像</b>传感器供电电容<b class='flag-5'>噪声</b>抑制

    如何降低视频占用空间?

    我发现不同分辨率图像保存的视频大小接近,1分钟的视频都是30MB,如下图 我最终目的是希望保存视频占用空间小一点,同时我也没有找到降低帧率的方法,目前只能使用默认的30帧
    发表于 08-14 06:25

    O-CS8系列表贴式(SMD)超高稳、超低相位噪声SC-cut OCXO

    提供稳定时钟,降低图像伪影,提升空间分辨率至0.5 mm³,助力精准医疗。l 粒子加速器:在同步辐射光源中,保障束流轨道稳定性,支持纳秒级时间分辨实验,推动材料科学与生命科学前沿研究。
    发表于 08-12 09:46

    降低adc在不同PCB上的噪声,如何做到接近AD4134验证板噪声水平?

    在我设计的复杂多片AD4134的大型数字系统中,噪声水平Nrms无法控制到预期水平。希望能够找到关键的影响因素。还请各位大师指点。 根据验证版及数据手册中的布局方式,不对ADC的下方地平面做切割处理
    发表于 08-11 08:24

    NVIDIA RTX AI加速FLUX.1 Kontext现已开放下载

    NVIDIA RTX 与 NVIDIA TensorRT 现已加速 Black Forest Labs 的最新图像生成和编辑模型;此外,Gemma 3n 现可借助 RTX 和 NVIDIA
    的头像 发表于 07-16 09:16 2174次阅读

    全新NVIDIA AI Blueprint精准检测信用卡交易欺诈

    这个由 NVIDIA AI 平台驱动的蓝图可帮助金融服务机构节省资金并降低风险。
    的头像 发表于 07-15 11:29 1344次阅读

    NVIDIA Isaac Sim与NVIDIA Isaac Lab的更新

    在 COMPUTEX 2025 上,NVIDIA 宣布了机器人仿真参考应用 NVIDIA Isaac Sim 和机器人学习框架 NVIDIA Isaac Lab 的更新,以加速各种形态机器人的开发。
    的头像 发表于 05-28 10:06 2386次阅读

    思特威SC301HIOT物联网3MP高性能图像传感器 搭载SmartAOV™和超低噪声外围读取电路

    思特威SC301HIOT物联网3MP高性能图像传感器 搭载SmartAOV™和超低噪声外围读取电路
    的头像 发表于 05-14 16:04 1198次阅读
    思特威SC301HIOT物联网3MP高性能<b class='flag-5'>图像</b>传感器 搭载SmartAOV™和超低<b class='flag-5'>噪声</b>外围读取电路