RV1126笔记三十八:PaddleOCR部署到RV1126

news/2024/4/28 14:16:33/文章来源:https://blog.csdn.net/weixin_38807927/article/details/131619802

若该文为原创文章,转载请注明原文出处。

一、环境

1、硬件:正点原子RV1126开发板

2、环境:ubuntu16.04 

二、模型转换

训练后的模型不能直接使用在RV1126,需要转换一下模型

1、PaddlePaddle的模型转成推理模型

在前面有提过了;

训练模型保存为用于部署的推理模型

保存路径:output文件夹内

python tools/export_model.py -c "./configs/det/ch_ppocr_v2.0/ch_det_mv3_db_v2.0.yml_car_plate.yml" -o Global.pretrained_model="./output/ch_db_mv3/latest" Global.save_inference_dir="./output/"

2、转成onnx模型

PaddleOCR有一个专门的工具 paddle2onnx,

更多详情请参考Paddle2ONNX的Github主页

安装方法有两种:

# PIP 安装
$ pip install paddle2onnx
# 源码安装
$ git clone https://github.com/paddlepaddle/paddle2onnx
$ cd paddle2onnx 
$ python setup.py install

安装后把推理模型转成onnx

paddle2onnx --model_dir cell_screen_inference --model_filename inference.pdmodel --params_filename inference.pdiparams --save_file first_det.onnx --enable_dev_version True --opset_version 13 --enable_onnx_checker True

3、验证onnx模型

写一个简单的脚本, 验证一下这个onnx文件有没有问题:

# 导入 ONNX 库
import onnx
# 载入 ONNX 模型
onnx_model = onnx.load("model.onnx")
# 使用 ONNX 库检查 ONNX 模型是否合理
check = onnx.checker.check_model(onnx_model)
# 打印检查结果
print('check: ', check)

输出check none表示正确

4、转成静态模型

OCR的模型, 它的输入图片大小是不固定的, 而rknn模型必须使用固定的输入图片大小

转换命令为

python -m paddle2onnx.optimize --input_model first_det.onnx --output_model static_model.onnx  --input_shape_dict "{'x':[1,3,640,640]}"

三、RKNN NPU驱动升级

正点提供的rknn toolkit版本是1.7.1,这里需要升级成1.7.3

1、升级rknn toolkit

安装最新版本的rknn toolkit

https://github.com/rockchip-linux/rknn-toolkit/releases

我使用的是ubuntu版本,python使用3.8的版本,

解包之后, 使用pip install wheel, 然后 install requirement。

 2、升级npu驱动

升级npu的驱动, clong rknn的npu仓库: GitHub - rockchip-linux/rknpu

README写得很清楚,要注意的是有些是软链接,这个要注意。

四、转成RKNN模型

有两种方式转化:

一、使用py脚本转换

(大佬博客提供的)

import os
from rknn.api import RKNN
import numpy as np
import onnxruntime as ortonnx_model = 'model/static_model.onnx' #onnx路径
save_rknn_dir = 'model/static_model.rknn'#rknn保存路径def norm(img):mean = 0.5std = 0.5img_data = (img.astype(np.float32)/255 - mean) / stdreturn img_dataif __name__ == '__main__':# Create RKNN objectrknn = RKNN(verbose=True)# image = np.random.randn(1,3,32,448).astype(np.float32)  image = np.random.randn(1,3,640,640).astype(np.float32)   # image = np.random.randn(640,640,3,1).astype(np.float32)          # 创建一个np数组,分别用onnx和rknn推理看转换后的输出差异,检测模型输入是1,3,640,640 ,识别模型输入是1,3,32,448onnx_net = ort.InferenceSession(onnx_model)                         # onnx推理onnx_infer = onnx_net.run(None, {'x': norm(image)})          # 如果是paddle2onnx转出来的模型输入名字默认是 "x"# pre-process configprint('--> Config model')rknn.config(mean_values=[[127.5, 127.5, 127.5]], std_values=[[127.5, 127.5, 127.5]], reorder_channel='2 1 0', target_platform=['rv1126'], batch_size=4,quantized_dtype='asymmetric_quantized-u8')  # 需要输入为RGB#####需要转化一下均值和归一化的值# rknn.config(mean_values=[[0.0, 0.0, 0.0]], std_values=[[255, 255, 255]], reorder_channel='2 1 0', target_platform=['rv1126'], batch_size=1)  # 需要输入为RGBprint('done')# model_name = onnx_model[onnx_model.rfind('/') + 1:]# Load ONNX modelprint('--> Loading model %s' % onnx_model)ret = rknn.load_onnx(model=onnx_model)if ret != 0:print('Load %s failed!' % onnx_model)exit(ret)print('done')# Build modelprint('--> Building model')# rknn.build(do_quantization=False)ret = rknn.build(do_quantization=True, dataset='coco_dataset_1.txt', pre_compile=True)# do_quantization是否对模型进行量化,datase量化校正数据集,pre_compil模型预编译开关,预编译 RKNN 模型可以减少模型初始化时间,# 但是无法通过模拟器进行推理或性能评估if ret != 0:print('Build net failed!')exit(ret)print('done')# Export RKNN modelprint('--> Export RKNN model')ret = rknn.export_rknn(save_rknn_dir)if ret != 0:print('Export rknn failed!')exit(ret)ret = rknn.init_runtime(target='rv1126',device_id="a9d00ab1f032c17a")           # 两个参数分别是板子型号和device_id,device_id在双头usb线连接后通过 adb devices查看if ret != 0:print('init runtime failed.')exit(ret)print('done')# Inferenceprint('--> Running model')outputs = rknn.inference(inputs=[image])# perfprint('--> Begin evaluate model performance')perf_results = rknn.eval_perf(inputs=[image])              # 模型评估print('done')print()print("->>模型前向对比!")print("--------------rknn outputs--------------------")print(outputs[0])print()print("--------------onnx outputs--------------------")print(onnx_infer[0])print()std = np.std(outputs[0]-onnx_infer[0])print(std)                                # 如果这个值比较大的话,说明模型转换后不太理想rknn.release()

需要修改的地方有两个:

一:模型路径(onnx路径和rknn路径)

二:设备ID,ID为板子的ID,需要先查询出来,具体yolov5有提及。

二、使用rknn_model_zoo转换模型

下载最新版本的rknn_model_zoo,并把onnx转成RKNN,这个没测试过,具体自行测试。

测试在前面已经有测试过了,不在过多描述,代码git上有大佬开源,请自行去下载测试。

如有侵权,或需要完整代码,请及时联系博主。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_328299.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

InnoDB: Waiting for page_cleaner to finish flushing of buffer pool 解决方案

这个是因为linux系统时间,Mysql数据库时间,Mysql日志时间出现不一致导致的。 1、date -R 查询linux系统时间 中国标准时区东八区时区 2、mysql数据库的时间 3、在mysql的配置文件里面,定义好时间,时区一致。 问题解决。

Blender基础入门(0):下载和资源

文章目录 我个人的Blender专栏前言相关资料Blender和C4D如何选择视频资源BlenderBlender官网下载基础设置常用快捷键介绍空格键:跳出选择框ShiftA:跳出添加框选中物体按F9:显示物体属性 Blender能做到什么总结 我个人的Blender专栏 Blender简单教学 前…

【深度学习】受限玻尔兹曼机 (RBM) 初学者指南

一、说明 受限玻尔兹曼机(Restricted Boltzmann Machine,RBM)是一种基于能量模型的人工神经网络。它只有一个隐层,将输入层和隐层中的每个神经元互相连接,但不同层的神经元之间没有连接。RBM是一种无向的概率图模型&am…

一份非常牛逼的计算机相关技术资料整理

最近发现GitHub上一个非常牛逼的项目。作者收录了一整套 计算机相关的技术资料整理。 收录内容包括,但不仅仅包括,比如比较实用的计算机相关技术书籍,可以在短期之内入门的简单实用教程、一些技术网站以及一些写的比较好的博文。真的得给作者…

2023CCF CAT- 热身赛

NOIP普及组 字符串 排序2017 动态规划 递推 USACO 2001 贪心 牛客小白月赛12 说实话还是很喜欢打比赛,喜欢AC的感觉,但是这玩意咋越来越难了那。。。。。 扎心了,不是~~~~~ 当个爱好吧,还是很喜欢当年打比赛和队友相视一笑的样子…

WebGIS 信息系统-Element项目实战

WebGIS 信息系统-Element项目实战 Element的安装OpenLayers的安装采用直接引用的方式配置开发环境下载Vue文件下载Element文件下载OpenLayers文件 Element的安装 在项目的根目录中,首先按下 Shift鼠标右键,在弹出的右键菜单中选择“在此处打开命令行窗口…

libdrm编译调试

本文主要介绍libdrm的代码下载、编译和调试的工作。新版本的libdrm不再采用configure && make的方式编译,而是改用meson && ninja编译方式,近些年很多多媒体的开源软件包的构建系统有向后者靠拢的趋势,典型的比如gstream及其…

English Learning - L3 作业打卡 Lesson8 Day59 2023.7.4 周二

English Learning - L3 作业打卡 Lesson8 Day59 2023.7.4 周二 引言🍉句1: I started snowboarding, then I went back to work, then I went back to school.成分划分连读爆破语调 🍉句2: And just this past February, I won two back to back World C…

视频编码流程 YUV数据编码为H264数据

文章目录 1.视频编码流程2.实战demo3.相关编码知识点讲解1. 参数设置问题:2. 关于av_opt_set3. 关于码流设置 1.视频编码流程 2.实战demo #ifndef MAINBACK_C #define MAINBACK_C #endif // MAINBACK_C #include <stdint.h> #include <stdio.h> #include <stdl…

Go内存分配那些事,就这么简单!

这篇文章主要介绍Go内存分配和Go内存管理&#xff0c;会轻微涉及内存申请和释放&#xff0c;以及Go垃圾回收。 从非常宏观的角度看&#xff0c;Go的内存管理就是下图这个样子&#xff0c;我们今天主要关注其中标红的部分。 本文基于go1.11.2&#xff0c;不同版本Go的内存管理可…

Linux驱动开发:Linux内核启动流程详解

前言&#xff1a;Linux 内核同样作为 Linux 驱动开发的 “三巨头” 之一&#xff0c;Linux 内核的启动流程要比 uboot 复杂的多&#xff0c;涉及到的内容也更多。但秉持着 “知其然知其所以然” 的学习态度&#xff0c;作者将给读者朋友大致的过一遍 Linux 内核的启动流程。(考…

Java csv文件上传下载中的相关转换

目录 一. 需求二. List<Entity>转List<List<String>>2.1 实体类2.2 转换 三. 上传csv文件转List<Map>3.1 csv文件3.2 前台3.3 实体类3.4 转换3.5 效果 一. 需求 &#x1f914;项目中遇到了两个需求 1.查询数据库&#xff0c;得到List<Entity>这…

初阶C语言———操作符详解(2)

hello&#xff0c;我们又见面了&#xff0c;今天我们把操作符这一章节完结&#xff0c;那让我们一起来学习吧 逻辑操作符 &&逻辑与 ||逻辑或 这里我们要区分按位与和按位或还有逻辑与和逻辑或的区分。 1&2----->0 1&&2---->1 1|2----->3 1||2---…

嵌入式_Keil (MDK - ARM) 的调试步骤

目录 1. 编译 调试 2. 复位 全速运行 3. 单步调试 4. 逐步调试 5. 跳出调试 6. 运行到光标处 7. 跳转到暂停行 8. 调试窗口 首先为什么需要在 MDK 中进行程序的调试呢&#xff1f; 在 MDK 中进行程序调试的主要目的是识别和解决程序中的问题和错误。 比如说找到程序中…

【CANopen】周立功轻松入门CANopen笔记

前言 想学习些新东西了&#xff0c;原本想直接学学Ethercat&#xff0c;但是简单看了看对象字典啥的概念一头雾水的&#xff0c;决定先从CANopen开始&#xff0c;Ethercat看着头疼。Etehrcat和CANopen有挺多类似的地方。感谢ZLG的这个入门笔记&#xff0c;我似乎是看懂了些&am…

一、枚举类型——新特性(模式匹配-支配性)

switch 中 case 语句的顺序很重要。如果基类先出现&#xff0c;就会支配任何出现在后面的 case&#xff1a; Dominance.java JDK 17 sealed interface Base { }record Derived() implements Base { }public class Dominance {static String test(Base base) {return switch (ba…

视频行为识别(一)——综述

Deep Neural Networks in Video Human Action Recognition: A Review 本次分享的文章是2023年收录在计算机视觉领域的顶刊“CVPR”&#xff08;级别&#xff1a;视觉类TOP&#xff09;期刊上。该期刊详细信息可关注公众号 AI八倍镜 点击菜单项查询。 论文地址&#xff1a;http…

代码随想录二刷day46 | 动态规划之139.单词拆分

day46 139.单词拆分1.确定dp数组以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp[i] 139.单词拆分 题目链接 解题思路&#xff1a;单词就是物品&#xff0c;字符串s就是背包&#xff0c;单词能否组成字符串s&#xff0c;就是问物品能不能把背包装满…

第三章 SSD存储介质:闪存 3.4

3.4 闪存数据完整性 可采用以下数据完整性的技术确保用户数据不丢失&#xff1a; &#xff08;1&#xff09;ECC纠错&#xff1b; &#xff08;2&#xff09;RAID数据恢复&#xff1b; &#xff08;3&#xff09;重读&#xff08;Read Retry&#xff09;&#xff1b; &#xff…

vue 进阶---动态组件 插槽 自定义指令

目录 动态组件 如何实现动态组件渲染 使用 keep-alive 保持状态 keep-alive 对应的生命周期函数 keep-alive 的 include 属性和exclude属性 插槽 插槽的基础用法 具名插槽 作用域插槽 自定义指令 自定义指令的分类 私有自定义指令 全局自定义指令 了解 eslint 插件…