当前位置: 首页 > news >正文

RK3588芯片NPU的使用:yolov8-pose例子图片检测在安卓系统部署与源码深度解析(rknn api)

一、本文的目标

  • 将yolo8-pose例子适配安卓端,提供选择图片后进行姿态识别功能。
  • 通过项目学习源码和rknn api。

二、开发环境说明

  • 主机系统:Windows 11
  • 目标设备:搭载RK3588芯片的安卓开发板
  • 核心工具:Android Studio Koala | 2024.1.1 Patch 2,NDK 27.0

三、适配(迁移)安卓

有了前两次的迁移经验,这次就很顺利了。可以参考之前三篇文章,如果还是遇到问题(或者需要源码),给我留言。
Yolo8-pose C语言例子请参考之前的博文《RK3588芯片NPU的使用:Windows11 Docker中编译YOLOv8-Pose C Demo并在开发板运行实践》。
将C Demo移植到安卓应用端的相关知识,请参考博文《手把手部署YOLOv5到RK3588安卓端:NPU加速与JNI/C/Kotlin接口开发指南》。
上一次移植,请参考《RK3588芯片NPU的使用:PPOCRv4例子在安卓系统部署》,解决图像格式问题,很重要。

四、重要源码解析

4.1 init_yolov8_pose_model方法

本函数主要任务是YOLOv8模型在RKNN框架下的初始化、属性查询和配置保存。
函数源码如下:

int init_yolov8_pose_model(const char *model_path, rknn_app_context_t *app_ctx)
{int ret;// 1.初始化RKNN上下文rknn_context ctx = 0;ret = rknn_init(&ctx, (char *)model_path, 0, 0, NULL);if (ret < 0){printf("rknn_init fail! ret=%d\n", ret);return -1;}// 2.查询模型的输入输出数量rknn_input_output_num io_num;ret = rknn_query(ctx, RKNN_QUERY_IN_OUT_NUM, &io_num, sizeof(io_num));if (ret != RKNN_SUCC){printf("rknn_query fail! ret=%d\n", ret);return -1;}printf("model input num: %d, output num: %d\n", io_num.n_input, io_num.n_output);// 3.获取输入张量属性printf("input tensors:\n");rknn_tensor_attr input_attrs[io_num.n_input];memset(input_attrs, 0, sizeof(input_attrs));for (int i = 0; i < io_num.n_input; i++){input_attrs[i].index = i;ret = rknn_query(ctx, RKNN_QUERY_INPUT_ATTR, &(input_attrs[i]), sizeof(rknn_tensor_attr));if (ret != RKNN_SUCC){printf("rknn_query fail! ret=%d\n", ret);return -1;}dump_tensor_attr(&(input_attrs[i]));}// 4.获取输出张量属性printf("output tensors:\n");rknn_tensor_attr output_attrs[io_num.n_output];memset(output_attrs, 0, sizeof(output_attrs));for (int i = 0; i < io_num.n_output; i++){output_attrs[i].index = i;ret = rknn_query(ctx, RKNN_QUERY_OUTPUT_ATTR, &(output_attrs[i]), sizeof(rknn_tensor_attr));if (ret != RKNN_SUCC){printf("rknn_query fail! ret=%d\n", ret);return -1;}dump_tensor_attr(&(output_attrs[i]));}// 5.保存配置到应用上下文app_ctx->rknn_ctx = ctx;// 6.判断模型是否量化:检查第一个输出张量是否是非FP16的仿射量化类型,设置is_quant标志,用于后续反量化处理。if (output_attrs[0].qnt_type == RKNN_TENSOR_QNT_AFFINE_ASYMMETRIC && output_attrs[0].type != RKNN_TENSOR_FLOAT16){app_ctx->is_quant = true;}else{app_ctx->is_quant = false;}// 7. 复制输入输出属性到应用上下文:动态分配内存并拷贝输入输出属性,保存到app_ctx以便后续访问。app_ctx->io_num = io_num;app_ctx->input_attrs = (rknn_tensor_attr *)malloc(io_num.n_input * sizeof(rknn_tensor_attr));memcpy(app_ctx->input_attrs, input_attrs, io_num.n_input * sizeof(rknn_tensor_attr));app_ctx->output_attrs = (rknn_tensor_attr *)malloc(io_num.n_output * sizeof(rknn_tensor_attr));memcpy(app_ctx->output_attrs, output_attrs, io_num.n_output * sizeof(rknn_tensor_attr));// 8. 解析输入张量维度if (input_attrs[0].fmt == RKNN_TENSOR_NCHW){printf("model is NCHW input fmt\n");app_ctx->model_channel = input_attrs[0].dims[1];app_ctx->model_height = input_attrs[0].dims[2];app_ctx->model_width = input_attrs[0].dims[3];}else{printf("model is NHWC input fmt\n");app_ctx->model_height = input_attrs[0].dims[1];app_ctx->model_width = input_attrs[0].dims[2];app_ctx->model_channel = input_attrs[0].dims[3];}printf("model input height=%d, width=%d, channel=%d\n",app_ctx->model_height, app_ctx->model_width, app_ctx->model_channel);return 0;
}

4.1.1 rknn_init初始化

rknn_init初始化函数功能为创建rknn_context对象、加载RKNN模型以及根据flag和rknn_init_extend结构体执行特定的初始化行为。
函数原型

int rknn_init(rknn_context* context,      // 输出参数:返回的 RKNN 上下文句柄void* model,                // 输入参数:模型数据或模型文件路径uint32_t size,              // 输入参数:模型数据的大小(字节数)uint32_t flag,              // 输入参数:初始化标志位(扩展选项)rknn_in

相关文章:

  • 【Hive入门】Hive数据导出完全指南:从HDFS到本地文件系统的专业实践
  • form表单提交前设置请求头request header及文件下载
  • 佐航BYQ2321直阻变比二合一全面升级!
  • Linux进程地址空间
  • Zephyr kernel Build System (CMake)介绍
  • 如何配置Spark
  • 技术视界 | 从自然中获取智慧: 仿生机器人如何学会“像动物一样思考和行动”
  • 基于 Python(selenium) 的今日头条定向爬虫:根据输入的关键词在今日头条上进行搜索,并爬取新闻详情页的内容
  • 使用spring boot vue 上传mp4转码为dash并播放
  • Pycharm(六):可变与不可变类型
  • 3.3 Spring Boot文件上传
  • 2025年深度学习模型发展全景透视(基于前沿技术突破与开源生态演进的交叉分析)
  • 【AI插件开发】Notepad++ AI插件开发1.0发布和使用说明
  • Linux系统下的常用网络命令
  • 如何在SOLIDWORKS中高效管理文件属性?
  • 第十二届蓝桥杯 2021 C/C++组 直线
  • macOS 更新后找不到钥匙串访问工具的解决方案
  • Flutter Dart中的函数参数 默函数的定义 可选参数 箭头函数 匿名函认参数 命名参类数 闭包等
  • 如何通过python连接hive,并对里面的表进行增删改查操作
  • 信奥赛之c++基础(计算机存储+数据类型转换)
  • 乌称泽连斯基与特朗普进行简短会谈
  • 新闻1+1丨应对外部冲击,中央政治局会议释放哪些信号?
  • 美联储官员:货币政策不会立即改变,金融市场波动或致美国经济增长承压
  • 见微知沪|最大力度消费补贴,最大程度满足人们对美好生活的向往
  • “中华优秀科普图书榜”2024年度榜单揭晓
  • 安徽临泉一小区交付后多楼层现裂缝,专家组论证称不影响安全