概述
此算法用于减少视频序列中的空间和时域噪声。噪声水平可能因照明条件、相机传感器的灵敏度和质量等因素而显著变化。VPI 的时域噪声消除更适合处理热噪声和散粒噪声,它们分别服从高斯分布和泊松分布。
目前该算法有 3 个版本,它们在速度、可配置性和质量方面各有不同。并非所有版本都始终在给定的后端和平台组合中可用。
噪声降低因子可以通过两个参数进行自定义:场景照明条件和强度(介于 0 和 1 之间的值)。将场景设置为弱光场景会导致降噪强度增加,但可能会导致高纹理区域的细节丢失,甚至出现一些重影效应。使用明亮光线模式则相反:重影较少,更多细节得到保留,但噪声降低因子降低。
下面的示例展示了时域噪声消除的实际效果。将鼠标指针悬停在视频上,然后单击最大化按钮以查看更多详细信息。
含噪输入 | 参数 | 降噪输出 |
| 场景: 户外中等光线
强度 1.0
版本 3 |
|
- 注意
- 视频输出需要支持 HTML5 且支持 mp4 视频解码的浏览器。
实现
根据所选算法版本,该算法采用不同的技术,例如用于处理空间噪声的双边滤波和/或与运动检测器关联的时域 IIR 滤波器。
算法版本
该算法有 3 个版本,每个版本在速度/可配置性/质量之间进行不同的权衡。
- VPI_TNR_V1 - 提供基本的噪声消除,在噪声水平不太高时效果良好。照明条件和噪声降低强度是固定的,无法配置,但总的来说,它提供了良好的速度。
- VPI_TNR_V2 - 提供改进的噪声消除,并且可以针对特定的照明条件进行配置。仍然提供良好的速度。
- VPI_TNR_V3 - 提供最佳的噪声消除质量和可配置性,但会牺牲一定的性能。
每个版本的可用性取决于后端和设备,请参阅 VPITNRVersion。要选择最佳可用版本,只需在指定算法版本时使用 VPI_TNR_DEFAULT。
场景照明条件
版本 2 和 3 允许用户指定场景的照明条件,这反过来控制特定场景的噪声降低强度。更高的强度将减少噪声,但有时会导致高纹理区域的细节丢失和一些重影,尤其是在快速移动的物体周围。如果输入噪声很高,由于光线不足和/或传感器灵敏度较高,这可能是一个合适的折衷方案。
对于每个 VPITNRPreset,用户可以定义一个强度因子,基本上是一个介于 0(最小噪声降低量)和 1(最大噪声降低量)之间的浮点数。在大多数情况下,0.5 是一个不错的默认选择。
C API 函数
有关实现该算法的限制、约束和后端的列表,请查阅以下函数的参考文档。
用法
语言
- 导入 VPI 模块
- 初始化阶段
- 创建时域噪声消除对象,将其配置为处理 NV12_ER 输入。CUDA 后端将用于执行该算法。
with vpi.Backend.CUDA
tnr = vpi.TemporalNoiseReduction(size, vpi.Format.NV12_ER)
- 处理阶段
- 从输入视频序列中获取新帧。此处假设它已经是 VPI 图像,格式为 NV12_ER。
while inVideo.read(input)[0]
- 将其馈送到 TNR 对象。返回输入的降噪版本。
denoised = tnr(input, preset=vpi.TNRPreset.INDOOR_MEDIUM_LIGHT, strength=1)
- 初始化阶段
- 包含定义时域噪声消除算法的头文件
- 创建将存储从视频源获取的每个帧的图像。帧将直接以 NV12 格式获取。如果它们采用算法不支持的格式,则可以使用 Convert Image Format 来实现所需的转换。
struct VPIImageImpl * VPIImage
图像的句柄。
VPIStatus vpiImageCreate(int32_t width, int32_t height, VPIImageFormat fmt, uint64_t flags, VPIImage *img)
使用指定的标志创建空图像实例。
- 创建与输入具有相同尺寸和类型的输出和先前输出图像缓冲区。
- 创建算法有效负载。它将处理具有中等照明条件的场景的视频序列,并具有最大强度(strength = 1)。
struct VPIPayloadImpl * VPIPayload
算法有效负载的句柄。
@ VPI_BACKEND_CUDA
CUDA 后端。
VPIStatus vpiCreateTemporalNoiseReduction(uint64_t backends, int32_t width, int32_t height, VPIImageFormat imgFormat, VPITNRVersion version, VPIPayload *payload)
为时域噪声消除算法创建有效负载。
@ VPI_TNR_DEFAULT
选择当前设备和给定后端中可用的最佳质量版本。
- 创建将在其中提交算法以供执行的流。
struct VPIStreamImpl * VPIStream
流的句柄。
VPIStatus vpiStreamCreate(uint64_t flags, VPIStream *stream)
创建流实例。
- 处理阶段
- 从输入视频序列中获取新帧并将其写入 input。
while (FetchFrame(vid, &input))
{
- 将其提交到流中进行处理。如果是第一帧,则第二个参数 prevFrame 必须为 NULL,否则必须传递上一次迭代的输出。
if (isFirstFrame)
{
}
else
{
}
VPITNRPreset preset
要使用的场景预设。
VPIStatus vpiSubmitTemporalNoiseReduction(VPIStream stream, uint64_t backend, VPIPayload payload, VPIImage prevFrame, VPIImage curFrame, VPIImage outFrame, const VPITNRParams *params)
将时域噪声消除操作提交到流。
VPIStatus vpiInitTemporalNoiseReductionParams(VPITNRParams *params)
使用默认值初始化 vpiSubmitTemporalNoiseReduction。
@ VPI_TNR_PRESET_OUTDOOR_MEDIUM_LIGHT
中等光线户外场景。
定义 vpiSubmitTemporalNoiseReduction 参数的结构体。
- (可选)同步到流并使用/显示降噪帧。
VPIStatus vpiStreamSync(VPIStream stream)
阻止调用线程,直到此流队列中的所有提交命令都完成(队列为空)...
- 交换 output 和 prevOutput。在下一次迭代中,output 将作为 prevOutput 输入,而当前的 prevOutput 缓冲区将接收下一个降噪帧。
output = prevOutput;
prevOutput = tmp;
}
- 清理阶段
- 释放流、有效负载以及输入和输出图像所持有的资源。
void vpiImageDestroy(VPIImage img)
销毁图像实例。
void vpiPayloadDestroy(VPIPayload payload)
释放有效负载对象和所有关联的资源。
void vpiStreamDestroy(VPIStream stream)
销毁流实例并释放所有硬件资源。
有关完整示例,请参阅 Temporal Noise Reduction 示例应用程序。
有关更多信息,请参阅《VPI - 视觉编程接口》的“C API 参考”部分中的 Temporal Noise Reduction。
性能
有关如何使用下面的性能表的信息,请参阅 Algorithm Performance Tables。
在比较测量结果之前,请查阅 Comparing Algorithm Elapsed Times。
有关性能基准测试方式的更多信息,请参阅 Performance Benchmark。
-