调整前处理归一化参数的位置
本项目提供了一个通用的模型部署框架,支持多种模型(例如 YOLO 系列:yolov4_tiny、yolov5s、yolov8s 等)。 通过本示例,用户可以了解如何根据所选模型部署相应的推理代码,只需修改前后处理函数,其他部分的代码和函数接口保持一致。
example 目录结构及其主要功能如下所示:
examples ├── yolov5s │ ├── postprocess # yolov5s 后处理相关函数接口 │ ├── resource # 相关模型、图片等资源 │ └── yolov5s_demo.c # yolov5s 推理流程示例代码 ├── resnet18 │ ├── postprocess # resnet18 后处理相关函数接口 │ ├── resource # 相关模型、图片等资源 │ └── resnet18_demo.c # resnet18 推理流程示例代码 ... └── README.md # 示例说明文档
yolov5s_demo.c
yolov4_tiny_demo.c
yolov8s_demo.c
int pnna_open(); // 初始化 Pnna 硬件和驱动资源 int pnna_close(); // 释放硬件资源,关闭驱动
app_ctx_t *create_app_ctx(buffer_t *nbg_buffer, void *norm_param, preprocess_cb preprocess, postprocess_cb postprocess);
int app(app_ctx_t *model, void **output, buffer_t *input);
void destroy_app_ctx(app_ctx_t *model);
以 yolov5s 为例
如 yolov5s_demo.c 中所示:
// 1. 打开设备 pnna_open(); // 2. 加载模型 buffer_t *nbg_buffer = read_nbg("yolov5s.nb"); // 3. 创建模型上下文 app_ctx_t *model = create_app_ctx(&nbg_buffer, &norm_params, preprocess_normalize_quantize, // 前处理 yolov5s_postprocess_dq); // 后处理 // 如果不需要前后处理 // app_ctx_t *model = create_app_ctx(&nbg_buffer, NULL, NULL, NULL); // 4. 读取输入数据 buffer_t input_data = load_image("car.jpg"); // 5. 推理 app(model, output, &input_data); // 6. 清理资源 destroy_tensor(input_data); free_nbg_buffer(nbg_buffer); destroy_app_ctx(model); // 7. 关闭设备 pnna_close();
如果模型有多个输入,则需要多次获取输入数据,输入的个数在函数 create_app_ctx() 完成后可获取
int input_count = yolov5s_model->ctx->input_count; buffer_t *input = (buffer_t *)malloc(input_count * sizeof(buffer_t)); for (int i = 0; i < input_count; ++i) { input[i] = load_image(image_path); } app(model, output, input);
输出结果为最终结果,如 yolov5s_demo.c 中所示,最终结果类型为
detection *output = (detection *)malloc(10 * sizeof(detection)); app(model, (void **)output, input);
请勿使用 detection output[10]; ,这种类型在传入 app() 函数时会有类型不匹配的问题
detection output[10];
app()
输出结果为 buffer_t * 类型,使用方法如下:
buffer_t *
create_app_ctx(); // 需要先初始化网络后,才能获取网络中的参数 int output_count = yolov5s_model->ctx->output_count; buffer_t *output = (buffer_t *)malloc(output_count * sizeof(buffer_t)); app(model, (void **)output, input);
请勿使用 buffer_t output[10]; ,这种类型在传入 app() 函数时会有类型不匹配的问题
buffer_t output[10];
preprocess_cb
preprocess_normalize_quantize
yolov5s_postprocess_dq
NULL
详细介绍如 nn_api.h 中的函数说明所示。
nn_api.h
arm-linux-gnueabihf-gcc
.nb
./yolov5s_demo
rtt_dsp/
#ifdef _TMS320C6X
以下函数为历史接口,已被 V2.1 封装取代。建议新项目统一使用 V2.1 接口。
int nn_init(nn_context **context, const char *nbg_name, unsigned int timeout); // 初始化模型 @deprecated int nn_infer(nn_context *context, void **input_buffer, void **output_buffer); // 推理入口 @deprecated int nn_destroy(nn_context *context); // 释放资源 @deprecated
作者 {{xunyingya}}
模型部署顶层示例程序。包含各模型的demo.c和后处理代码
©Copyright 2023 CCF 开源发展委员会 Powered by Trustie& IntelliDE 京ICP备13000930号
示例程序使用说明
概述
本项目提供了一个通用的模型部署框架,支持多种模型(例如 YOLO 系列:yolov4_tiny、yolov5s、yolov8s 等)。 通过本示例,用户可以了解如何根据所选模型部署相应的推理代码,只需修改前后处理函数,其他部分的代码和函数接口保持一致。
文件简介
example 目录结构及其主要功能如下所示:
yolov5s_demo.c使用 V2.1 接口,推荐使用;yolov4_tiny_demo.c和yolov8s_demo.c使用 V1.0 接口(已废弃),保留做兼容性参考。接口说明
打开与关闭设备
创建模型上下文
执行推理
销毁模型上下文
示例流程
以 yolov5s 为例
推理主流程
如
yolov5s_demo.c中所示:多输入模型参数说明
如果模型有多个输入,则需要多次获取输入数据,输入的个数在函数 create_app_ctx() 完成后可获取
推理结果说明
带后处理
输出结果为最终结果,如
yolov5s_demo.c中所示,最终结果类型为请勿使用
detection output[10];,这种类型在传入app()函数时会有类型不匹配的问题不带后处理
输出结果为
buffer_t *类型,使用方法如下:请勿使用
buffer_t output[10];,这种类型在传入app()函数时会有类型不匹配的问题前后处理说明
preprocess_cb指针注入(如preprocess_normalize_quantize),实现归一化、量化、图像通道排列等;yolov5s_postprocess_dq,负责输出结果解析(如目标框解码、阈值过滤、NMS等);NULLNULL详细介绍如
nn_api.h中的函数说明所示。编译与部署说明
ARM 平台部署
arm-linux-gnueabihf-gcc)编译示例;.nb文件、输入图片传至开发板;DSP / RT-Thread 平台部署
rtt_dsp/提供的库文件;yolov5s_demo.c中的#ifdef _TMS320C6X代码块;V1.0 接口(不推荐使用,仅保留说明)