作者:SkyXZ
CSDN:SkyXZ~-CSDN博客
博客园:SkyXZ - 博客园
宿主机环境:Ubuntu22.04(192x CPU 8x NVIDIA GeForce RTX 4090)、D-Robotics-OE 3.2.0、Ubuntu22.04 GPU Docker
端侧设备环境:RDKS100-RDK OS 4.0.2-Beta
买了RDK S100还只停留在RDKX5的使用思想?想部署模型但对着全新的工具链不知从何下手?好不容易学会X5上的HB_DNN结果面对S100的UCP只能一脸懵?我知道你很急,但你先别急!跟着这篇学妹吵着要学的模型量化部署教程包你30Min告别RDKS100模型量化部署小白!!!本篇文章为万字长文,学弟一看就会的RDKX5模型转换及部署,你确定不学?的姐妹篇,本篇侧重于基础模型的部署,后续会更新VLA等具身智能模型在RDKS100的部署教程,首先介绍一下我们本篇教程的参考资料:
- RDKS100用户手册:https://developer.d-robotics.cc/rdk_doc/rdk_s/RDK/
- RDKS100 OpenExplorer®算法工具链:https://toolchain.d-robotics.cc/
- RDKS100—ModelZoo:https://github.com/D-Robotics/rdk_model_zoo_s/tree/s100
一、算法工具链介绍及环境安装
目前,我们在GPU上训练的模型通常采用浮点数格式,因为浮点类型能够提供较高的计算精度和灵活性,但是对于边缘式设备来说浮点类型模型所需的算力和存储资源远超其承载能力,因此一般边缘式设备上的AI加速芯片基本都只支持INT8(业内处理器的通用精度)定点模型,我们S100的BPU也不例外,因此我们需要将我们训练出来的浮点模型转化为定点模型,这一过程便叫做模型的量化,而我们要下载的OE包是Open Explorer的缩写简称,中文名为天工开物(以下简称OE),它是基于地平线自研计算平台打造的全生命周期开发平台, 主要包括模型编译优化工具集、算法仓库和应用开发SDK三大功能模块。下面我们介绍该如何安装算法工具链:
由于算法工具链暂时只能在Linux环境运行,因此大家首先先确保自己的开发机满足以下要求并且安装了WSL2-Ubuntu(具体可参阅:告别虚拟机!WSL2安装配置教程!!! - SkyXZ - 博客园)或者是虚拟机里的Ubuntu亦或者在自己的Linux服务器,由于官方有给我们工具链的docker镜像因此Ubuntu的系统版本不是很重要,以下为官方建议的系统配置:
硬件/操作系统要求CPUCPU I3以上或者同级别E3/E5的处理器内存16G或以上级别GPUCUDA11.8、驱动版本Linux:>= 510.39.01* (推荐驱动版本Linux:520.61.05) 适配显卡包括但不限于: 1. GeForce RTX 3090 2. GeForce RTX 2080 Ti 3. NVIDIA TITAN V 4. Tesla V100S-PCIE-32GB 5. A100系统原生Ubuntu 22.04 S100的工具链手册中有详细的环境部署教程https://toolchain.d-robotics.cc/guide/env_install.html,我们这里仅介绍最通用最便捷的Docker容器部署的方法:
(1)安装Docker及NVIDIA Container Toolkit
我们在Ubuntu中安装Docker(官方要求20.10.10或更高版本,安装详见:Get Docker | Docker Docs)及NVIDIA Container Toolkit(官方建议1.13.5或更高版本,建议安装1.15.0,安装详见:NVIDIA Container Toolkit安装手册),接着我将从头带着大家走一遍这个过程,首先便是安装Docker,我们先卸载系统默认安装的docker并安装一些必要支持:- #如果有便删,报错说没有那就无所谓不用管
- sudo apt-get remove docker docker-engine docker.io containerd runc
- #下载必要依赖
- sudo apt install apt-transport-https ca-certificates curl software-properties-common gnupg lsb-release
复制代码 我们默认大家不会使用代理,因此我们所有的源均使用国内源,我们添加阿里的GPG KEY以及阿里的APT源后便可以直接APT安装Docker的最新版本啦- # step 1 添加阿里GPG Key
- curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
- # step 2 添加阿里Docker APT源
- echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
- # step 3 Update
- sudo apt update
- sudo apt-get update
- # step 4 下载Docker
- sudo apt install docker-ce docker-ce-cli containerd.io
- # step 5 验证Docker安装
- sudo docker version #查看Docker版本
- sudo systemctl status docker #验证Docker运行状态
复制代码
如果验证Docker安装均有输出且正常运行那么便代表我们的Docker安装完成啦,接着我们将无root权限的用户添加到Docker用户组中,这样我们便可以让当前用户在不切root,或者不加sudo 的情况下正常使用 docker 命令:- sudo groupadd docker
- sudo gpasswd -a ${USER} docker
- sudo service docker restart
复制代码 但是到这里还没有结束,因为大概率大家运行docker run hello-world是会一直报如下网络错误:
这是因为国内暂时无法直接访问Docker源镜像,我们需要使用第三方Docker源,我在这里帮大家已经整理好了一些常见的Docker源,大家只需要添加进/etc/docker/daemon.json文件即可:- # step 1 创建 or 编辑 /etc/docker/daemon.json
- sudo nano /etc/docker/daemon.json
- # step 2 复制粘贴进入文件
- {
- "registry-mirrors": [
- "https://dockerproxy.com",
- "https://docker.m.daocloud.io",
- "https://cr.console.aliyun.com",
- "https://ccr.ccs.tencentyun.com",
- "https://hub-mirror.c.163.com",
- "https://mirror.baidubce.com",
- "https://docker.nju.edu.cn",
- "https://docker.mirrors.sjtug.sjtu.edu.cn",
- "https://github.com/ustclug/mirrorrequest",
- "https://registry.docker-cn.com"
- ]
- }
- # step 3 重载配置文件,并重启 docker
- sudo systemctl daemon-reload
- sudo systemctl restart docker
- # step 4 查看Docker配置检查是否配置成功
- sudo docker info
复制代码
可以看到运行了docker info命令后终端输出了我们之前添加进去的docker源地址,这时候我们再次运行docker run hello-world便可以看到docker成功下载了对应的镜像并打印输出了“Hello from Docker!”
安装完docker,接着我们来安装NVIDIA Container Toolkit (电脑没有GPU或者是使用的VM等虚拟机的同学可以跳过这一步了,由于你们无法访问到GPU所以这步不需要安装),这个工具链组件是一个Nvidia提供的一组工具,安装了之后我们便可以在Docker中使用GPU并能够支持 GPU 加速,由于Nvidia的文档写的非常的详细,因此我们按照英伟达文档中的步骤来安装配置
类似于之前的Docker,我们需要添加Nvidia官方的源,添加了之后我们便可以直接使用APT安装啦- # step 1 配置生产存储库
- curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
- && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
- sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
- sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
- # step 2 Update
- sudo apt-get update
- # step 3 使用APT安装
- sudo apt-get install -y nvidia-container-toolkit #如果没有代理这部分耗时会比较久
复制代码 接着我们开始为Docker配置NVIDIA Container Runtime,这部分很简单只需要两行命令即可:- sudo nvidia-ctk runtime configure --runtime=docker #使用nvidia-ctk命令修改/etc/docker/daemon.json 文件
- sudo systemctl restart docker #重启Docker守护进程
复制代码 最后输入以下命令即可验证我们的配置是否成功,如果出现下图即代表Nvidia Container Toolkit安装完成啦!!!- sudo docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi
复制代码
(2)配置使用S100算法工具链
好啦,走完上述流程没有问题的话就代表我们现在已经完成了所有的前置配置啦!接着我们便可以开始配置我们的算法工具链,首先我们下载RDK的OE交付包(截止文章发布最新版本为V3.2.0)以及对应的Docker镜像- # 下载OE-v1.2.8交付包
- wget -c ftp://oeftp@sdk.d-robotics.cc/oe_v3.2.0/s100-3.2.0-oe-package.tgz --ftp-password=Oeftp~123$%
- # 自行选择下述CPU or GPU版本的Docker镜像下载,二选一即可
- #CPU Docker镜像
- wget -c ftp://oeftp@sdk.d-robotics.cc/oe_v3.2.0/ai_toolchain_ubuntu_22_s100_cpu_v3.2.0.tar --ftp-password=Oeftp~123$%
- #GPU Docker镜像
- wget -c ftp://oeftp@sdk.d-robotics.cc/oe_v3.2.0/ai_toolchain_ubuntu_22_s100_gpu_v3.2.0.tar --ftp-password=Oeftp~123$%
- #算法工具链 用户开发文档(按需下载)
- wget -c ftp://oeftp@sdk.d-robotics.cc/oe_v3.2.0/s100-3.2.0-oe-doc.zip --ftp-password=Oeftp~123$%
复制代码 由于docker系统文件较大,所以我们需要稍等一会,下载完之后输入ls便能看到两个文件啦
我们输入以下指令进行解压:- tar -xvf s100-3.2.0-oe-package.tgz #解压OE交付包
复制代码 解压完成后我们进入OE包,可以看到我们的OE包的结构如下,分为两个大的文件夹package和samples,package里面主要是目录下包含了发布物运行的一些基础库和组件,由于我们使用的Docker镜像因此这个文件夹我们可以不用管我们主要来看看samples包叭,samples下包含了 ai_toolchain、model_zoo和ucp_tutorial三个交付包,其中ai_toolchain提供了一些模型算法的一系列示例。(其中horizon_model_train_samples为浮点模型训练框架示例,horizon_model_convert_sample为浮点模型转定点模型的转换示例, model_zoo是一个模型库,用于放置工具链示例模型编译的源模型和runtime模型。),ucp_tutorial为统一计算平台UCP的示例包,提供UCP必要的依赖以及相关示例,具体介绍见:https://toolchain.d-robotics.cc/guide/preface/learn_oe.html#release
看完了OE交付包接着我们开始导入Docker镜像,由于这个docker镜像和OE包相辅相成,因此我们可以设置docker的映射路径,接着我们从tar包导入docker镜像即可:- #大家根据自己的路径进行修改
- export S100_Model_path=/home/qi.xiong/RDK/S100/Model # Docker与开发机的交互工作空间需要在Docker中使用的文件放此文件夹
- export dataset_path=/home/qi.xiong/Dataset # 数据集存放路径(按需设置,我用来统一存放校准数据集)
- #导入镜像
- docker load < ai_toolchain_ubuntu_22_s100_gpu_v3.2.0.tar
复制代码 由于我们的镜像比较大,所以导入的时间会比较久,大家安心等待即可,接着我们输入如下的指令即可启动docker镜像- docker run -it --rm --gpus '"device=6"' --shm-size=32g -v "$ai_toolchain_package_path":/open_explorer -v "$dataset_path":/open_explorer/Dataset -v "$S100_Model_path":/open_explorer/Model ai_toolchain_ubuntu_22_s100_gpu:v3.2.0
复制代码 接着在镜像中输入命令hb_mapper有如下打印输出则代表我们环境安装完成啦~~
小Tips:大家可以在~/.bashrc中使用alias添加如下一行,之后便可以直接在终端输入RDK_S100DockerToolchain打开工具链啦,就不用去记那么长的指令了- alias RDK_S100DockerToolchain="docker run -it --rm --gpus '"device=6"' --shm-size=32g -v "$ai_toolchain_package_path":/open_explorer -v "$dataset_path":/open_explorer/Dataset -v "$S100_Model_path":/open_explorer/Model ai_toolchain_ubuntu_22_s100_gpu:v3.2.0"
复制代码
至此我们的地瓜工具链的环境便全部安装配置完成啦!!!
二、Model Zoo介绍
我觉得对于刚拿到RDKS100板子的同学来说,我们无法绕开地瓜机器人最新推出的Model Zoo而直接去学习RDK的算法工具链,因此我们的X5模型量化转换部署教程便先从Model_Zoo_s开始介绍。Model Zoo,意如其名,从字面上我们便可以知道这是一个"模型动物园",这是一个是一个由地瓜开发者社区在维护的一个开源社区算法案例仓库,旨在为开发者提供能直接上板部署的,丰富多样的模型案例。RDKX5有属于自己的ModelZoo,RDKS100也拥有属于他自己的ModelZoo,目前还仍在不断扩充中
那我们该如何使用这个仓库呢?我们首先从Github上将Model Zoo拉取下来,我们可以看到Model Zoo的项目结构如图所示:- git clone https://github.com/D-Robotics/rdk_model_zoo_s/tree/s100 #拉取Model Zoo
复制代码
主文件夹下面有中英双语的README、README的图片资源文件夹resource以及我们最主要的sample文件夹,这里面把官方目前支持的所有模型按照视觉模型Vision、LLM大语言模型LLM、多模态模型Multi-Model、动作策略模型Planning及语音模型Speech等分为了五大类
相信到这大家应该对Model Zoo有了基本的认识,接下来我们以Yolo-Detect系列模型为例子给大家介绍如何转换模型
三、模型量化示例教程
接下来我们正式进入工具链的使用,我们以Ultralytics官方版本为示例带着大家在完成模型转化的同时简单了解其中的一些概念,本流程将基于rdk_model_zoo_s/samples/Vision/ultralytics_YOLO_Detect/README_cn.md地瓜Model Zoo中的官方文档描述的进行介绍,由于经过这套方案处理之后的模型具有相同了前处理和后处理因此本方案理论上支持Yolo全系列模型
我们首先拉取Ultralytics的源码,并配置好环境,我们这里先通过下载ultralytics包完成所有依赖的安装,然后由于我们在导出的时候需要修改输出头,因此我们安装完后需要卸载掉ultralytics包并启用可编辑开发模式安装本地源码,这样可以方便我们修改源码后立即生效,完整的流程如下:- git clone https://github.com/ultralytics/ultralytics.git
- conda create -n YOLO python=3.10 -y && conda activate YOLO
- pip3 install ultralytics && pip uninstall ultralytics
- cd ultralytics && pip3 install -e .
复制代码 接着我们打开ultralytics/ultralytics/nn/modules/head.py文件找到class Detect类的forward部分(大概114行),并修改成如下形式,主要就是修改了导出时的输出头,同时添加了训练和导出模式的判定,以便我们在训练和导出的时候不需要频繁修改forward方法:- def forward(self, x: List[torch.Tensor]) -> Union[List[torch.Tensor], Tuple]:
- """Concatenate and return predicted bounding boxes and class probabilities."""
- if self.training:
- if self.end2end:
- return self.forward_end2end(x)
- for i in range(self.nl):
- x[i] = torch.cat((self.cv2[i](x[i]), self.cv3[i](x[i])), 1)
- if self.training: # Training path
- return x
- y = self._inference(x)
- return y if self.export else (y, x)
- elif self.export:
- result = []
- for i in range(self.nl):
- result.append(self.cv3[i](x[i]).permute(0, 2, 3, 1).contiguous())
- result.append(self.cv2[i](x[i]).permute(0, 2, 3, 1).contiguous())
- return result
复制代码 接着我们下载ultralytics官方预训练权重,我们这里就以YOLOv8n来演示叭- wget https://github.com/ultralytics/assets/releases/download/v8.3.0/yolov8n.pt
复制代码 下载之后我们新建一个export.py文件,并使用以下代码导出onnx格式的模型,注意和X5不一样的地方是S100支持Opset19- from ultralytics import YOLO
- YOLO('yolov8n.pt').export(imgsz=640, format='onnx', simplify=True, opset=19)
复制代码 接着我们需要准备校准数据,这部分其实就是将我们的数据集里的图片变换成我们训练时输入的格式即可,具体代码如下不过多叙述,可以直接套用- import os
- import numpy as np
- from PIL import Image
- import cv2
- from tqdm import tqdm
- import argparse
- def preprocess_image(image_path, target_size=(640, 640), scale_value=0.003921568627451):
- image = cv2.imread(image_path)
- if image is None:
- raise ValueError(f"无法读取图片: {image_path}")
- image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
- image = cv2.resize(image, target_size, interpolation=cv2.INTER_LINEAR)
- # 转换为float32并归一化
- image = image.astype(np.float32)
- image = image * scale_value # 等同于 / 255
- # 转换为NCHW格式 (Batch, Channel, Height, Width)
- # 原始格式: (H, W, C) -> 目标格式: (1, C, H, W)
- image = np.transpose(image, (2, 0, 1)) # (H, W, C) -> (C, H, W)
- image = np.expand_dims(image, axis=0) # (C, H, W) -> (1, C, H, W)
- return image
- def batch_preprocess(input_dir, output_dir, target_size=(640, 640),
- scale_value=0.003921568627451, max_images=100):
- # 创建输出目录
- os.makedirs(output_dir, exist_ok=True)
- # 获取所有jpg图片
- image_files = []
- for ext in ['*.jpg', '*.jpeg', '*.JPG', '*.JPEG']:
- image_files.extend([f for f in os.listdir(input_dir) if f.lower().endswith(('.jpg', '.jpeg'))])
- image_files = sorted(image_files)[:max_images] # 限制数量
- print(f"找到 {len(image_files)} 张图片,将处理前 {len(image_files)} 张")
- print(f"目标尺寸: {target_size}")
- print(f"缩放因子: {scale_value}")
- print(f"输出目录: {output_dir}")
- # 批量处理
- for i, filename in enumerate(tqdm(image_files, desc="处理图片")):
- try:
- input_path = os.path.join(input_dir, filename)
- # 预处理图片
- processed_image = preprocess_image(input_path, target_size, scale_value)
- # 保存为npy文件
- output_filename = f"calibration_{i:04d}.npy"
- output_path = os.path.join(output_dir, output_filename)
- # 保存时去掉batch维度,保存为 (C, H, W) 格式
- np.save(output_path, processed_image.squeeze(0))
- except Exception as e:
- print(f"处理图片 {filename} 时出错: {e}")
- continue
- print(f"预处理完成!共生成 {len(os.listdir(output_dir))} 个校准数据文件")
- print(f"校准数据保存在: {output_dir}")
- def verify_calibration_data(calibration_dir, num_samples=5):
- """
- 验证校准数据格式
- """
- print("\n=== 校准数据验证 ===")
- npy_files = [f for f in os.listdir(calibration_dir) if f.endswith('.npy')]
- npy_files = sorted(npy_files)[:num_samples]
- for filename in npy_files:
- filepath = os.path.join(calibration_dir, filename)
- data = np.load(filepath)
- print(f"文件: {filename}")
- print(f" 形状: {data.shape}")
- print(f" 数据类型: {data.dtype}")
- print(f" 数值范围: [{data.min():.6f}, {data.max():.6f}]")
- print(f" 均值: {data.mean():.6f}")
- print()
- if __name__ == "__main__":
- parser = argparse.ArgumentParser(description='S100 校准数据预处理')
- parser.add_argument('--input_dir', type=str,
- default='/home/qi.xiong/Dataset/UAV_Sheep/yolo_dataset/test/images',
- help='输入图片目录')
- parser.add_argument('--output_dir', type=str,
- default='/home/qi.xiong/RDK/S100/Model/calibration_data',
- help='输出校准数据目录')
- parser.add_argument('--target_size', type=int, nargs=2, default=[640, 640],
- help='目标图片尺寸 (width height)')
- parser.add_argument('--scale_value', type=float, default=0.003921568627451,
- help='缩放因子 (通常是 1/255)')
- parser.add_argument('--max_images', type=int, default=100,
- help='最大处理图片数量')
- args = parser.parse_args()
- print("=== S100 校准数据预处理 ===")
- print(f"输入目录: {args.input_dir}")
- print(f"输出目录: {args.output_dir}")
- # 检查输入目录
- if not os.path.exists(args.input_dir):
- print(f"错误: 输入目录不存在 - {args.input_dir}")
- exit(1)
- # 执行预处理
- batch_preprocess(
- input_dir=args.input_dir,
- output_dir=args.output_dir,
- target_size=tuple(args.target_size),
- scale_value=args.scale_value,
- max_images=args.max_images
- )
- # 验证结果
- verify_calibration_data(args.output_dir)
复制代码 在准备了校准数据之后我们还需要查看一下需要移除的反量化节点名称,我们打开Netron可视化工具,将我们上一步生成的onnx模型拖入其中打开即可看到我们的这个模型的网络架构,接着我们拖动到最上方点击输入的images即可在右边弹出的界面看到我们这个模型的所有输出
接着我们找到带有64(64 = 4 * REG, REG = 16.)的三个输出依此点击这三个输出后记录下右边的输出节点的name,不同版本的Ultralytics导出的ONNX的名称是不同的, 请勿直接套用!!!
在记录下这三个反量化节点的名字后我们开始配置模型转换的Yaml,并将记录好的节点名字填入remove_node_name中并以英文的;号分割,yaml的具体介绍请见模型量化编译 - OpenExplorer的“配置文件具体参数信息”一节,接着我们将前一步生成的校准数据文件路径填入yaml的cal_data_dir一项后配置文件就完成啦!- model_parameters:
- onnx_model: 'yolov8n.onnx'
- march: nash-e # S100: nash-e, S100P: nash-m.
- layer_out_dump: False
- working_dir: 'ultralytcs_YOLO_output'
- output_model_file_prefix: 'ultralytcs_YOLO'
- remove_node_name: ""
- input_parameters:
- input_name: ''
- input_type_rt: 'nv12'
- input_type_train: 'rgb'
- input_layout_train: 'NCHW;'
- input_shape: ''
- norm_type: 'data_scale'
- mean_value: ''
- scale_value: 0.003921568627451
- calibration_parameters:
- cal_data_dir: './calibration_data_rgb_f32'
- cal_data_type: 'float32'
- calibration_type: 'default'
- quant_config: {"op_config": {"softmax": {"qtype": "int8"}}}
- compiler_parameters:
- extra_params: {'input_no_padding': True, 'output_no_padding': True}
- jobs: 16
- compile_mode: 'latency'
- debug: True
- advice: 1
- optimize_level: 'O2'
复制代码 接着我们将配置文件以及转换之后的onnx模型放入我们之前提到的开发机与Docker文件交互文件夹中,我们便可以在Docekr中访问到我们的必要文件啦
完成了上述步骤后我们运行如下命令即可开始模型的转换- hb_compile -c convert.yaml
复制代码
耐心等待即可,编译完成之后便会在目录下生成所需文件以及我们推理需要用到的hbm文件
四、模型部署应用实例
接下来就到了大家最关心最好奇的模型部署环节啦!!!RDKS100采用了和X5不同的异构编程接口也就是统一计算平台(Unify Compute Platform,以下简称 UCP)以实现对计算平台资源的调用,官方详细的介绍见UCP总览 - OpenExplorer,工具链手册中已经有了详细的API介绍,但我们这篇文章中为了避免大家频繁的来回切换网页,我们对于每个新出现的API函数还是会附上对应的介绍,话不多说,我们一步一步的开始实现推理代码,完整代码已传至ModelZoo
首先我们先来完成代码的宏定义以便我们修改模型路径、类别名称等基本配置
[code]// D-Robotics S100 *.hbm 模型路径// Path of D-Robotics S100 *.hbm model.#define MODEL_PATH "rdk_model_zoo_s/samples/Vision/ultralytics_YOLO_Detect/source/reference_hbm_models/yolov5nu_detect_nashe_640x640_nv12.hbm"// 推理使用的测试图片路径// Path of the test image used for inference.#define TEST_IMG_PATH "rdk_model_zoo_s/resource/datasets/COCO2017/assets/bus.jpg"// 前处理方式选择, 0:Resize, 1 etterBox// Preprocessing method selection, 0: Resize, 1: LetterBox#define RESIZE_TYPE 0 #define LETTERBOX_TYPE 1#define PREPROCESS_TYPE LETTERBOX_TYPE// 推理结果保存路径// Path where the inference result will be saved#define IMG_SAVE_PATH "cpp_result.jpg"// 模型的类别数量, 默认80// Number of classes in the model, default is 80#define CLASSES_NUM 80// NMS的阈值, 默认0.7// Non-Maximum Suppression (NMS) threshold, default is 0.7#define NMS_THRESHOLD 0.7// 分数阈值, 默认0.25// Score threshold, default is 0.25#define SCORE_THRESHOLD 0.25// 控制回归部分离散化程度的超参数, 默认16// A hyperparameter that controls the discretization level of the regression part, default is 16#define REG 16// 绘制标签的字体尺寸, 默认1.0// Font size for drawing labels, default is 1.0.#define FONT_SIZE 1.0// 绘制标签的字体粗细, 默认 1.0// Font thickness for drawing labels, default is 1.0.#define FONT_THICKNESS 1.0// 绘制矩形框的线宽, 默认2.0// Line width for drawing bounding boxes, default is 2.0.#define LINE_SIZE 2.0// API运行控制#define RDK_CHECK_SUCCESS(value, errmsg) \ do \ { \ auto ret_code = value; \ if (ret_code != 0) \ { \ std::cout |