esp32-s3部署yolox_nano进行目标检测

2023-11-30 17:36

本文主要是介绍esp32-s3部署yolox_nano进行目标检测,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

ESP32-S3部署yolox_nano进行目标检测

      • 一、生成模型部署项目
        • 01 环境
        • 02 配置TVM包
        • 03 模型量化
          • 3.1预处理
          • 3.2 量化
        • 04 生成项目
      • 二、烧录程序

手上的是ESP32-S3-WROOM-1 N8R8芯片,整个链路跑通了,但是识别速度太慢了,20秒一张图,所以暂时还没打算进一步优化程序。
在这里插入图片描述

一、生成模型部署项目

官方指导文件:使用TVM自动生成模型部署项目

先下载onnx模型:yolox_nano.onnx,将下载好的yolox_nano.onnx放置在esp-dl/tutorial/evm_example路径下。

01 环境
  • ESP-IDF 5.0
  • 虚拟机Ubuntu 20.04
  • python环境
    在这里插入图片描述
02 配置TVM包

按官方文档下载完包后,设置环境变量PYTHONPATH

sudo vim ~/.bashrc
# 在文件的最后添加以下行,其中path-to-esp-dl更换为你的文件路径
export PYTHONPATH='$PYTHONPATH:/path-to-esp-dl/tools/tvm/python'
03 模型量化
3.1预处理
~/esp-dl $ cd tutorial/tvm_example
~/esp-dl/tutorial/tvm_example $ python -m onnxruntime.quantization.preprocess --input yolox_nano.onnx --output yolox_nano_opt.onnx
3.2 量化
  • 生成校准数据
import numpy as np
import cv2
import os# 图片路径
path = 'esp-dl/img/calib'# 读取图片并将它们保存为numpy数组
images = []
for filename in os.listdir(path):img = cv2.imread(os.path.join(path, filename))img_resized = cv2.resize(img, (416, 416))img_array = np.transpose(img_resized, (2, 0, 1))img_array = img_array / 255.0if img_array is not None:images.append(img_array)print(filename)# 将numpy数组保存为npy文件
np.save('esp-dl/tutorial/tvm_example/calib_416x416.npy', images)
  • 生成模型输入
import numpy as np
import cv2
import ospath = 'esp-dl/img/input.jpg'img = cv2.imread(path)
img_resized = cv2.resize(img, (416, 416))
img_array = np.transpose(img_resized, (2, 0, 1))
img_array = img_array / 255.0
images = [img_array]np.save('esp-dl/tutorial/tvm_example/input_416x416.npy', images)
  • 生成量化后的模型
~/esp-dl/tutorial/tvm_example $ python ../../tools/tvm/esp_quantize_onnx.py --input_model yolox_nano_opt.onnx --output_model yolox_nano_quant.onnx --calibrate_dataset calib_416x416.npy
Collecting tensor data and making histogram ...
Finding optimal threshold for each tensor using entropy algorithm ...
Number of tensors : 365
Number of histogram bins : 128 (The number may increase depends on the data it collects)
Number of quantized bins : 128
WARNING:root:Please use QuantFormat.QDQ for activation type QInt8 and weight type QInt8. Or it will lead to bad performance on x64.
04 生成项目
~/esp-dl/tutorial/tvm_example $ python ../../tools/tvm/export_onnx_model.py --model_path yolox_nano_quant.onnx --img_path input_416x416.npy --target_chip esp32s3 --out_path "." --template_path "../../tools/tvm/template_project_for_model/"
Model Information:
------------------
Input Name: images
Input Shape: (1, 3, 416, 416)
Input DType: float
Output Name: output
Output Shape: (1, 3549, 85)
Output DType: float
[17:21:47] /home/gansichen/Workspace/projects/local/framework/tvm/src/relay/transforms/convert_layout.cc:99: Warning: Desired layout(s) not specified for op: nn.max_pool2d
[17:21:47] /home/gansichen/Workspace/projects/local/framework/tvm/src/relay/transforms/convert_layout.cc:99: Warning: Desired layout(s) not specified for op: nn.max_pool2d
[17:21:47] /home/gansichen/Workspace/projects/local/framework/tvm/src/relay/transforms/convert_layout.cc:99: Warning: Desired layout(s) not specified for op: nn.max_pool2d
[17:21:47] /home/gansichen/Workspace/projects/local/framework/tvm/src/relay/transforms/convert_layout.cc:99: Warning: Desired layout(s) not specified for op: image.resize2d
[17:21:47] /home/gansichen/Workspace/projects/local/framework/tvm/src/relay/transforms/convert_layout.cc:99: Warning: Desired layout(s) not specified for op: image.resize2d
esp_dl_library_path: /home/zymidea/Desktop/esp32-cam/esp-dl
generated project in: ./new_project

二、烧录程序

烧录用的windows系统,将虚拟机中生成的new_project文件夹复制到PC端,打开ESP-IDF CMD

cd new_preject
idf.py set-target esp32s3
idf.py flash monitor

这是按照官方的教程进行烧录,但是模型太大会出现内存溢出esp32-template-project.elf section '.dram0.bss' will not fit in region 'dram0_0_seg' region 'dram0_0_seg' overflowed by 2141320 bytes

~/new_project $ idf.py size-components
...
Total sizes:                                                                               
Used static IRAM:   61042 bytes ( 301198 remain, 16.9% used)                                    .text size:   60015 bytes                                                                  .vectors size:    1027 bytes                                                         
Used stat D/IRAM: 2442376 bytes (-2096520 remain, 706.2% used) Overflow detected!              .data size:   11088 bytes                                                                  .bss  size: 2431288 bytes                                                             
Used Flash size : 3729295 bytes                                                                .text     :  473467 bytes                                                                  .rodata   : 3255572 bytes                                                             
Total image size: 3801425 bytes (.bin may be padded larger) 

在这里插入图片描述

找到new_project/build/project_description.jsonlibtvm_model.a静态文件的源代码。
在这里插入图片描述

官方指导片外RAM

需要调整的是将模型的权重文件保存到flash并将模型的输出存放在PSRAM,操作如下

// 打开/new_project/components/tvm_model/model/codegen/host/src/default_lib0.c// 代码最前面
// 增加一个头文件
#include "E:/Espressif/frameworks/esp-idf-v5.0.4/components/esp_common/include/esp_attr.h"// static struct global_const_workspace 将static改为const
const struct global_const_workspace// 代码最后面
// __attribute__((section(".bss.noinit.tvm"), aligned(16))) 将这句话注释掉
static EXT_RAM_BSS_ATTR uint8_t global_workspace[2422784]; // 增加宏EXT_RAM_BSS_ATTR
// 打开/new_project/main/output_data.h
const static _SECTION_ATTR_IMPL(".ext_ram.bss", __COUNTER__) __attribute__((aligned(16))) float output_data[42588] // 指定该数组存放到外部RAM的.ext_ram.bss段
~/new_project $ idf.py menuconfig

在这里插入图片描述
在这里插入图片描述
修改完毕S键保存,Esc键退出。

修改/new_project/partitions.csv分区表中的factory的大小,原本的3000多K存储模型权重不够,将其增大点,三个区的Offset都清空,生成过程它会自动匹配。

在这里插入图片描述

所有的修改完毕后再重新再看一下各个RAM的使用情况

~/new_project $ idf.py size-components
...
Used static IRAM:   61042 bytes ( 301198 remain, 16.9% used).text size:   60015 bytes.vectors size:    1027 bytes
Used stat D/IRAM:   19592 bytes ( 326264 remain, 5.7% used) .data size:   11088 bytes.bss  size:    8504 bytes 
Used Flash size : 3729203 bytes                                                                .text     :  473455 bytes                                                                  .rodata   : 3255492 bytes                                                             
Total image size: 3801333 bytes (.bin may be padded larger) 
...

在这里插入图片描述

最后重新烧录就能运行成功了。

~/new_project $ idf.py flash monitor

在这里插入图片描述

这篇关于esp32-s3部署yolox_nano进行目标检测的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/437913

相关文章

QT进行CSV文件初始化与读写操作

《QT进行CSV文件初始化与读写操作》这篇文章主要为大家详细介绍了在QT环境中如何进行CSV文件的初始化、写入和读取操作,本文为大家整理了相关的操作的多种方法,希望对大家有所帮助... 目录前言一、CSV文件初始化二、CSV写入三、CSV读取四、QT 逐行读取csv文件五、Qt如何将数据保存成CSV文件前言

通过Spring层面进行事务回滚的实现

《通过Spring层面进行事务回滚的实现》本文主要介绍了通过Spring层面进行事务回滚的实现,包括声明式事务和编程式事务,具有一定的参考价值,感兴趣的可以了解一下... 目录声明式事务回滚:1. 基础注解配置2. 指定回滚异常类型3. ​不回滚特殊场景编程式事务回滚:1. ​使用 TransactionT

Java中使用Hutool进行AES加密解密的方法举例

《Java中使用Hutool进行AES加密解密的方法举例》AES是一种对称加密,所谓对称加密就是加密与解密使用的秘钥是一个,下面:本文主要介绍Java中使用Hutool进行AES加密解密的相关资料... 目录前言一、Hutool简介与引入1.1 Hutool简介1.2 引入Hutool二、AES加密解密基础

Spring Boot项目部署命令java -jar的各种参数及作用详解

《SpringBoot项目部署命令java-jar的各种参数及作用详解》:本文主要介绍SpringBoot项目部署命令java-jar的各种参数及作用的相关资料,包括设置内存大小、垃圾回收... 目录前言一、基础命令结构二、常见的 Java 命令参数1. 设置内存大小2. 配置垃圾回收器3. 配置线程栈大小

SpringSecurity6.0 如何通过JWTtoken进行认证授权

《SpringSecurity6.0如何通过JWTtoken进行认证授权》:本文主要介绍SpringSecurity6.0通过JWTtoken进行认证授权的过程,本文给大家介绍的非常详细,感兴趣... 目录项目依赖认证UserDetailService生成JWT token权限控制小结之前写过一个文章,从S

使用Jackson进行JSON生成与解析的新手指南

《使用Jackson进行JSON生成与解析的新手指南》这篇文章主要为大家详细介绍了如何使用Jackson进行JSON生成与解析处理,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 核心依赖2. 基础用法2.1 对象转 jsON(序列化)2.2 JSON 转对象(反序列化)3.

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

Python使用自带的base64库进行base64编码和解码

《Python使用自带的base64库进行base64编码和解码》在Python中,处理数据的编码和解码是数据传输和存储中非常普遍的需求,其中,Base64是一种常用的编码方案,本文我将详细介绍如何使... 目录引言使用python的base64库进行编码和解码编码函数解码函数Base64编码的应用场景注意

Java进行文件格式校验的方案详解

《Java进行文件格式校验的方案详解》这篇文章主要为大家详细介绍了Java中进行文件格式校验的相关方案,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、背景异常现象原因排查用户的无心之过二、解决方案Magandroidic Number判断主流检测库对比Tika的使用区分zip

Java使用Curator进行ZooKeeper操作的详细教程

《Java使用Curator进行ZooKeeper操作的详细教程》ApacheCurator是一个基于ZooKeeper的Java客户端库,它极大地简化了使用ZooKeeper的开发工作,在分布式系统... 目录1、简述2、核心功能2.1 CuratorFramework2.2 Recipes3、示例实践3