演示视频链接 https://www.bilibili.com/video/BV1jK41117yV/
本项目是一个基于ESP32
的热成像手势识别系统,使用的传感器是AMG8833
,这是一个I2C接口的,输出8x8温度数值的热成像传感器阵列,系统对传感器输出的温度数组进行双三次插值,得到24x24的温度数值送入预训练的模型进行推理,进行手势分类,其中,识别数字手势使用图像4分类(背景,手势1,手势2,手势3)的卷积神经网络,识别调节手势使用图像5分类(背景,张开,合拢远,合拢近,交叉)的卷积神经网络。
网络模型的训练在PC端,是使用ESP32
串口回传的温度数据进行训练的,训练框架使用Keras
,量化工具使用TensorFlowLite
,训练完成的网络模型在边缘端ESP32
上进行部署,ESP32的开发平台为VScode
+PlatformIO IDE
+Arduino
,推理框架使用TensorFlowLite_ESP32
提供的API函数
项目文件夹包含内容如下:
1.NetworkModel
包含存有数据集的文件夹dataset
,模型训练脚本gesture_train.ipynb
,已量化和未量化的tflite网络文件model.tflite
,model_quantized.tflite
2.Firmware_ESP32
包含三个ESP32工程文件夹,获取数据集1.GetDataset
,识别数字手势2.NumberPred
,模拟调节滚动条3.ProgressBar
3.HardwareInfo
包含项目用到的硬件信息和datasheet4.Img
项目相关图片
使用SecureCRT
软件以日志(x.log)的形式保存串口回传的数据,波特率设定为921600,采样单个手势的650组温度值的时间大约为1min15s
ESP32启动后再连接SecureCRT,最后的log文件删除第一行和最后一行数据,避免因为SecureCRT的连接和断开导致单组数据不完整(一行不足576个温度值)
使用numpy.genfromtxt
读入温度数据,每一组温度数据都需要进行预处理,具体方法是减去均值(单组数据温度值相加除以576),再除以10,防止数值过大
卷积层使用5个3x3卷积核,池化层为2x2的Maxpooling池化,接下来是两层全连接(128,64),最后的softmax层对应网络模型的分类数,数5代表手势分5类
这里设置单个手势的模型训练样本数为600,测试样本数为50(即数字手势的总训练样本为2400,总测试样本为200)batchsize为10,在训练3个epoch后模型在测试集的精度就很高了(>99%),loss也降得非常低(<0.0001),因为数据集非常小,且网络学到的数据比较单一,后续会考虑增加数据集(如单个手势2000)并且进行数据增强,让模型的鲁棒性增加,泛化性能提高。
在Linux环境下使用xxd -i model_quantized.tflite > model.cpp
命令将tflite
文件转为16进制unsigned char
数组,数组包含了模型的权重参数和框架(TensorFlowLite_ESP32库会解析该模型数组),将model.cpp
导入ESP32工程文件的src
文件夹中,更改数组名称为alignas(8) const unsigned char g_model[]
,进行8字节对齐以及保存进Flash,更改长度名称为const int g_model_len
ST7789 LCDTFT | ESP32 DevKitC |
---|---|
CS | 15或接GND |
SDA | 23 |
SCL | 18 |
RES | 4 |
DC | 2 |
AMG8833 | ESP32 DevKitC |
---|---|
SDA | 21 |
SCL | 22 |