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.json中libtvm_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进行目标检测
ESP32-S3部署yolox_nano进行目标检测 一、生成模型部署项目01 环境02 配置TVM包03 模型量化3.1预处理3.2 量化 04 生成项目 二、烧录程序 手上的是ESP32-S3-WROOM-1 N8R8芯片,整个链路跑通了,但是识别速度太慢了,20秒一张图,所以暂…...
TCP传输数据的确认机制
实际的TCP收发数据的过程是双向的。 TCP采用这样的方式确认对方是否收到了数据,在得到对方确认之前,发送过的包都会保存在发送缓冲区中。如果对方没有返回某些包对应的ACK号,那么就重新发送这些包。 这一机制非常强大。通过这一机制…...
使用Ansible Expect模块实现自动化交互式任务
Ansible是一种功能强大的自动化工具,可用于自动化配置管理、部署和任务执行。其中的Expect模块是Ansible的一个重要组件,它允许我们自动化处理需要与交互式命令行进行交互的任务。本文将介绍如何使用Ansible的Expect模块,并提供一些示例来说明…...
51单片机独立按键以及矩阵按键的使用以及其原理--独立按键 K1 控制 D1 指示灯亮灭以及数码管显示矩阵按键 S1-S16 按下后键值 0-F
IO 的使用–按键 本文主要涉及8051单片机按键的使用,包括独立按键以及矩阵按键的使用以及其原理,其中代码实例包括: 1.独立按键 K1 控制 D1 指示灯亮灭 2.通过数码管显示矩阵按键 S1-S16 按下后键值 0-F 文章目录 IO 的使用--按键一、按键消抖二、独立按…...
chrome安装jsonview
写在前面 通过jsonview可以实现,当http响应时application/json时直接在浏览器格式化显示,增加可读性。本文看下如何安装该插件到chrome中。 1:安装 首先在这里 下载插件包,然后解压备用。接着在chrome按照如下步骤操作…...
使用TouchSocket适配一个c++的自定义协议
这里写目录标题 说明一、新建项目二、创建适配器三、创建服务器和客户端3.1 服务器3.2 客户端3.3 客户端发送3.4 客户端接收3.5 服务器接收与发送 四、关于同步Send 说明 今天有小伙伴咨询我,他和同事(c端)协商了一个协议,如果使…...
VSC改造MD编辑器及图床方案分享
VSC改造MD编辑器及图床方案分享 用了那么多md编辑器,到头来还是觉得VSC最好用。这次就来分享一下我的blog文件编辑流吧。 这篇文章包括:VSC下md功能扩展插件推荐、图床方案、blog文章管理方案 VSC插件 Markdown All in One Markdown Image - 粘粘图片…...
SpringBoot的依赖管理和自动配置
与其明天开始,不如现在行动! 文章目录 1 依赖管理机制2 自动配置机制2.1 初步理解2.2 完整流程 💎总结 1 依赖管理机制 为什么导入starter-web后所有相关依赖都会导入进来? 开发什么场景,导入什么场景启动器-spring-bo…...
linux 定时任务
使用 crontab Usage: crontab [-u user] [-e|-l|-r] Crontab 的格式说明如下: * 逗号(‘,’) 指定列表值。如: “1,3,4,7,8″ * 中横线(‘-’) 指定范围值 如 “1-6″, 代表 “1,2,3,4,5,6″ * 星号 (‘*’) 代表所有可能的值 */15 表示每 15 分钟执行一次 # Use the ha…...
增强现实中的真实人/机/环与虚拟人/机/环
在增强现实中,真实人与虚拟人、真实机器与虚拟机器、真实环境与虚拟环境之间有着密切的关系。增强现实技术通过将真实与虚拟相结合,打破了传统的现实世界与虚拟世界的界限,创造出了一种新的体验方式。真实人、真实机器和真实环境与其对应的虚…...
Python网络爬虫环境的安装指南
网络爬虫是一种自动化的网页数据抓取技术,广泛用于数据挖掘、信息搜集和互联网研究等领域。Python作为一种强大的编程语言,拥有丰富的库支持网络爬虫的开发。本文将为你详细介绍如何在你的计算机上安装Python网络爬虫环境。 一、安装python开发环境 进…...
【MyBatis系列】MyBatis字符串问题
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
【Java】构建表达式二叉树和表达式二叉树求值
问题背景 1. 实现一个简单的计算器。通过键盘输入一个包含圆括号、加减乘除等符号组成的算术表达式字符串,输出该算术表达式的值。要求: (1)系统至少能实现加、减、乘、除等运算; (2)利用二叉…...
采用Python 将PDF文件按照页码进行切分并保存
工作中经常会遇到 需要将一个大的PDF文件 进行切分,比如仅需要大PDF文件的某几页 或者连续几页,一开始都是用会员版本的WPS,但是对于程序员,就是要采用技术白嫖 这里就介绍一个 python的PDF 包 PyPDF2 其安装方式也很简单 p…...
H264视频编码原理
说到视频,我们首先想到的可能就是占内存。我们知道一个视频是由一连串图像序列组成的,视频中图像一般是 YUV 格式。假设有一个电影视频,分辨率是 1080P,帧率是 25fps,并且时长是 2 小时,如果不做视频压缩的…...
UDP实现群聊
代码: import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.net.*; import java.io.IOException; import java.lang.String;public class liaotian extends JFrame{private static final int DEFAULT_PORT8899;private JLabel stateLB…...
服务器部署网易开源TTS | EmotiVoice部署教程
一、环境 ubuntu 20.04 python 3.8 cuda 11.8二、部署 1、docker方式部署 1.1、安装docker 如何安装docker,可以参考这篇文章 1.2、拉取镜像 docker run -dp 127.0.0.1:8501:8501 syq163/emoti-voice:latest2、完整安装 安装python依赖 conda create -n Emo…...
贪心算法和动态规划
目录 一、简介 二、贪心算法案例:活动选择问题 1.原理介绍 三、动态规划案例:背包问题 1.原理介绍 四、贪心算法与动态规划的区别 五、总结 作者其他文章链接 正则表达式-CSDN博客 深入理解HashMap:Java中的键值对存储利器-CSDN博客…...
jsp 设备预约管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
一、源码特点 JSP 设备预约管理系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0…...
Python:核心知识点整理大全10-笔记
目录 5.4 使用 if 语句处理列表 5.4.1 检查特殊元素 toppings.py 5.4.2 确定列表不是空的 5.4.3 使用多个列表 5.5 设置 if 语句的格式 5.6 小结 第6章 字 典 6.1 一个简单的字典 alien.py 6.2 使用字典 6.2.1 访问字典中的值 6.2.2 添加键—值对 6.2.3 先创建一…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
沙箱虚拟化技术虚拟机容器之间的关系详解
问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西,但是如果把三者放在一起,它们之间到底什么关系?又有什么联系呢?我不是很明白!!! 就比如说: 沙箱&#…...
32单片机——基本定时器
STM32F103有众多的定时器,其中包括2个基本定时器(TIM6和TIM7)、4个通用定时器(TIM2~TIM5)、2个高级控制定时器(TIM1和TIM8),这些定时器彼此完全独立,不共享任何资源 1、定…...
验证redis数据结构
一、功能验证 1.验证redis的数据结构(如字符串、列表、哈希、集合、有序集合等)是否按照预期工作。 2、常见的数据结构验证方法: ①字符串(string) 测试基本操作 set、get、incr、decr 验证字符串的长度和内容是否正…...
工厂方法模式和抽象工厂方法模式的battle
1.案例直接上手 在这个案例里面,我们会实现这个普通的工厂方法,并且对比这个普通工厂方法和我们直接创建对象的差别在哪里,为什么需要一个工厂: 下面的这个是我们的这个案例里面涉及到的接口和对应的实现类: 两个发…...
Pandas 可视化集成:数据科学家的高效绘图指南
为什么选择 Pandas 进行数据可视化? 在数据科学和分析领域,可视化是理解数据、发现模式和传达见解的关键步骤。Python 生态系统提供了多种可视化工具,如 Matplotlib、Seaborn、Plotly 等,但 Pandas 内置的可视化功能因其与数据结…...
智能体革命:企业如何构建自主决策的AI代理?
OpenAI智能代理构建实用指南详解 随着大型语言模型(LLM)在推理、多模态理解和工具调用能力上的进步,智能代理(Agents)成为自动化领域的新突破。与传统软件仅帮助用户自动化流程不同,智能代理能够自主执行工…...
Go 并发编程基础:select 多路复用
select 是 Go 并发编程中非常强大的语法结构,它允许程序同时等待多个通道操作的完成,从而实现多路复用机制,是协程调度、超时控制、通道竞争等场景的核心工具。 一、什么是 select select 类似于 switch 语句,但它用于监听多个通…...
【Redis】Redis 的持久化策略
目录 一、RDB 定期备份 1.2 触发方式 1.2.1 手动触发 1.2.2.1 自动触发 RDB 持久化机制的场景 1.2.2.2 检查是否触发 1.2.2.3 线上运维配置 1.3 检索工具 1.4 RDB 备份实现原理 1.5 禁用 RDB 快照 1.6 RDB 优缺点分析 二、AOF 实时备份 2.1 配置文件解析 2.2 开启…...
