演示视频链接 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.tflite2.Firmware_ESP32包含三个ESP32工程文件夹,获取数据集1.GetDataset,识别数字手势2.NumberPred,模拟调节滚动条3.ProgressBar3.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 |
