VPI - 视觉编程接口

3.2 版本

立体视差估计器

概述

给定来自立体相机的校正图像对,立体视差算法使用高质量的密集立体匹配来生成与输入图像分辨率相同的输出图像,其中包含左右视差信息。这允许推断左右图像捕获的场景的深度。

左图像右图像
视差图置信度图

实现

立体视差估计器使用 半全局匹配算法 来计算视差。我们通过使用 census 变换 的汉明距离作为立体图像对的成本函数,从而偏离了原始算法。

C API 函数

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

函数描述
vpiInitStereoDisparityEstimatorCreationParams 使用默认值初始化 VPIStereoDisparityEstimatorCreationParams
vpiCreateStereoDisparityEstimator vpiSubmitStereoDisparityEstimator 创建有效负载。
vpiInitStereoDisparityEstimatorParams 使用默认值初始化 VPIStereoDisparityEstimatorParams
vpiSubmitStereoDisparityEstimator 在一对图像上运行立体处理并输出视差图。

用法

语言
  1. 导入 VPI 模块
    import vpi
  2. 估计左右输入 VPI 图像之间的视差,使用 5x5 窗口和 64 最大视差。可选地,生成的视差图像被转换为 U8,范围为 [0,255],适合显示。
    with vpi.Backend.CUDA
    output = vpi.stereodisp(left, right, window=5, maxdisp=64) \
    .convert(vpi.Format.U8, scale=1.0/(32*64)*255)
  1. 初始化阶段
    1. 包含定义所需函数和结构的头文件。将需要 ColorImageFormat 算法来处理用于显示的视差输出。
      声明处理图像格式转换的函数。
      声明实现立体视差估计算法的函数。
    2. 定义输入的校正立体图像对。
      VPIImage left = /*...*/;
      VPIImage right = /*...*/;
      struct VPIImageImpl * VPIImage
      图像的句柄。
      定义: Types.h:256
    3. 创建输出视差和置信度图像,以及用于视差显示的图像(可选)。
      int32_t w, h;
      vpiImageGetSize(left, &w, &h);
      VPIImage disparity;
      vpiImageCreate(w, h, VPI_IMAGE_FORMAT_S16, 0, &disparity);
      VPIImage confidence;
      vpiImageCreate(w, h, VPI_IMAGE_FORMAT_U16, 0, &confidence);
      VPIImage display;
      vpiImageCreate(w, h, VPI_IMAGE_FORMAT_U8, 0, &display);
      #define VPI_IMAGE_FORMAT_U16
      单平面,带有一个 16 位无符号整数通道。
      #define VPI_IMAGE_FORMAT_S16
      单平面,带有一个 16 位有符号整数通道。
      #define VPI_IMAGE_FORMAT_U8
      单平面,带有一个 8 位无符号整数通道。
      VPIStatus vpiImageCreate(int32_t width, int32_t height, VPIImageFormat fmt, uint64_t flags, VPIImage *img)
      使用指定的标志创建空的图像实例。
      VPIStatus vpiImageGetSize(VPIImage img, int32_t *width, int32_t *height)
      以像素为单位获取图像尺寸。
    4. 创建将包含处理所需的所有临时缓冲区的有效负载。它将在 CUDA 后端上创建。
      VPIPayload stereo;
      struct VPIPayloadImpl * VPIPayload
      算法有效负载的句柄。
      定义: Types.h:268
      VPIStatus vpiCreateStereoDisparityEstimator(uint64_t backends, int32_t imageWidth, int32_t imageHeight, VPIImageFormat inputFormat, const VPIStereoDisparityEstimatorCreationParams *params, VPIPayload *payload)
      为 vpiSubmitStereoDisparityEstimator 创建有效负载。
      @ VPI_BACKEND_CUDA
      CUDA 后端。
      定义: Types.h:93
    5. 创建将在其中提交算法以执行的流。
      VPIStream stream;
      vpiStreamCreate(0, &stream);
      struct VPIStreamImpl * VPIStream
      流的句柄。
      定义: Types.h:250
      VPIStatus vpiStreamCreate(uint64_t flags, VPIStream *stream)
      创建流实例。
  2. 处理阶段
    1. 定义算法执行所需的配置参数。
      params.windowSize = 5;
      params.maxDisparity = 64;
      int32_t windowSize
      表示 OFA+PVA+VIC 后端上的中值滤波器大小或 census 变换窗口大小(其他后端...)。
      int32_t maxDisparity
      匹配搜索的最大视差。
      VPIStatus vpiInitStereoDisparityEstimatorParams(VPIStereoDisparityEstimatorParams *params)
      使用默认值初始化 VPIStereoDisparityEstimatorParams。
      定义 vpiSubmitStereoDisparityEstimator 参数的结构体。
    2. 提交有效负载以在与其关联的后端上执行。
      vpiSubmitStereoDisparityEstimator(stream, VPI_BACKEND_CUDA, stereo, left, right, disparity, confidence, &params);
      VPIStatus vpiSubmitStereoDisparityEstimator(VPIStream stream, uint64_t backend, VPIPayload payload, VPIImage left, VPIImage right, VPIImage disparity, VPIImage confidenceMap, const VPIStereoDisparityEstimatorParams *params)
      在一对图像上运行立体处理并输出视差图。
    3. 可选地,可以将生成的视差图像转换为 U8 格式,并将视差值重新缩放到 [0,255] 范围内,以适合显示。
      cvtParams.scale = 1.0f / (32 * params.maxDisparity) * 255;
      vpiSubmitConvertImageFormat(stream, VPI_BACKEND_CUDA, disparity, display, &cvtParams);
      VPIStatus vpiInitConvertImageFormatParams(VPIConvertImageFormatParams *params)
      使用默认值初始化 VPIConvertImageFormatParams。
      VPIStatus vpiSubmitConvertImageFormat(VPIStream stream, uint64_t backend, VPIImage input, VPIImage output, const VPIConvertImageFormatParams *params)
      将图像内容转换为所需的格式,并具有可选的缩放和偏移。
      用于自定义图像格式转换的参数。
    4. 等待直到处理完成。
      vpiStreamSync(stream);
      VPIStatus vpiStreamSync(VPIStream stream)
      阻塞调用线程,直到此流队列中所有提交的命令都完成(队列为空)。
  3. 清理阶段
    1. 释放流、有效负载以及输入和输出图像所持有的资源。
      vpiImageDestroy(display);
      vpiImageDestroy(disparity);
      vpiImageDestroy(confidence);
      void vpiImageDestroy(VPIImage img)
      销毁图像实例。
      void vpiPayloadDestroy(VPIPayload payload)
      释放有效负载对象和所有关联的资源。
      void vpiStreamDestroy(VPIStream stream)
      销毁流实例并释放所有硬件资源。

请参阅 立体视差示例 以获取完整示例。

有关更多信息,请参阅 VPI - 视觉编程接口 的 “C API 参考” 部分中的 立体视差估计器

性能

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

 - 

参考

  • Hirschmüller, Heiko (2005). "通过半全局匹配和互信息实现精确高效的立体处理"。
    IEEE 计算机视觉和模式识别会议。pp. 807–814。
  • Zabih, Ramin; Woodfill, John (1994). "用于计算视觉对应的非参数局部变换"。
    欧洲计算机视觉会议。pp. 151–158。