VPI - 视觉编程接口

3.2 版本

AprilTag 检测器和姿态估计器

概述

AprilTag 是为视觉检测和定位而设计的基准标记。VPI 支持检测多种常见的标签族,并且可以作为 参考检测算法 的直接替代品使用。

有关更多信息,请参阅 AprilTags 的主页:April Robotics。

输入检测输出

实现

检测器

检测器的实现分为以下阶段

阶段描述后端
抽取输入图像缩小 2 倍PVA/CPU
自适应阈值化决定缩小图像中的像素是黑色还是白色PVA/CPU
连通组件标记为黑色/白色像素的连续区域分配唯一 IDPVA/CPU
梯度簇生成聚类所有位于给定黑色/白色区域对之间边缘上的坐标PVA/CPU
四边形拟合尝试将四边形拟合到每个梯度簇CPU
解码尝试将每个四边形解码为 AprilTagCPU

当选择 VPI_BACKEND_PVA 时,VPI 将对支持此后端的阶段使用 PVA,其余阶段则回退到 CPU。VPIStream 和输入/输出缓冲区应创建为同时支持 PVA 和 CPU。

姿态估计器

通常,从单应性分解 [1] 进行 3D 姿态估计有八个数学解。在这八个解中,只有两个在满足以下约束条件下有效:(1)相机在标签前方,以及(2)相机正对标签。

姿态估计器尝试通过 SVD 估计这两个候选姿态,然后进行固定次数的迭代,以最大限度地减少角点重投影误差。如果两个候选姿态都有效,则估计器返回导致角点重投影误差最小的姿态。

C API 函数

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

函数描述
vpiInitAprilTagDecodeParams 使用默认值初始化 VPIAprilTagDecodeParams
vpiCreateAprilTagDetector 创建 AprilTag 检测器 负载。
vpiSubmitAprilTagDetector 向流提交 AprilTag 检测器 操作。
vpiSubmitAprilTagPoseEstimation 向流提交 AprilTag 姿态估计 操作。

用法

语言
  1. 初始化阶段
    1. 包含定义 AprilTags 函数的头文件
      声明实现 AprilTag 检测和姿态估计的函数。
    2. 定义所需的输入图像
      VPIImage input = /*...*/;
      struct VPIImageImpl * VPIImage
      图像的句柄。
      定义: Types.h:256
    3. 定义有效负载以使用提供的宽度和高度处理输入图像
      int32_t w, h;
      vpiImageGetSize(input, &w, &h);
      VPIPayload payload;
      const int maxHamming = 1;
      VPIAprilTagDecodeParams params = {NULL, 0, maxHamming, family};
      vpiCreateAprilTagDetector(VPI_BACKEND_CPU, w, h, &params, &payload);
      VPIStatus vpiCreateAprilTagDetector(uint64_t backends, int32_t inputWidth, int32_t inputHeight, VPIAprilTagDecodeParams const *params, VPIPayload *payload)
      创建 AprilTag 检测器负载。
      VPIAprilTagFamily
      指定要检测的 AprilTag 标签族。
      @ VPI_APRILTAG_36H11
      36h11 标签族
      vpiCreateAprilTagDetector 的解码参数。
      VPIStatus vpiImageGetSize(VPIImage img, int32_t *width, int32_t *height)
      获取图像尺寸(以像素为单位)。
      struct VPIPayloadImpl * VPIPayload
      算法负载的句柄。
      定义: Types.h:268
      @ VPI_BACKEND_CPU
      CPU 后端。
      定义: Types.h:92
    4. 定义输出数组
      const int maxDetections = 64;
      VPIArray detections;
      VPIArray poses;
      VPIStatus vpiArrayCreate(int32_t capacity, VPIArrayType type, uint64_t flags, VPIArray *array)
      创建空数组实例。
      struct VPIArrayImpl * VPIArray
      数组的句柄。
      定义: Types.h:232
      @ VPI_ARRAY_TYPE_POSE
      VPIPose 元素。
      @ VPI_ARRAY_TYPE_APRILTAG_DETECTION
      VPIAprilTagDetection 元素。
    5. 创建流,算法将提交到该流以执行
      VPIStream stream;
      vpiStreamCreate(0, &stream);
      struct VPIStreamImpl * VPIStream
      流的句柄。
      定义: Types.h:250
      VPIStatus vpiStreamCreate(uint64_t flags, VPIStream *stream)
      创建流实例。
  2. 处理阶段
    1. 提交检测器
      vpiSubmitAprilTagDetector(stream, VPI_BACKEND_CPU, payload, maxDetections, input, detections);
      VPIStatus vpiSubmitAprilTagDetector(VPIStream stream, uint64_t backend, VPIPayload payload, uint32_t maxDetections, VPIImage input, VPIArray outDetections)
      向流提交 AprilTag 检测器操作。
    2. 提交姿态估计器
      const VPICameraIntrinsic intrinsics = {{w / 3.5f, 0.0f, w / 2.f}, {0.0f, h / 3.6f, h / 2.f}};
      const float tagSize = 0.2f;
      vpiSubmitAprilTagPoseEstimation(stream, VPI_BACKEND_CPU, detections, intrinsics, tagSize, poses);
      VPIStatus vpiSubmitAprilTagPoseEstimation(VPIStream stream, uint64_t backend, VPIArray inDetections, const VPICameraIntrinsic intrinsics, float tagSize, VPIArray outPoses)
      向流提交 AprilTag 姿态估计操作。
      float VPICameraIntrinsic[2][3]
      相机内参矩阵。
      定义: Types.h:655
    3. 等待直到处理完成
      vpiStreamSync(stream);
      VPIStatus vpiStreamSync(VPIStream stream)
      阻塞调用线程,直到此流队列中的所有提交命令完成(队列为空)。
  3. 清理阶段
    1. 释放流、负载、输入图像和输出数组所持有的资源
      vpiArrayDestroy(detections);
      void vpiArrayDestroy(VPIArray array)
      销毁数组实例。
      void vpiImageDestroy(VPIImage img)
      销毁图像实例。
      void vpiPayloadDestroy(VPIPayload payload)
      释放负载对象和所有相关资源。
      void vpiStreamDestroy(VPIStream stream)
      销毁流实例并释放所有硬件资源。

性能

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

 - 

参考

  1. Malis, E. 和 Vargas, M. "Deeper understanding of the homography decomposition for vision-based control"
    Research Report 6303, INRIA 2007