VPI - 视觉编程接口

3.2 版本

图像直方图

概述

图像直方图是数字图像中色调分布的表示。它统计每个色调值的像素数量。 更多信息,请参见 [1]

输入参数输出
start = 0
end = 256
numBins = 256

实现

此算法将分布划分为多个 bin,并统计每个像素值在 bin 中出现的次数。

强度为 'i' 的像素将导致直方图 bin \(b_i\) 递增,其中

\[ b_i = \frac{(i - \text{start}) * \text{numBins}}{\text{end}-\text{start}} \]

注意
在某些极端情况下,来自 CPU 和 CUDA 后端的直方图结果不匹配,因为这些后端执行浮点计算的方式不同。 CPU 和 CUDA 上的浮点计算仅在一定精度水平上保证相同。 这些细微的差异可能导致 bin 索引的计算方式不同。 例如,当start = 0, end = 245, bin 数量 = 50 时,如果像素值为 147,CPU 后端将返回 bin 索引 = 30,而 CUDA 后端将返回 bin 索引 = 29.999998。

C API 函数

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

函数描述
vpiCreateHistogramEven 为图像直方图均匀算法创建有效负载。
vpiSubmitHistogram 计算图像直方图。

用法

语言
  1. 导入 VPI 模块
    import vpi
  2. 使用 CUDA 后端计算输入 VPI 图像的直方图。 输出是一个包含 numBins 元素的 VPI 数组。
    with vpi.Backend.CUDA
    output = input.histogram(numBins, range=(start, end))
  1. 初始化阶段
    1. 包含定义图像直方图函数的头文件。
      声明计算图像直方图的函数。
    2. 定义输入图像。
      VPIImage input = /*...*/;
      struct VPIImageImpl * VPIImage
      图像的句柄。
      Definition: Types.h:256
    3. 创建输出数组。
      VPIArray output;
      vpiArrayCreate(numBins, VPI_ARRAY_TYPE_U32, 0, &output);
      VPIStatus vpiArrayCreate(int32_t capacity, VPIArrayType type, uint64_t flags, VPIArray *array)
      创建空数组实例。
      struct VPIArrayImpl * VPIArray
      数组的句柄。
      Definition: Types.h:232
      @ VPI_ARRAY_TYPE_U32
      无符号 32 位。
      Definition: ArrayType.h:76
    4. 由于此算法需要临时内存缓冲区,请在 CUDA 后端上为其创建有效负载。
      VPIPayload payload;
      #define VPI_IMAGE_FORMAT_U8
      具有一个 8 位无符号整数通道的单平面。
      Definition: ImageFormat.h:100
      VPIStatus vpiCreateHistogramEven(uint64_t backends, VPIImageFormat fmt, float start, float end, int32_t numBins, VPIPayload *payload)
      为图像直方图均匀算法创建有效负载。
      struct VPIPayloadImpl * VPIPayload
      算法有效负载的句柄。
      Definition: Types.h:268
      @ VPI_BACKEND_CUDA
      CUDA 后端。
      Definition: Types.h:93
    5. 创建流,算法将提交到该流以执行。
      VPIStream stream;
      vpiStreamCreate(0, &stream);
      struct VPIStreamImpl * VPIStream
      流的句柄。
      Definition: Types.h:250
      VPIStatus vpiStreamCreate(uint64_t flags, VPIStream *stream)
      创建流实例。
  2. 处理阶段
    1. 使用 CUDA 后端将算法连同所有参数提交到流。
      vpiSubmitHistogram(stream, VPI_BACKEND_CUDA, payload, input, output, 0);
      VPIStatus vpiSubmitHistogram(VPIStream stream, uint64_t backend, VPIPayload payload, VPIImage input, VPIArray output, uint64_t flags)
      计算图像直方图。
    2. (可选)等待直到处理完成。
      vpiStreamSync(stream);
      VPIStatus vpiStreamSync(VPIStream stream)
      阻塞调用线程,直到此流队列中的所有已提交命令完成(队列为空)。..
  3. 清理阶段
    1. 释放流以及输入和输出图像所持有的资源。
      vpiArrayDestroy(output);
      void vpiArrayDestroy(VPIArray array)
      销毁数组实例。
      void vpiImageDestroy(VPIImage img)
      销毁图像实例。
      void vpiPayloadDestroy(VPIPayload payload)
      释放有效负载对象和所有相关资源。
      void vpiStreamDestroy(VPIStream stream)
      销毁流实例并释放所有硬件资源。

更多信息,请参见 VPI - 视觉编程接口 的 “C API 参考” 部分中的 图像直方图

性能

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

 - 

参考

  1. https://en.wikipedia.org/wiki/Image_histogram