回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页

【教哈有方】IOT人脸识别测温AI门禁系统 简单

头像 txm派瑞深山锹🐛🐜🐞🦂 2020.03.23 1699 2

本项目的研究目的治旨在为大型人流聚集的单位(如学校,工作单位)提供健康监测和日常考勤签到,并能通过iot互联技术将异常者信息进行迅速通知。通过此次新型冠状病毒事件,社会层面需要一套更加便捷且自动化的检测设施,一来减少检测人员,二来能方便考勤统计。

材料清单

  • Arduino mage2560 X1
  • 二哈ai识图 X1
  • asr语音识别扩展版 X1
  • 面包板+线材 X1
  • 语音合成bee X1
  • i2cLCD 2*16 X1
  • 环境光传感器 X1
  • sharp红外测距 X1
  • 人体红外释电传感器 X1
  • ESP8266iot模块 X1
  • 继电器 X1
  • 散热小风扇 X1
  • 模拟量非接触式红外温度传感器 X1

也许看到标题和所使用的材料,不免有些疑问,为啥都用了红外温度传感器还要来报名呢?

qwq弱弱地回答:模拟量红外温度实在不准,也不大好用,对实际测量误差甚大

PS.而且测量距离对模拟量输出的结果数据影响也很大

为了能换上一款精确实用的红外温度传感器,提升产品实用性,慕名前来投稿参加活动 :)

project-image

实验采用红外测距传感器及红外无接触式体温传感器,进行实时的体温监控。通过面部识别技术,准确获取人员身份。

检测时支持语音识别与语音合成输出。

检测时间如果超时会退回主界面。

系统支持控制电磁锁根据测温结果开关门禁。

系统在人体红外热释电传感器检测到有人接近会开始进行呼吸灯闪烁提示进行人脸识别和提问检测。

如果发现非授权人员和体温超标,均会发出警报,并关闭门禁。对授权人员且体温正常的则予以放行。

检测到有预先录入的人脸开始识别

project-image

开始提示并检测温度

project-image

体温正常,继电器打开,人员通过,考勤时间上传至iot平台

project-image

体温过高,不予以放行,并及时上报iot平台

project-image

步骤1 录入人脸

project-image

所有人脸都得预先录入,二哈识图操作简单,适合新人玩转AI!
二哈背面指示灯:
蓝:检测到图像/正在学习
绿:学习完成
以下附上二哈文档 :)

步骤2 搭建硬件

设计思路:

二哈进行人脸识别

led呼吸光圈配合环境光检测补光

人体红外释热使门禁在有人时保持检测状态

红外测距配合模拟量非接触式红外温度传感器检测温度(因为模拟量非接触式红外温度传感器受距离影响特别大

语音识别与语音播报使人机在非接触条件下进行交互

ESP8266IOT模块上传数据至物联网平台

继电器模拟电磁阀锁或直接接入电磁阀门锁


{配图如下)

project-image
project-image

步骤3 外观设计

project-image

侧拉式设计,方便开关后盖,引出继电器导线,也方便悬挂在墙面上

步骤4 语音识别&语音合成播报

project-image

(左:语音合成bee,右:语音识别扩展板)
意外!:拆扩展板拍照展示时arduino不知为何发出了刺鼻的气味,赶忙抢修!!!

project-image

步骤5 IOT测试

绿灯亮表示连网成功,蓝灯/紫灯表示wifi正在连接,红灯则表示wifi断连

但由于某些问题iot模块时常断开连接,所以每次发送信息之前都得初始化iot模块 :(

project-image
project-image
project-image

所有检测结果均传输到IOT云服务器,如有异常将通过微信公众号等互联网网络方式迅速告知其重要联系人。通过一系列程序的调试及传感器硬件的运用,形成一套完整的体温考勤系统。其制作成本较低,能够广泛应用与诸如学校,工作单位等大型人员聚集区。通过体温检测和人脸识别的身份认证,达到出勤,身体监测一步到位。做到减少人员部署,实现全自动化服务,提高工作时间效率。管理者也可以通过iot平台导出考勤时间的Excel表格和温度的表格以进行进一步的大数据挖掘和研究。

后继升级与改进:将数据上传至微信平台,并被动回复数据

project-image

easyIOT平台查看数据并导出统计结果

project-image

步骤6 源码

部分代码用mind+直观编辑,再嵌套入ArduinoIDE中语音识别的部分最终在ArduinoIDE中编译烧录,所有需要将mind+中的部分库拷贝调用(小聪明!)

project-image
代码
//Mage2560版功能已实现并展示,源码也已具备,但由于特殊原因暂不公开,将延迟上传
//一下附上Uno板源码,要用mind+的库文件
#include <UNO_Obloq.h>
#include <SoftwareSerial.h>
#include <DFRobot_IICScan.h>
#include <DFRobot_HuskyLens.h>
#include <DFRobot_Libraries.h>
#include <DFRobot_LiquidCrystal_I2C.h>

// 动态变量
volatile float mind_n_pwm2, mind_n_pwm, mind_n_facedb1, mind_n_light, mind_n_times,
               mind_n_time1, mind_n_time2, mind_n_faceid, mind_n_temp, mind_n_facedb2;
// 静态常量
const String topics[5] = {"BkMH48Djf","","","",""};
// 创建对象
SoftwareSerial            softwareSerial1(3, 2);
UNO_Obloq                 olq;
DFRobot_HuskyLens         huskylens;
DFRobot_LiquidCrystal_I2C lcd1602;
DFRobot_IICScan           iicscan;
DFRobot_Sharp             sharp;


// 主程序开始
void setup() {
	Serial.begin(9600);
	Serial.println("硬串口ok");
	softwareSerial1.begin(9600);
	olq.startConnect(0, 1, "dfrobotYanfa", "hidfrobot", "SJISVLvoz", "r1xUSVUwsz", topics, "iot.dfrobot.com.cn", 1883);
	Serial.println("软串口ok");
	delay(500);
	huskylens.beginI2CUntilSuccess();
	delay(500);
	Serial.println("识图模组ok");
	huskylens.writeAlgorithm(ALGORITHM_FACE_RECOGNITION);
	Serial.println("切换人脸识别ok");
	lcd1602.begin(0x27);
	lcd1602.clear();
	Serial.println("iiclcd显示屏ok");
	analogWrite(6, 0);
	digitalWrite(12, LOW);
	Serial.println("引脚低电平");
	lcd1602.printLine(uint32_t(1), "Everything is OK");
	lcd1602.printLine(uint32_t(2), iicscan.scan());
	Serial.println((String("所有i2c地址:") + String(iicscan.scan())));
	Serial.println("初始化完成");
	mind_n_pwm2 = 255;
	mind_n_pwm = 0;
}
void loop() {
	analogWrite(5, 255);
	delay(100);
	analogWrite(5, 0);
	while (!((mind_n_pwm2<=5) && (mind_n_pwm<=5))) {
		mind_n_pwm -= 5;
		mind_n_pwm2 -= 4.5;
		analogWrite(9, mind_n_pwm2);
		analogWrite(6, (constrain(mind_n_pwm, 0, 255)));
		delay(50);
	}
	lcd1602.clear();
	analogWrite(5, 0);
	digitalWrite(12, LOW);
	digitalWrite(6, LOW);
	mind_n_pwm = 0;
	while (!(mind_n_pwm2>=225)) {
		analogWrite(6, mind_n_pwm);
		mind_n_pwm2 += 5;
		analogWrite(9, mind_n_pwm2);
		delay(50);
	}
	while (!(sharp.distanceMm(A0)<=150)) {
		while (!((mind_n_pwm>=150) || (sharp.distanceMm(A0)<=150))) {
			mind_n_pwm += 1;
			mind_n_pwm2 -= 1.2;
			mind_n_facedb1 = 0;
			analogWrite(6, (constrain(mind_n_pwm, 0, 255)));
			analogWrite(9, mind_n_pwm2);
			lcd1602.printLine(uint32_t(2), (String("Wave at me") + String(sharp.distanceMm(A0))));
			lcd1602.printLine(uint32_t(1), analogRead(A3));
			Serial.println(mind_n_pwm2);
		}
		while (!((mind_n_pwm<=1) || (sharp.distanceMm(A0)<=150))) {
			mind_n_pwm -= 1;
			mind_n_pwm2 += 1.2;
			analogWrite(6, (constrain(mind_n_pwm, 0, 255)));
			analogWrite(9, mind_n_pwm2);
			lcd1602.printLine(uint32_t(2), (String("Wave at me") + String(sharp.distanceMm(A0))));
			lcd1602.printLine(uint32_t(1), analogRead(A3));
			Serial.println(mind_n_pwm2);
		}
	}
	analogWrite(5, 255);
	lcd1602.clear();
	lcd1602.printLine(uint32_t(1), "hello world !!!");
	delay(100);
	Serial.println("调光准备就绪");
	analogWrite(5, 0);
	while (!(mind_n_pwm<=0)) {
		analogWrite(6, (constrain(mind_n_pwm, 0, 255)));
		analogWrite(9, (map(mind_n_pwm, 255, 0, 0, 255)));
		lcd1602.printLine(uint32_t(2), (String(mind_n_pwm) + String((String(" ") + String(analogRead(A2))))));
		mind_n_pwm -= 3;
	}
	analogWrite(6, 0);
	mind_n_light = analogRead(A2);
	mind_n_pwm = 0;
	lcd1602.printLine(uint32_t(1), "Let me see you!");
	lcd1602.printLine(uint32_t(2), "Who are you?");
	mind_n_times = 0;
	Serial.println("启动摄像模组");
	mind_n_time1 = millis();
	huskylens.request();
	while (!(huskylens.isLearned(huskylens.readBlockCenterParameterDirect().ID) || ((mind_n_time2-mind_n_time1)>6000))) {
		if (((analogRead(A2)<=720) || (mind_n_pwm<252))) {
			mind_n_pwm += 2;
			analogWrite(6, mind_n_pwm);
		}
		mind_n_time2 = millis();
		mind_n_times += 1;
		lcd1602.printLine(uint32_t(2), (String("  Trying:") + String(mind_n_times)));
		huskylens.request();
		mind_n_faceid = huskylens.readBlockCenterParameterDirect().ID;
	}
	if (huskylens.isLearned(huskylens.readBlockCenterParameterDirect().ID)) {
		Serial.println("识别到人脸");
		Serial.println((String("Hello") + String(mind_n_faceid)));
		analogWrite(5, 255);
		lcd1602.printLine(uint32_t(1), (String("Hello") + String(mind_n_faceid)));
		lcd1602.printLine(uint32_t(2), "Close to Top");
		delay(100);
		analogWrite(5, 0);
		Serial.println("请靠近温度探头");
		mind_n_times = 0;
		mind_n_time1 = millis();
		while (!((sharp.distanceMm(A0)<=70) || ((mind_n_time2-mind_n_time1)>6000))) {
			if ((mind_n_pwm>0)) {
				mind_n_pwm -= 1;
				analogWrite(6, mind_n_pwm);
			}
			mind_n_time2 = millis();
			mind_n_times += 1;
			lcd1602.printLine(uint32_t(2), (String("Close to Top") + String(mind_n_times)));
		}
		if ((!((mind_n_time2-mind_n_time1)>6000))) {
			Serial.println(sharp.distanceMm(A0));
			mind_n_temp = (map(analogRead(A3), 0, 665, 0, 225));
			analogWrite(5, 255);
			Serial.println((String((String("ID:") + String(mind_n_faceid))) + String((String("Temp:") + String(mind_n_temp)))));
			lcd1602.clear();
			lcd1602.printLine(uint32_t(1), (String((String("ID:") + String(mind_n_faceid))) + String((String("Temp:") + String(mind_n_temp)))));
			delay(100);
			analogWrite(5, 0);
			if ((mind_n_temp<=37.3)) {
				olq.publish(olq.topic_0, (String((String("ID:") + String(mind_n_faceid))) + String((String("Temp:") + String(mind_n_temp)))));
				Serial.println((String(mind_n_temp) + String("coming")));
				lcd1602.printLine(uint32_t(2), "Please coming!");
				digitalWrite(12, HIGH);
				delay(2000);
				huskylens.request();
				mind_n_facedb1 = huskylens.readBlockCenterParameterDirect().ID;
				while (!((!(mind_n_facedb1==mind_n_faceid)) && (!(mind_n_facedb2==mind_n_faceid)))) {
					digitalWrite(A1, HIGH);
					huskylens.request();
					mind_n_facedb1 = huskylens.readBlockCenterParameterDirect().ID;
					delay(1500);
					huskylens.request();
					mind_n_facedb2 = huskylens.readBlockCenterParameterDirect().ID;
					delay(1500);
				}
			}
			else {
				olq.publish(olq.topic_0, (String((String("Danger!   ID:") + String(mind_n_faceid))) + String((String("Temp:") + String(mind_n_temp)))));
				analogWrite(5, 255);
				Serial.println("bye");
				lcd1602.printLine(uint32_t(2), "Danger! Get out!");
				digitalWrite(12, LOW);
				delay(2000);
			}
			huskylens.writeAlgorithm(ALGORITHM_FACE_RECOGNITION);
			delay(1000);
		}
		else {
			analogWrite(5, 255);
			Serial.println("Fail to get Temperature ");
			lcd1602.printLine(uint32_t(1), "Fail to Temperature ");
			lcd1602.printLine(uint32_t(2), "Please try again");
			delay(1000);
		}
	}
	else {
		digitalWrite(12, LOW);
		Serial.println("I don't know!");
		lcd1602.printLine(uint32_t(1), "I don't know!");
		lcd1602.printLine(uint32_t(2), "Get out !");
		delay(1000);
	}
}

                                                                                                                                                作者及团队人员:

滕孝鸣 丘坛 刘懿文

评论

user-avatar
  • XDJtSxlk

    XDJtSxlk2020.03.30

    加油加油

    0
    • XDJtSxlk

      XDJtSxlk2020.03.30

      哈哈哈,看来我明天也得传个源码了

      0