当前位置: 首页 > news >正文

STM32与OpenCV实现低成本人脸红外测温仪

1. 项目概述

这个基于STM32和OpenCV的人脸红外测温仪项目,是我在疫情期间开发的一个实用型嵌入式系统。它完美结合了嵌入式硬件的数据采集能力和计算机视觉的目标识别技术,实现了非接触式的体温监测功能。整套系统由下位机(STM32F103C8T6+MLX90614)和上位机(Qt+OpenCV)两部分组成,通过串口通信实现数据交互。

提示:这个项目特别适合电子工程、计算机相关专业的学生作为毕业设计,也适用于创客爱好者制作实用的防疫设备。整套硬件成本可以控制在100元以内。

我在开发过程中遇到了不少坑,比如MLX90614的温度漂移问题、OpenCV人脸检测的误报问题等,这些都会在后续章节详细说明解决方案。这个系统实测精度可以达到±0.3℃,响应时间小于500ms,完全满足日常体温筛查的需求。

2. 硬件系统设计

2.1 核心硬件选型

STM32F103C8T6最小系统

作为项目的主控芯片,我选择了经典的"蓝莓派"开发板,主要基于以下几点考虑:

  • 价格低廉(约15元)
  • 丰富的外设接口(I2C、USART等)
  • 充足的性能(72MHz主频)
  • 成熟的开发环境(Keil MDK)

实际使用中,我发现这款芯片的ADC精度一般,但用于处理MLX90614的数字输出完全够用。需要注意的是,市面上有些兼容板可能存在晶振不准的问题,建议购买正版ST芯片的开发板。

MLX90614红外测温模块

这是项目的核心传感器,我选择的是BAA版本(测量范围-20℃~120℃),主要参数:

  • 精度:±0.5℃(人体温度范围内)
  • 视场角:35°
  • 接口:I2C(默认地址0x5A)
  • 响应时间:<100ms

注意:市场上有些劣质模块可能存在校准问题,建议购买带原厂校准的版本(价格约50元)。我在测试中发现,某些山寨模块在环境温度变化时会出现明显漂移。

2.2 硬件电路设计

I2C接口电路

MLX90614通过I2C与STM32通信,具体连接方式:

MLX90614 STM32 VCC → 3.3V GND → GND SCL → PB6 SDA → PB7

我在PCB设计时特别注意了以下几点:

  1. SCL/SDA线上加了4.7kΩ上拉电阻
  2. 电源端并联了100nF去耦电容
  3. 传感器与MCU距离控制在10cm以内
串口通信电路

使用CH340G芯片实现USB转TTL,连接方式:

STM32 CH340G PA9(TX) → RXD PA10(RX) → TXD

调试时发现,如果波特率设置过高(如>500000bps),会出现数据丢失。最终选择115200bps作为通信速率,实测稳定可靠。

3. 下位机软件设计

3.1 温度采集实现

MLX90614的驱动代码主要包含以下几个部分:

// 初始化I2C接口 void MLX90614_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; I2C_InitTypeDef I2C_InitStruct; // 使能时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); // 配置GPIO GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStruct); // 配置I2C I2C_InitStruct.I2C_Mode = I2C_Mode_I2C; I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStruct.I2C_OwnAddress1 = 0x00; I2C_InitStruct.I2C_Ack = I2C_Ack_Enable; I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStruct.I2C_ClockSpeed = 100000; // 100kHz I2C_Init(I2C1, &I2C_InitStruct); I2C_Cmd(I2C1, ENABLE); } // 读取温度数据 float MLX90614_ReadTemp(void) { uint16_t rawData; float temp; // 读取RAM地址0x07的数据(物体温度) I2C_ReadData(I2C1, MLX90614_ADDR, 0x07, &rawData); // 数据转换 temp = (float)rawData * 0.02 - 273.15; return temp; }

实际使用中,我增加了滑动平均滤波算法来平滑数据波动:

#define FILTER_SIZE 5 float tempFilter[FILTER_SIZE]; uint8_t filterIndex = 0; float GetFilteredTemp(void) { float sum = 0; float newTemp = MLX90614_ReadTemp(); // 更新滤波器数组 tempFilter[filterIndex] = newTemp; filterIndex = (filterIndex + 1) % FILTER_SIZE; // 计算平均值 for(int i=0; i<FILTER_SIZE; i++) { sum += tempFilter[i]; } return sum / FILTER_SIZE; }

3.2 串口通信协议设计

为了确保数据传输的可靠性,我设计了一个简单的通信协议:

字节位置内容说明
00xAA帧头
1-2TempHigh/Low温度值(整数+小数)
3Checksum校验和(高低温字节异或)
40x55帧尾

对应的发送函数实现:

void USART_SendTemp(float temp) { uint8_t buffer[5]; uint16_t tempInt = (uint16_t)(temp * 100); // 转换为整数 buffer[0] = 0xAA; // 帧头 buffer[1] = (tempInt >> 8) & 0xFF; // 高字节 buffer[2] = tempInt & 0xFF; // 低字节 buffer[3] = buffer[1] ^ buffer[2]; // 校验和 buffer[4] = 0x55; // 帧尾 for(int i=0; i<5; i++) { USART_SendData(USART1, buffer[i]); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); } }

4. 上位机软件设计

4.1 Qt界面框架

上位机使用Qt5开发,主要界面元素包括:

  • 视频显示区域(QLabel)
  • 温度显示区域(QTextEdit)
  • 串口配置面板(QComboBox+QPushButton)
  • 报警状态指示灯(QLedIndicator)

界面布局采用QVBoxLayout和QHBoxLayout组合实现,确保在不同分辨率下都能正常显示。

4.2 OpenCV人脸检测实现

我测试了两种人脸检测算法,最终选择了效果更好的DNN模型:

// 加载预训练模型 cv::dnn::Net net = cv::dnn::readNetFromCaffe( "deploy.prototxt", "res10_300x300_ssd_iter_140000.caffemodel"); // 人脸检测函数 std::vector<cv::Rect> detectFaces(cv::Mat &frame) { cv::Mat blob = cv::dnn::blobFromImage(frame, 1.0, cv::Size(300, 300), cv::Scalar(104, 177, 123)); net.setInput(blob); cv::Mat detections = net.forward(); std::vector<cv::Rect> faces; for(int i=0; i<detections.size[2]; i++) { float confidence = detections.at<float>(0, 0, i, 2); if(confidence > 0.7) { // 置信度阈值 int x1 = static_cast<int>(detections.at<float>(0, 0, i, 3) * frame.cols); int y1 = static_cast<int>(detections.at<float>(0, 0, i, 4) * frame.rows); int x2 = static_cast<int>(detections.at<float>(0, 0, i, 5) * frame.cols); int y2 = static_cast<int>(detections.at<float>(0, 0, i, 6) * frame.rows); faces.emplace_back(x1, y1, x2-x1, y2-y1); } } return faces; }

提示:模型文件较大(约20MB),建议在程序启动时异步加载,避免界面卡顿。

4.3 温度显示与报警逻辑

温度显示的核心代码如下:

void MainWindow::updateTemperature(float temp) { QString tempStr = QString::number(temp, 'f', 1) + "℃"; // 报警逻辑 if(temp >= 37.3 || temp <= 35.0) { ui->tempLabel->setStyleSheet("color: red; font-size: 24px;"); // 语音报警(防重复) static QTime lastAlertTime; if(lastAlertTime.elapsed() > 10000) { // 10秒间隔 QTextToSpeech::say("体温异常,请复查!"); lastAlertTime.start(); } } else { ui->tempLabel->setStyleSheet("color: green; font-size: 24px;"); } ui->tempLabel->setText(tempStr); }

5. 系统集成与调试

5.1 硬件组装要点

  1. 传感器安装角度:MLX90614需要正对人脸,建议安装在支架上,与地面成15°仰角
  2. 测量距离:最佳测量距离为5-15cm,太远会导致精度下降
  3. 环境温度补偿:可以在STM32端增加DS18B20测量环境温度,对MLX90614读数进行补偿

5.2 常见问题排查

问题1:温度读数不稳定
  • 检查电源是否稳定(建议用示波器观察3.3V纹波)
  • 增加软件滤波算法(如前面提到的滑动平均)
  • 确保传感器与被测物体之间没有气流干扰
问题2:人脸检测漏检
  • 调整摄像头曝光参数
  • 尝试不同的检测模型(Haar/DNN)
  • 增加图像预处理(直方图均衡化)
问题3:串口通信失败
  • 检查波特率设置(两端必须一致)
  • 确认TX/RX线没有接反
  • 测试时可以先使用串口调试助手验证硬件连接

6. 项目优化与扩展

在实际使用中,我发现还可以做以下改进:

  1. 增加蓝牙/WiFi模块,实现无线数据传输
  2. 使用TinyML在STM32端实现轻量级人脸检测
  3. 开发手机APP替代Qt上位机
  4. 增加数据库存储功能,记录历史体温数据
  5. 结合RFID技术实现人员身份识别

这个项目最让我自豪的是它的实用性和低成本。在疫情期间,我帮助本地社区中心部署了5台这样的设备,大大提高了他们的防疫工作效率。整套系统的硬件成本不到100元,但实现了商业设备上千元的功能。

http://www.jsqmd.com/news/599407/

相关文章:

  • 电机类型详解与选型维护指南
  • 硫化物固态电池 vs 传统锂电池:性能、成本、安全性全方位对比
  • ABC452E
  • VSCode远程开发:SSH端口转发的实战指南
  • Alibaba Cloud Linux 3 Pro 安装phpredis
  • TP4054锂电池充电管理库原理与嵌入式工程实践
  • 当TVA“不听话”时:故障诊断与应急处理实战指南
  • python-langchain框架(3-7-提取pdf中的图片 )
  • Windows 10/11下,用VS2022命令行搞定StyleGAN2-ADA-Pytorch的C++插件编译报错
  • 从内存寻址到游戏操控:CE逆向分析扫雷核心机制的完整实践
  • 『n8n』遍历节点 Loop Over Items 的用法
  • ESP32实战:5分钟搞定CAN通信,从硬件连接到数据收发(附代码)
  • 激光熔覆熔池温度场与流场模拟仿真:基于现成模型的UDF分析中的高斯旋转体热源、VOF梯度计算、...
  • 示波器测量串口波特率的原理与实用技巧
  • 《米思米商品详情页前端性能优化实战》
  • 嵌入式开发:应用层与BSP的核心差异与职业发展
  • 一站式 AI 视频与图片创作平台 Veogen 实践分享
  • C# Exception 异常捕获
  • Avalonia 跨平台实时协作工具开发实战(支持Win、银河麒麟、统信UOS)
  • 【JEECG Boot】JEECG Boot 系统性知识体系全方位结构化总结
  • Arduino 3线驱动LCD:基于74HC595的轻量级LiquidCrystalSerial库
  • 战略级部署:企业如何规避TVA落地中的三大决策陷阱
  • Chronos:语言模型架构适配时序预测
  • 计算机毕业设计:Python智慧交通数据挖掘与预测系统 Flask框架 可视化 Requests爬虫 Arima模型 LSTM 深度学习(建议收藏)✅
  • TriCore MPU实战:从寄存器配置到安全任务切换
  • 现代Qt开发——入门 · 环境搭建 · 00 · Qt6 安装踩坑指南
  • 数据库性能优化与调优:从原理到实践
  • TVA供应商博弈论:从合同条款到交付验收的全流程风控指南
  • 用Python从零解析ARS548 4D毫米波雷达数据:一个完整的数据处理与可视化实战教程
  • Kubernetes与多集群服务网格实践