基于 ESP-DL 的 7 类人脸情绪分类emotion_cls 组件从模型部署到推理实践【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution导读本文聚焦乐鑫 esp-iot-solution 仓库中examples/ai/esp_dl/emotion_recognition示例的核心组件emotion_cls完整讲解其在 ESP32-P4以及可复用的 ESP32-S31上运行 7 类人脸情绪分类模型的部署方式、推理接口与实测性能。读完本文你将掌握如何阅读并复用该组件的模型文件、Kconfig 配置、C 推理 API 与测试用例理解其量化精度与端侧工程化缓解策略并能在自己的 ESP-IDF 工程中一键接入情绪识别能力。组件概览一个开箱即用的情绪分类模型emotion_cls是 esp-iot-solution 中一个人脸情绪分类模型组件其核心信息浓缩在 组件 README 中项目值支持目标芯片ESP32-P4模型文件model/p4/emotion_cls.espdl输入图像尺寸100 x 100类别数7 类7 个情绪类别在源码中按固定顺序定义见 emotion_cls.cppconst char *kEmotionCategoryNames[] { surprise, // 惊讶 fear, // 恐惧 disgust, // 厌恶 happiness, // 高兴 sadness, // 悲伤 anger, // 愤怒 neutral, // 中性 };类别索引从 0 开始与模型输出 logits 的 top-1 索引一一对应。组件的idf_component.yml声明依赖espressif/esp-dl: 3.3.3目标平台仅允许esp32p4与esp32s31两种芯片这与组件 README 中Supported target: ESP32-P4的描述一致——ESP32-S31 直接复用同一份 ESP32-P4 模型文件见 idf_component.yml 与构建脚本中IDF_TARGET STREQUAL esp32p4 OR IDF_TARGET STREQUAL esp32s31的判断。实测推理延迟组件 README 给出了在 ESP32-P4 上单次推理的基准耗时模型名图像尺寸耗时usemotion_cls100 x 100136803即约 136.80 ms。该数据由组件的 test app 使用esp_timer_get_time()实测得到测试代码见 app_main.cppint64_t start_us esp_timer_get_time(); emotion_cls::result_t result cls.predict(img); int64_t elapsed_us esp_timer_get_time() - start_us;值得注意136.80 ms 是纯 emotion_cls 模型推理的时间。当在完整的 emotion_recognition 示例中与 face detection 模型并发运行时单次情绪分类的端到端平均耗时约为 870 ms这是模型与检测流水线共享计算资源导致的现象示例 README 中对此有明确说明。使用测试程序验证模型组件内置了一个可独立运行的 test app路径为components/emotion_cls/test_apps/。其主程序 app_main.cpp 的逻辑非常清晰通过dl::image::sw_decode_jpeg()将捆绑在固件中的test.jpg100x100 测试人脸图软解码为 RGB888 图像构造emotion_cls::EmotionCls cls;实例调用cls.predict(img)得到推理结果打印类别 ID、类别名、置信度分数与耗时。组件 README 给出了打包test.jpg运行 test app 后的典型串口输出I (1785) emotion_cls: Inference result: class_id6, class_nameneutral, score3.880 I (1785) emotion_cls: Inference time: 136803 us (136.80 ms) I (1795) main_task: Returned from app_main()测试用例还通过 partitions.csv 定义了nvs、phy_init与factory8 MB 应用分区三个分区以容纳模型与固件。C 推理接口解析emotion_cls对外暴露的核心类是EmotionCls定义于 emotion_cls.hpp。它有两个核心成员result_t结构体包含class_id类别索引、scoretop-1 类别的 softmax 概率、class_name类别名字符串指针predict()重载predict(const dl::image::img_t img)与带crop_area裁剪区域的版本后者支持传入人脸检测框坐标仅对 ROI 区域做分类。构造与预处理构造函数 emotion_cls.cpp 中完成两件关键工作模型加载通过dl::Model加载模型模型名缺省为emotion_cls.espdl模型位置由 Kconfig 选项CONFIG_EMOTION_CLS_MODEL_LOCATION决定预处理配置创建dl::image::ImagePreprocessor传入ImageNet 归一化参数mean/std 乘以 255 后映射到 [0, 255] 输入域m_preprocessor new dl::image::ImagePreprocessor( m_model, {123.675f, 116.28f, 103.53f}, {58.395f, 57.12f, 57.375f}, false);这与训练侧 PyTorch 使用的 ImageNet 统计量mean[0.485, 0.456, 0.406]、std[0.229, 0.224, 0.225]完全对应保证端侧推理与训练时数据分布一致。推理与结果解析predict()的执行链路为preprocess()→m_model-run()→ 取输出张量get_output()→ 按输出 dtype 调用get_top1_resultint8_t()或get_top1_resultint16_t()。该模板函数emotion_cls.cpp实现了一个数值稳定的 softmax遍历输出找到最大 logits 值best_quant及其索引best_index用ldexpf()将量化整数按张量exponent反量化为浮点 logits以expf(logit - max_logit)计算 softmax 分母最终score 1 / sum_exp即 top-1 类别概率。输出同时支持 INT8 与 INT16 两种量化 dtype这也印证了模型采用混合精度量化基础层 INT8、敏感层 INT16的设计。模型存储位置Kconfig 双模式组件通过 Kconfig 提供模型部署位置的可配置能力两个互斥选项EMOTION_CLS_MODEL_IN_FLASH_RODATA默认模型通过target_add_aligned_binary_data()以二进制方式链接进固件的 rodata 段源码中用extern const uint8_t emotion_cls_espdl[] asm(_binary_emotion_cls_espdl_start)直接引用EMOTION_CLS_MODEL_IN_FLASH_PARTITION模型作为独立分区数据烧录分区名为emotion_cls运行期从分区读取便于独立升级模型而无需重刷固件。此外还有一个未出现在菜单中的CONFIG_EMOTION_CLS_MODEL_IN_SDCARD分支见 CMakeLists.txt当启用时可跳过构建期打包逻辑暗示模型也可从 SD 卡加载。构建期模型打包依赖 ESP-DL 的fbs_loader工具链CMake 会调用pack_espdl_models.py将model/p4/emotion_cls.espdl打包为espdl_models/emotion_cls.espdl再根据所选位置嵌入固件或烧录到分区。模型训练与量化背景示例级佐证虽然组件 README 只聚焦部署但其所属示例的顶层 README 提供了模型的完整训练画像可作为理解组件行为的背景依据数据集RAF-DBReal-world Affective Faces Database训练集 12,271 张预对齐人脸图验证集 3,068 张骨干网络MobileNetV2ImageNet 预训练后微调分类头Linear(1280→256) → ReLU6 → Dropout(0.3) → Linear(256→7)输入112×112 RGB端侧推理时缩放到 100×100量化基于 ESP-PPQ 工具链的混合精度 INT8/INT16 量化。类别分布与量化精度RAF-DB 各类别训练样本数量差异悬殊这在量化后体现为精度分化FP32 验证集 vs INT8 混合精度验证集类别Train (FP32)Valid (FP32)Valid (INT8 混合)happiness100.0%95.4%94.2%neutral100.0%85.4%88.8%surprise100.0%82.1%76.0%sadness100.0%79.3%65.9%anger100.0%71.0%65.4%fear100.0%47.3%32.4%disgust100.0%38.1%29.4%Overall100.0%83.8%80.2%总体精度从 FP32 的 83.8% 略降至量化后的 80.2%但少数类fear/disgust由于样本严重不足fear 仅 281 张训练图而 happiness 约 4,800 张且与 surprise/anger 面部表情高度混淆量化噪声被进一步放大。这些是训练与量化层面的客观事实并非端侧代码问题。端侧缓解策略示例 README 同时给出了在设备端提升实用体验的三条工程手段分数门控Score gating将score 0.5的预测视为uncertain并跳过更新牺牲弱类召回换取更少的误报时间平滑Temporal smoothing对最近 5 帧的 top-1 结果做多数投票抑制单帧抖动导致的情绪跳变标签折叠Label collapsing若产品只需正向 / 中性 / 负向三分类将 7 类映射到 3 类同等权重下总体准确率可提升至 90% 以上。完整示例摄像头 → 检测 → 分类 → 屏显流水线emotion_cls组件被嵌入到完整的 emotion_recognition 示例中实现摄像头实时取流 → 人脸检测 → 情绪分类 → LCD 叠加显示的端到端流程。入口程序 emotion_recognition.cpp 展示了关键组装方式auto *panel app_lcd_init(); auto *camera new Camera(VIDEO_PIX_FMT_RGB565, 4, V4L2_MEMORY_MMAP, false); auto *overlay new EmotionOverlay(panel); EmotionPipeline::Config cfg { .camera camera, .face_detect_period_ms 100, // 人脸检测周期 .capture_period_ms 20, // 取帧周期 };运行期日志示例来源示例 READMEI (3657) emotion_pipeline: Face[0]: emotionsurprise score0.357 I (4605) emotion_pipeline: Face[0]: emotionneutral score0.886 I (5508) emotion_pipeline: Face[0]: emotionneutral score0.944 I (6386) emotion_pipeline: Face[1]: emotionneutral score0.399硬件要求运行完整示例需要以下任一开发板示例 README 明确列出ESP32-S31-Korvo集成 DVP 摄像头、800x480 RGB LCD 与 GT1151 触摸屏ESP32-P4-Function-EV-Board搭配 MIPI-CSI 摄像头SC2336与 1024x600 MIPI-DSI LCDEK79007。环境与构建ESP32-P4 目标要求ESP-IDF release/v5.5 及以后版本ESP32-S31 属于预览目标需使用ESP-IDF master 分支并以idf.py --preview set-target esp32s31配置烧录与监控命令将PORT替换为串口号退出串口监控按Ctrl-]idf.py -p PORT flash monitor小结emotion_cls组件为 ESP32-P4 / ESP32-S31 提供了一套完整、可复用的 7 类人脸情绪分类部署方案100x100输入、约136.8 ms纯推理耗时、INT8/INT16 混合量化模型、rodata/分区双模式存储以及开箱即用的 test app 验证入口。配合示例中的分数门控、时间平滑与标签折叠策略开发者可以将其快速接入实时摄像头情绪识别的产品原型。深入阅读 emotion_cls.cpp 与 emotion_cls.hpp 即可完全掌握其加载、预处理、推理与结果解析的完整调用链。【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考