项目简介
本项目讨论的表情识别系统,是深度学习的一个应用,包含了多门学科知识。在实际生活中,表情识别在人机交互、安全、机器人制造、无人驾驶和医疗都有着一定的作用。本文将介绍基于嵌入式系统的表情识别系统的设计方法,将图像采集、人脸检测、表情识别和结果输出整合到树莓派中。项目使用USB摄像头实时采集数据,利用PyramidBox算法在复杂环境下检测人脸,将检测到的人脸截取,使用PaddlePaddle搭建MobileNetV2深度学习网络,使fer2013数据集训练模型,并对截取的人脸进行表情分类,最后将模型转化,部署到Raspberry Pi 3B+中,实现实时表情识别系统。
数据集及模型评估
训练模型的数据是Kaggele ICML2013 fer2013人脸表情识别数据集,将csv数据转图片后分别保存在不同类别的文件夹即可用来训练模型。项目选取happy、normal、surprised和angry四种类别辨识度较高的数据。读者可以自行添加其他的表情类别。数据按照70%、20%和10%的比例切分为训练集、验证集和测试集。训练集用于模型参数训练,验证集评估模型预测准确率,测试集在生成模型后使用,直观的感受模型效果。该数据集的图片数据,均为48*48的单通道数据。
训练好的MobileNetV2和DenseNet121模型,top1准确率分别为85.33%和87.50%。在树莓派3b+中,单张图片处理耗时30ms,整个项目在树莓派3b+中的fps为20~30。
最终效果(截取视频)
环境搭建
首先,搭建好程序运行的环境。本项目的数据准备、网络搭建、模型训练步骤均在百度Aistudio一站式开发实训平台完成,无需搭建训练环境。如果对平台不熟悉可以查看新手指南(https://ai.baidu.com/ai-doc/AISTUDIO/Tk39ty6ho)
模型最终部署在树莓派3b+中,其环境要求如下表
软件环境 | 硬件环境 | 软件依赖 |
raspberrypi | 树莓派3b+ | Paddle-Lite |
python3.7 | ||
opencv3 |
树莓派的系统推荐安装raspberrypi,官网即可下载系统镜像(https://www.raspberrypi.org/downloads/)
同时,项目需要调用opencv,推荐官网下载源码放入树莓派编译(https://opencv.org/releases/)
树莓派PaddleLite编译步骤
在树莓派中进行模型预测,需要安装Paddle-lite预测引擎。Paddle-Lite为Paddle-Mobile的升级版,定位支持包括手机移动端在内更多场景的轻量化高效预测,支持更广泛的硬件和平台,是一个高性能、轻量级的深度学习预测引擎。在保持和PaddlePaddle无缝对接外,也兼容支持其他训练框架产出的模型。完整使用文档位于:https://paddle-lite.readthedocs.io/zh/latest/
1.编译环境要求
gcc、g++、git、make、wget、python
cmake(建议使用3.10或以上版本)
具体步骤
# 1. Install basic software
apt update
apt-get install -y --no-install-recomends \
gcc g++ make wget python unzip
# 2. install cmake 3.10 or above
wget https://www.cmake.org/files/v3.10/cmake-3.10.3.tar.gz
tar -zxvf cmake-3.10.3.tar.gz
cd cmake-3.10.3
./configure
make
sudo make install
可通过cmake --version查看cmake是否安装成功。 至此,完成 Linux 交叉编译环境的准备。
2.编译PaddleLite
下载代码
git clone https://github.com/PaddlePaddle/Paddle-Lite.git
cd Paddle-Lite
git checkout
编译
./lite/tools/build.sh \
--build_extra=OFF \
--arm_os=armlinux \
--arm_abi=armv7hf \
--arm_lang=gcc \
tiny_publish
至此,环境搭建完成,开始进行模型训练。
模型训练
解压数据集并通过代码生成训练集文件夹、测试集文件夹以及相应的路径txt文件。
随机读取表情数据并存放在训练集、测试集文件夹中。
img = Image.open(os.path.join(image_path_pre, file))
if random.uniform(0, 1) <= train_ratio:
shutil.copyfile(os.path.join(image_path_pre, file), os.path.join(train_image_dir, file))
train_file.write("{0}\t{1}\n".format(os.path.join(train_image_dir, file), label_id))
else:
shutil.copyfile(os.path.join(image_path_pre, file), os.path.join(eval_image_dir, file))
eval_file.write("{0}\t{1}\n".format(os.path.join(eval_image_dir, file), label_id))
对数据进行预处理后,就开始搭建网络,训练网络。项目使用的网络是MobileNetV2,具体代码见文末链接。
训练好的模型文件保存在fer_model文件夹中,模型格式为Seperated Param:即参数信息分开保存在多个参数文件中,模型的拓扑信息保存在__model__文件中。训练好可以运行eval.py文件评估模型。
模型转化
PaddlePaddle训练好的模型保存fer-model文件夹中,训练的模型的保存格式是Seperated Param,这种格式的模型需要使用opt转化后才能成为paddle-lite可以预测的模型,才可以部署到树莓派中。
opt(opt完整文档:https://paddle-lite.readthedocs.io/zh/latest/user_guides/model_optimize_tool.html)可以将PaddlePaddle的部署模型格式转化为Paddle-Lite 支持的模型格式。
opt是 x86 平台上的可执行文件,需要在PC端运行:支持Linux终端和Mac终端。也可以使用Ai studio来完成转化工作。
首先需要运行下方指令,下载opt工具。
wget https://github.com/PaddlePaddle/Paddle-Lite/releases/download/v2.3.0/opt
运行下方指令,转化fer-model文件夹中的模型
#对模型进行转化
cd ~
#给opt工具加上可执行权限
chmod +x opt
#使用opt工具进行模型转化
./opt --model_dir=./fer-model \
--valid_targets=arm \
--optimize_out_type=naive_buffer \
--optimize_out=fer_opt
ls
树莓派项目部署
完整项目文件fer_detection.zip已经上传Aistudio:https://aistudio.baidu.com/aistudio/projectdetail/439995
下载fer_detection.zip,放入树莓派中解压,项目文件结构如下:
fer_detection
Paddle-Lite:
include
libs
code:
model
images
CMakeLists.txt
fer_detection.cc
run_camera.sh
将训练好的模型fer_opt.nb放入model文件夹中,并且修改run_camera.sh文件中的模型名称。 在终端执行
cd fer_detection
sudo ./run_camera.sh
即可运行表情识别项目。
部分代码
配置构建轻量级PaddlePredictor
//人脸检测模型配置
MobileConfig config;
//设置工作线程数
config.set_threads(CPU_THREAD_NUM);
//设置CPU能耗模式
config.set_power_mode(CPU_POWER_MODE);
//设置模型文件夹路径,加载老格式模型的接口。加载人脸检测模型(pymidbox模型)
config.set_model_dir(detect_model_dir);
//表情识别模型配置
MobileConfig config2;
config2.set_threads(CPU_THREAD_NUM);
config2.set_power_mode(CPU_POWER_MODE);
//设置模型文件,加载表情识别模型
config2.set_model_from_file(classify_model);
// 创建检测模型预测器
std::shared_ptr predictor = CreatePaddlePredictor(config);
// 创建分类模型预测器
std::shared_ptr predictor2 = CreatePaddlePredictor(config2);
读取摄像头数据
cv::VideoCapture cap(-1);
cap.set(CV_CAP_PROP_FRAME_WIDTH, 640);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, 480);
cv::Mat input_image;
cap >> input_image;
执行预测
cv::Mat img =RunModel(input_image,predictor,predictor2);
cv::Mat RunModel(cv::Mat img,
std::shared_ptr &predictor,
std::shared_ptr &predictor2) {
//部分代码
//设置输入,检测人脸
std::unique_ptr input_tensor0(std::move(predictor->GetInput(0)));
input_tensor0->Resize({1, 3, s_height, s_width});
auto* data = input_tensor0->mutable_data();
//执行预测
predictor->Run();
//获得结果,即人脸的位置信息。
std::unique_ptr output_tensor0(
std::move(predictor->GetOutput(0)));
auto* outptr = output_tensor0->data();
auto shape_out = output_tensor0->shape();
int64_t out_len = ShapeProduction(shape_out);
//表情分类输入为人脸检测结果,代码类似。
}
开机自启
个人感觉上电程序自启动会更方便,所以这里提供一种开机自启方法。如果不喜欢,忽略。
打开lxtermial输入
cd .config/autostart
nano fer.desktop
输入代码
[Desktop Entry]
Comment=my program
Exec=lxterminal --working-directory=/home/pi/fer_detection/code/ --command=./run_camera.sh
Terminal=flase
MultipleArgs=false
Type=Application
Name=fer
Categories=Application;Development;
StartupNotify=true
ctrl+o、回车保存ctrl+x退出
sudo reboot
总结
完整项目包括训练文件、移动端文件公开在AIStudio上,欢迎Fork。
https://aistudio.baidu.com/aistudio/projectdetail/439995
很详细
学习到了,刚刚好项目用到表情识别
小白发问:你是用手机做的摄像头吗?
哈哈哈这灵魂马赛克
其实这个场景挺适合手机部署?
树莓派有专用的摄像头,去搜一下就有了
啊这……原来是去年的项目,现在可好了,可以直接用paddleclas
部署现在不知道可不可以直接用easyedge
用paddlelite就可以
求问~
pi@raspberrypi:~/fer_detection/code $ sudo ./run_camera.sh
./run_camera.sh: 7: ./fer_detection: not found
在终端运行后显示这个不知道怎么解决
兄弟解决了吗