VPI - 视觉编程接口

3.2 版本

背景减除器

概述

背景减除是一种算法,用于在连续视频序列中将前景对象从背景图像中分离出来。 通过将视频帧作为输入,将生成二值(或三值,如果包括阴影区域)前景掩码和静态背景图像的估计值(如果启用)。

输入前景掩码背景图像

实现

对于每个像素,将基于视频序列的光照变化创建一组高斯模型。 对于图像中的像素,GMM 可以描述为

\[ p(\vec{x}) = \sum_{m=1}^{M}\pi_mN(\vec{x};\vec{\mu}_m, {\vec{\delta}_m}^2) \]

其中
\(\vec{x}\) 是像素值
\(M\) 是高斯模型的总数
\(\pi_m\) 是对应于第 m 个高斯模型的权重
\(\vec{\mu}_m\) 是第 m 个高斯模型的均值
\(\vec{\delta}_m\) 是第 m 个高斯模型的标准方差

马氏距离用于衡量点与分布之间的距离。 有关更多信息,请参阅 [2]。 在这里,我们将 \(D(\vec{x}, m)\) 表示为像素值 x 和第 m 个模型之间的马氏距离。

对于视频序列中的任何新像素,它将计算马氏距离 \(D(\vec{x}, m)\) 与每个高斯模型进行比较。 如果距离在阈值范围内,则找到模型。 否则,如果尚未达到模型的最大数量,它将创建新的高斯模型。 根据匹配模型的权重,它将像素分类为前景或背景。 有关更多信息,请参阅 [1]

C API 函数

有关实现该算法的限制、约束和后端的列表,请查阅以下函数的参考文档

函数描述
vpiInitBackgroundSubtractorParams 使用默认值初始化 VPIBackgroundSubtractorParams
vpiCreateBackgroundSubtractor vpiSubmitBackgroundSubtractor 创建负载。
vpiSubmitBackgroundSubtractor 背景减除器 操作提交到流。

用法

语言
  1. 导入 VPI 模块
    import vpi
  2. 初始化阶段
    1. 创建背景减除器对象,将其配置为处理尺寸为 size 的 RGB8 输入。 CUDA 后端将用于执行该算法。
      with vpi.Backend.CUDA
      bgsub = vpi.BackgroundSubtractor(size, vpi.Format.RGB8)
  3. 处理阶段
    1. 从输入视频序列中获取新帧。 这里假设它已经是 RGB8 格式的 VPI 图像。
      while inVideo.read(input)[0]
    2. 将其馈送到 bgsub 对象中。 前景掩码和背景的估计值将作为 VPI 图像返回。
      fgmask, bgimage = bgsub(input, learnrate=0.01)
  1. 初始化阶段
    1. 包含定义背景减除器函数的头文件
      声明实现背景减除器算法的函数。
    2. 定义所需的图像
      VPIImage input = /* 视频序列中的帧 */;
      VPIPyramid fgmask = /* 前景掩码。格式必须为 VPI_IMAGE_FORMAT_U8 */;
      VPIPyramid bgimage = /* 背景图像。图像格式必须与输入图像格式相同 */;
      struct VPIImageImpl * VPIImage
      图像的句柄。
      Definition: Types.h:256
      struct VPIPyramidImpl * VPIPyramid
      图像金字塔的句柄。
      Definition: Types.h:262
    3. 创建算法要提交执行的流
      VPIStream stream;
      vpiStreamCreate(0, &stream);
      struct VPIStreamImpl * VPIStream
      流的句柄。
      Definition: Types.h:250
      VPIStatus vpiStreamCreate(uint64_t flags, VPIStream *stream)
      创建流实例。
    4. 创建算法负载以处理具有提供的宽度、高度和格式的输入图像
      VPIPayload payload;
      #define VPI_IMAGE_FORMAT_RGB8
      具有交错 RGB 8 位通道的单平面。
      Definition: ImageFormat.h:321
      VPIStatus vpiCreateBackgroundSubtractor(uint64_t backends, int32_t imageWidth, int32_t imageHeight, VPIImageFormat inputFormat, VPIPayload *payload)
      为 vpiSubmitBackgroundSubtractor 创建负载。
      struct VPIPayloadImpl * VPIPayload
      算法负载的句柄。
      Definition: Types.h:268
      @ VPI_BACKEND_CUDA
      CUDA 后端。
      Definition: Types.h:93
  2. 处理阶段
    1. 处理循环的开始。 从视频序列中获取输入。
      for (i = 0; i < nframes; ++i)
      {
      input = /* 从视频序列中获取帧 */;
    2. 配置提交的参数
      algoParams.learningRate = 0.01;
      float learningRate
      学习率,指示背景模型学习的速度。
      VPIStatus vpiInitBackgroundSubtractorParams(VPIBackgroundSubtractorParams *params)
      使用默认值初始化 VPIBackgroundSubtractorParams。
      定义 vpiCreateBackgroundSubtractor 参数的结构。
    3. 将算法提交到流,由 CUDA 后端执行,以及当前输入帧、输出前景掩码和背景图像
      vpiSubmitBackgroundSubtractor(stream, VPI_BACKEND_CUDA, payload, input, fgmask, bgimage, &algoParams);
      VPIStatus vpiSubmitBackgroundSubtractor(VPIStream stream, uint64_t backend, VPIPayload payload, VPIImage inFrame, VPIImage outFGMask, VPIImage outBGImage, const VPIBackgroundSubtractorParams *params)
      将背景减除器操作提交到流。
    4. (可选)等待直到处理完成
      vpiStreamSync(stream);
      VPIStatus vpiStreamSync(VPIStream stream)
      阻塞调用线程,直到此流队列中的所有提交命令完成(队列为空)...
    5. 一旦结果准备就绪,就处理结果
      process_results(fgmask, bgimage);
      }
  3. 清理阶段
    1. 释放流、负载、输入图像、前景图像和背景图像所持有的资源
      vpiImageDestroy(fgmask);
      vpiImageDestroy(bgimage);
      void vpiImageDestroy(VPIImage img)
      销毁图像实例。
      void vpiPayloadDestroy(VPIPayload payload)
      释放负载对象和所有关联的资源。
      void vpiStreamDestroy(VPIStream stream)
      销毁流实例并释放所有硬件资源。

性能

有关如何使用下表中的性能信息,请参阅 算法性能表
在比较测量结果之前,请查阅 比较算法运行时间
有关性能如何进行基准测试的更多信息,请参阅 性能基准

 - 

参考文献

  1. Z. Zivkovic,“用于背景减除的改进的自适应高斯混合模型。”
    第 17 届国际模式识别会议论文集,2004 年。ICPR 2004。
  2. 关于马氏距离的维基百科文章