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

yolo_RK3588系列(三)

一、前言

接着上一篇,大概讲解了使用在主机上使用yolov训练好了自己的模型,接下来讲解如何将模型部署到RK3588上。

二、格式转换

2.1 转化成.onnx格式

我们使用yolo训练出来的权重文件格式是.pt格式,但是部署到rk3588上所需要的格式是.rknn格式,这里的话就需要进行格式转换,但是.pt格式使用工具的话没有直接转成.rknn格式的工具,这里只有先将其转化成通用的权重格式.onnx格式。

yolo官方提供了export.py文件用于进行权重格式的转换,下面是运行权重文件的入口参数,这个和训练文件大同小异,我们只需要关注“--data”   “--weights”,'--imgsz',其他的参数按照自己的需要进行修改。

最重要的'--include'里面的default=['onnx']。

def parse_opt():parser = argparse.ArgumentParser()parser.add_argument('--data', type=str, default=ROOT / './data/finger.yaml', help='dataset.yaml path')parser.add_argument('--weights', nargs='+', type=str, default=ROOT / './runs/train/exp10/weights/yolov5s_finger_2480.pt', help='model.pt path(s)')parser.add_argument('--imgsz', '--img', '--img-size', nargs='+', type=int, default=[480, 480], help='image (h, w)')parser.add_argument('--batch-size', type=int, default=1, help='batch size')parser.add_argument('--device', default='cpu', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')parser.add_argument('--half', action='store_true', help='FP16 half-precision export')parser.add_argument('--inplace', action='store_true', help='set YOLOv5 Detect() inplace=True')parser.add_argument('--keras', action='store_true', help='TF: use Keras')parser.add_argument('--optimize', action='store_true', help='TorchScript: optimize for mobile')parser.add_argument('--int8', action='store_true', help='CoreML/TF INT8 quantization')parser.add_argument('--dynamic', action='store_true', help='ONNX/TF/TensorRT: dynamic axes')parser.add_argument('--simplify', action='store_true', help='ONNX: simplify model')parser.add_argument('--opset', type=int, default=12, help='ONNX: opset version')parser.add_argument('--verbose', action='store_true', help='TensorRT: verbose log')parser.add_argument('--workspace', type=int, default=4, help='TensorRT: workspace size (GB)')parser.add_argument('--nms', action='store_true', help='TF: add NMS to model')parser.add_argument('--agnostic-nms', action='store_true', help='TF: add agnostic NMS to model')parser.add_argument('--topk-per-class', type=int, default=100, help='TF.js NMS: topk per class to keep')parser.add_argument('--topk-all', type=int, default=100, help='TF.js NMS: topk for all classes to keep')parser.add_argument('--iou-thres', type=float, default=0.45, help='TF.js NMS: IoU threshold')parser.add_argument('--conf-thres', type=float, default=0.25, help='TF.js NMS: confidence threshold')parser.add_argument('--include',nargs='+',default=['onnx'],help='torchscript, onnx, openvino, engine, coreml, saved_model, pb, tflite, edgetpu, tfjs')parser.add_argument('--rknpu', action='store_true', help='RKNN npu platform')opt = parser.parse_args()print_args(vars(opt))return opt

然后执行命令,这里转换成功后就会生成上图的.onnx格式的权重文件。

python  ./export.py --rknpu

2.2 转化成.rknn格式

1、rk官方github提供了相关的demo资料,可以在去下面地址下载:

https://github.com/airockchip/rknn-toolkit2

2、文件的大概目录如下,在文件里面有如图所示的test.py文件,里面就有转化为.rknn的例子并且顺便对图片进行推理的完整流程。

3、在test.py文件中

# Model from https://github.com/airockchip/rknn_model_zoo
ONNX_MODEL = './yolov5s_finger_2480.onnx'
RKNN_MODEL = './yolov5s_finger_2480_nq.rknn'
IMG_PATH = './out_2216.jpg'
DATASET = './dataset.txt'

ONNX_MODEL 就是上面pt格式转化成onnx格式的权重文件

RKNN_MODEL  就是转化生成的.onnx权重文件

IMG_PATH    推理图片的路径

DATASET   也是推理图片的名称

然后运行生成后即可生成.rknn格式权重文件,以及图片的推理结果,结果如下:

4、这里有一点需要确认,在生成.onnx格式权重文件的时候,可以看在VScode使用netron工具参看自己的网络模型,特别是输出端的参数维度是否和他提供的demo一直,不然在板端推理处理数据的时候肯定会有问题,模型的输出如下(一个输出):

三、模型的板端部署

1、NPU驱动版本确认

查询命令:

dmesg | grep-i rknpu

cat /sys/kernel/debug/rknpu/version

cat /sys/kernel/debug/rknpu/driver_version

cat /proc/debug/rknpu/driver_version

查询结果:

RKNPU driver: vX.X.X15

Rockchip的固件均自带RKNPU驱动。若以上命令均查询不到NPU驱动版本,则可能为第三方固件未安装RKNPU驱动,需要打开kernel config文件的“CONFIG_ROCKCHIP_RKNPU=y”选项,重新编译内核驱动并烧录。建议RKNPU驱动版本>=0.9.2。

2、检查 RKNPU2 环境是否安装

如果能够启动 rknn_server 服务,则代表板端已经安装 RKNPU2 环境

# 启动

rknn_serverrestart_rknn.sh

如果出现以下输出信息,则代表启动rknn_server服务成功,即已经安装RKNPU2环境

start rknn server, version: x.x.x

3、检查版本是否一致

# 查询rknn_server版本

strings /oem/usr/bin/rknn_server | grep-i"rknn_server version"

# 查询librknnmrt.so库版本

strings /oem/usr/lib/librknnmrt.so | grep-i"librknnmrt version"

如果出现以下输出信息,则代表rknn_server版本为 x.x.x,librknnmrt.so 的版本为 x.x.x

rknn_server version: x.x.x

librknnmrt version: x.x.x

4、运行demo代码推理

在main.cc文件中可以看到,入口参数1是.rknn权重文件的路径,参数2是需要推理的图片路径。

还有一个out_path,是推理结果图片文件路径名。

if (argc < 3){printf("Usage: %s <rknn model> <input_image_path> <resize/letterbox> <output_image_path>\n", argv[0]);return -1;}int ret;rknn_context ctx;size_t actual_size = 0;int img_width = 0;int img_height = 0;int img_channel = 0;const float nms_threshold = NMS_THRESH;      // 默认的NMS阈值const float box_conf_threshold = BOX_THRESH; // 默认的置信度阈值struct timeval start_time, stop_time;char *model_name = (char *)argv[1];char *input_path = argv[2];std::string option = "letterbox";std::string out_path = "./out.jpg";if (argc >= 4){option = argv[3];}if (argc >= 5){out_path = argv[4];}

在postprocess.h文件中:

NMS阈值和BOX阈值根据直接的需要进行更改,还有自己模型的类别数量需要修改。

#define OBJ_NAME_MAX_SIZE 16
#define OBJ_NUMB_MAX_SIZE 64
#define OBJ_CLASS_NUM 3
#define NMS_THRESH 0.45
#define BOX_THRESH 0.35
#define PROP_BOX_SIZE (5 + OBJ_CLASS_NUM)

关键点:

一定要核对好推理出来的输出数据参数和你自己权重文件输出的参数是对应的,不然就需要自己去处理推理后的数据,然后画框还原了。

四、推理结果

下面是运行demo程序显示的一些信息,里面会显示该模型三个输出的纬度,输入的格式为NHWC

root@ATK-DLRK3588:/rknn/yolov5# ./rknn_yolov5_finger_image ./yolov5s_finger_480.rknn ./frame_2.jpg 
post process config: box_conf_threshold = 0.60, nms_threshold = 0.70
Loading mode...
sdk version: 1.5.2 (c6b7b351a@2023-08-23T15:28:22) driver version: 0.9.2
model input num: 1, output num: 3
  index=0, name=images, n_dims=4, dims=[1, 480, 480, 3], n_elems=691200, size=691200, w_stride = 480, size_with_stride=691200, fmt=NHWC, type=INT8, qnt_type=AFFINE, zp=-128, scale=0.003922
  index=0, name=output0, n_dims=4, dims=[1, 24, 60, 60], n_elems=86400, size=86400, w_stride = 0, size_with_stride=122880, fmt=NCHW, type=INT8, qnt_type=AFFINE, zp=-128, scale=0.003891
  index=1, name=286, n_dims=4, dims=[1, 24, 30, 30], n_elems=21600, size=21600, w_stride = 0, size_with_stride=30720, fmt=NCHW, type=INT8, qnt_type=AFFINE, zp=-128, scale=0.003835
  index=2, name=288, n_dims=4, dims=[1, 24, 15, 15], n_elems=5400, size=5400, w_stride = 0, size_with_stride=7680, fmt=NCHW, type=INT8, qnt_type=AFFINE, zp=-128, scale=0.003606
model is NHWC input fmt
model input height=480, width=480, channel=3
Read ./frame_2.jpg ...
img width = 480, img height = 800
resize image with letterbox
once run use 15.981000 ms
loadLabelName ./finger_labels_list.txt
two @ (58 223 338 474) 0.591172
save detect result to ./out.jpg
loop count = 10 , average run  11.136900 ms

三个模型输出的纬度就我们训练好的权重一致:

画框结果:

最后,其实demo也提供了视频流的识别,通过运行该demo就可以完成视频实时的识别,以及后续的相关应用了。

http://www.dtcms.com/a/341036.html

相关文章:

  • mac电脑软件左上角的关闭/最小化/最大化按钮菜单的宽度和高度是多少像素
  • ijkplayer Android 编译
  • strncpy 函数使用及其模拟实现
  • AI重塑软件测试:质量保障的下一站
  • 成本管控:餐饮利润的隐形守护者
  • Zemax光学设计输出3D
  • 4位量化:常规的线性层被替换成了4位线性层(48)
  • 酶 EC number 预测工具CLEAN的安装和使用
  • QT官方库头文件找不到(添加模块方法)
  • C++模板元编程:从SFINAE到Concepts的进化史
  • mac 搭建docker-compose,部署docker应用
  • AI on Mac, Your Way!全本地化智能代理,隐私与性能兼得
  • pcl求平面点云的边界凸包点
  • Frida Hook Android Activity生命周期全方法监控方案
  • 哈希:字母异位词分组
  • RHCA07-Linux跟踪工具及CPU调优
  • Linux I/O 多路复用实战:深入剖析 Select 与 Poll
  • capsh 命令详解
  • 【机器学习深度学习】Ollama、vLLM、LMDeploy对比:选择适合你的 LLM 推理框架
  • Objective-C 版本的 LiveEventBus 效果
  • vue+openlayers示例:适配arcgis矢量瓦片服务以及样式(附源码下载)
  • 英伟达Blackwell架构下的中国特供版AI芯片:B30A与RTX 6000D,是技术妥协还是市场新策略?
  • 基于单片机太阳能充电器/太阳能转换电能
  • C端高并发项目都有哪些
  • Angular由一个bug说起之十八:伴随框架升级而升级ESLint遇到的问题与思考
  • C++围绕音视频相关的资料都有哪些?如何进行学习
  • 实现自己的AI视频监控系统-第一章-视频拉流与解码2
  • 【ansible】4.实施任务控制
  • 【沉浸式解决问题】peewee.ImproperlyConfigured: MySQL driver not installed!
  • 亚马逊运营破局:销量与ACOS的动态平衡之道