基于stm32+amg8833+openmv实现的人脸跟随测温仪
基于stm32+amg8833+openmv实现的人脸跟随测温仪
资料链接:
https://download.csdn.net/download/keepfightingbob/12609314
前言
本人第一次发博客,属实博客小白,想和各位一样把自己做的一些东西发布上来大家一起学习指点,同时也是对自己努力的一个记录,希望也能给到自己一个激励作用,该项目分pcb部分、stm32部分、openmv部分,和我的一位伙伴一起努力完成了这个小项目,由于第一次焊接pcb,如图部分零件没有焊接但并不影响目标效果,且由于是第一次焊接pcb怕因为自己的焊接出现问题,就没有将pcb板做成专门针对这个项目的主控板,采用stm32f103c8t6原理图进行设计。
欢迎各位指点批评,具体代码或其他资料我稍后上传,也可私信我。
概括
疫情期间设计并实现了一个基于STM32的人体追踪温度检测系统,结合电路设计要求与经济性,实时性,选择STM32F103C8T6微控制器作为主控芯片和AMG8833热成像温度传感器来实现对人体温度的检测,基于Openmv做图像处理实现人脸额头追踪,实现自动人体无接触式体温测量,实时显示在Oled液晶显示屏上,超过预定温度启动声光报警。报具体分析如下:
项目实物图
方案
本系统可以分为模拟红外温度传感器(内含环境温度测量)模块、放大电路模块、AD转换电路模块、MCU主控模块、声光报警模块、显示模块和电源模块,图像获取和处理模块。如下图1所示。所谓的模拟传感器就是传感器的输出是模拟量,而不是可以直接进行数据处理的数字量,所以他需要通过信号放大和AD转换等处理才能传输给单片机进行相关的处理。
首先模拟红外温度传感器接收人体发出的红外线,然后经过转换后输出对应的电压值,传感器同时通过片上温度传感器测量环境温度/传感器温度[1]。这两个红外温度传感器的输出量通过放大电路和AD转换电路处理后传输到MCU模块进行相关的处理(软件滤波、黑体校定等),然后通过LED模块显示相应的人体温度。
图像处理模块:采用摄像头获取图像信息,结合Opencv对图像进行分析处理,包括人脸检测,额头坐标获取结合,传输回单片机再调整云台,从而实现追踪。
在本方案中采用数字红外成像温度传感器代替模拟红外温度传感器。由于数字红外成像温度传感器内部集成了红外光学处理系统,热辐信号-电信号转换电路实现热辐射信号转电信号,运放电路、A/D转换电路、滤波电路和数字信号处理器,,所以只需通过传感器的数据接口就可以把传感器所测量的人体温度数据直接传输给MCU主控模块处理并显示。系统框图如下图
AMG8833温度传感器驱动和目标温度的计算
AMG8833是一种检测红外辐射量的热电堆型红外传感器。64个像素点将测量0°C至80°C(32°F至176°F)的温度,精度为+2.5°C(4.5°F)。它能在7米(23)英尺的距离内探测到一个人。最大帧频为10Hz,非常适合创建人体探测器或微型热相机。在Arduino或stm32(传感器通过I2C通信)上或在Raspberry Pi和Python上使用此代码。在PY上,借助于SciPy python库的一些图像处理帮助,我们能够插值8x8网格并获得一些非常好的结果,但本项目使用的是stm32由c语言编程,且由于并不打算制作热成像,故没有采用液晶显示屏。
该传感器只支持I2C,并有一个可配置的中断引脚,当任何单个像素超过或低于设置的阈值时,可以触发。
为了便于使用,我们小组挑选单片机的3.3V和GND引脚对其进行供电。采用oled值输出人体温度值。由于不需要实现报警功能,故不进行中断配置,只连接VIN、GND、SCL、SDA和拉低AD0地址选择引脚,将7位地址配置为0x68.
(IIC协议等驱动在此省略,具体amg8833资料可参考网上手册,可私信我)
目标温度的计算:
Amg8833通过128个TEMPERATURE寄存器(8位寄存器,由高地址寄存器和低地址寄存器共同构成一个单位像素点温度的存储寄存器)一次性读取64个像素点的温度,存储在用户自定义数组中(例如a[64]),64个温度值中有部分受环境影响而导致测温不准确,由于环境的温度低于人体温度,故软件设计中采取设置阈值比较算法,取64个温度值中最大温度的10个温度取平均(如果大于44℃会被视为异常点舍弃),即代表了人体体温。
除此之外,该模块自带热敏电阻,用于修正因模块电路长时间工作产生的内能影响,可以在软件设计中读取THERMISTOR寄存器热敏电阻温度值,用于测量温度修正的修正。
openmv人脸识别部分
由图像获取及目标坐标获取可以得到人脸关键点的坐标(X_Real , Y_Real )
如果要将目标控制在图像的中点,可以计算得到坐标偏移量:
Offset = Real - Target (4)
偏移量 = 实际值 - 目标值
我们仅仅知道偏移量还不够,我们最终的控制量是舵机角度的增量(变化幅度), 所以需要在偏移量与舵机角度的增量之间建立某种联系,这里涉及到二*度舵机云台球面角度与坐标转换,需要借助四元数姿态解算,欧拉角旋转矩阵法,考虑到时间不足无法完成学习以及代码编写,我们直接调用OpenMV中的姿态解算算法,这里不再深入研究。
1 、云台舵机PID控制
一种调节器控制规律为比例、积分、微分的控制。其中:P:比例(proportion)、I:积分(integral)、D:导数(derivative)[9]
基本公式如下: Kp为比例系数,Ti为积分时间参数,Td为微分时间常数
位置PID
1.理论分析
位置闭环控制就是根据编码器的脉冲累加测量电机的位置信息,并与目标值进行比较,得到控制偏差,然后通过对偏差的比例、积分、微分进行控制,使偏差趋向于零的过程[5]。
2.应用到单片机中的云台舵机控制公式:
Pwm=Kpe(k)+Ki∑e(k)+Kd*[e(k)-e(k-1)][9] (5)
e(k):本次偏差
e(k-1):上一次的偏差
∑e(k):e(k)以及之前的偏差的累积和;其中k为1,2,k;
Pwm代表输出到舵机的脉冲
2、特征算法的选择分析
2.1 CascadeClassifier(级联分类器)检测的基本原理:
CascadeClassifier为OpenCV中cv namespace下用来做目标检测的级联分类器的一个类。该类中封装的目标检测机制,简而言之是滑动窗口机制+级联分类器的方式[10]
用 OpenCV 创建一个面部和眼部检测器。首先我们要加载需要的 XML 分类器。然后以灰度格式加载输入图像或者是视频。XML 中存放的是训练后的特征池,特征size大小根据训练时的参数而定,检测的时候可以简单理解为就是将每个固定size特征(检测窗口)与输入图像的同样大小区域比较,如果匹配那么就记录这个矩形区域的位置,然后滑动窗口,检测图像的另一个区域,重复操作[10]。通过6可以看到,由于输入的图像中特征大小不定,比如在输入图像中眼睛是50x50的区域,而训练时的是25x25,那么只有当输入图像缩小到一半的时候,才能匹配上,所以这里还有一个逐步缩小图像,也就是制作图像金字塔的流程。
通过图7可以看到,由于人脸可能出现在图像的任何位置,在检测时用固定大小的窗口对图像从上到下、从左到右扫描,判断窗口里的子图像是否为人脸,这称为滑动窗口技术[10](sliding window)。为了检测不同大小的人脸,还需要对图像进行放大或者缩小构造图像金字塔,对每张缩放后的图像都用上面的方法进行扫描。
以512x512大小的图像为例,假设分类器窗口为24x24,滑动窗口的步长为1,则总共需要扫描的窗口数为:以512x512大小的图像为例,假设分类器窗口为24x24,滑动窗口的步长为1,则总共需要扫描的窗口数为:
即要检测一张图片需要扫描大于120万个窗口,这对于实时获取图像信息的系统是十分不利的,因此使用不能使用滑动窗口的的蛮力特征匹配算法。
2.2 Haar特征分析+Adaboost级联分类器
Haar 级联检测器,OpenCV 中的 Haar 级联检测器支持人脸检测、微笑、眼睛与嘴巴检测等,通过加载这些预先训练的 Haar 模型数据可以实现相关的对象检测。Haar特征最先由Paul Viola等提出,后经过Rainer Lienhart等扩展引入45°倾斜特征,成为现在OpenCV所使用的的样子。图2展示了目前OpenCV所使用的共计14种Haar特征,包括5种Basic特征、3种Core特征和6种Titled(即45°旋转)特征。
Haar特征值反映了图像的灰度变化情况, 可用于于图像任意位置,大小也可以任意改变,所以矩形特征值是矩形模版类别、矩形位置和矩形大小这三个因素的函数。故类别、大小和位置的变化,使得很小的检测窗口含有非常多的矩形特征。
得到输入图像的特征后,训练一个决策树构建的adaboost级联决策器来识别是否为人脸。
经过实际检验比较: Haar 特征算法比普通特征匹配算法速度更快,效率更高。
在Opencv 中,已经存储了预先训练好的 Haar 模型数据,通过加载这些预先训练好的 Haar 模型数据,调用相关的分类算法即可实现相关对象的检测。
pcb电路
此处无关紧要,且本人pcb知识和经验不配在此多赘述。。。
调试结果
上面部分为环境温度,下面为测试者额头温顿,误差合理。