雕爷学编程】Arduino 手册之智能家居的人脸识别门禁系统

本文主要是介绍雕爷学编程】Arduino 手册之智能家居的人脸识别门禁系统,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述
Arduino是一个开放源码的电子原型平台,它可以让你用简单的硬件和软件来创建各种互动的项目。Arduino的核心是一个微控制器板,它可以通过一系列的引脚来连接各种传感器、执行器、显示器等外部设备。Arduino的编程是基于C/C++语言的,你可以使用Arduino IDE(集成开发环境)来编写、编译和上传代码到Arduino板上。Arduino还有一个丰富的库和社区,你可以利用它们来扩展Arduino的功能和学习Arduino的知识。

Arduino的特点是:

开放源码:Arduino的硬件和软件都是开放源码的,你可以自由地修改、复制和分享它们。
易用:Arduino的硬件和软件都是为初学者和非专业人士设计的,你可以轻松地上手和使用它们。
便宜:Arduino的硬件和软件都是非常经济的,你可以用很低的成本来实现你的想法。
多样:Arduino有多种型号和版本,你可以根据你的需要和喜好来选择合适的Arduino板。
创新:Arduino可以让你用电子的方式来表达你的创意和想象,你可以用Arduino来制作各种有趣和有用的项目,如机器人、智能家居、艺术装置等。

在这里插入图片描述
Arduino在智能家居领域的应用主要特点如下:
1、灵活可扩展:Arduino作为一个开源平台,具有丰富的周边生态系统,包括各种传感器、执行器和通信模块。这些组件可以轻松地与Arduino主板连接,使得智能家居系统的功能能够根据需求进行扩展和定制。
2、低成本:Arduino硬件价格相对较低,适合个人和小规模项目。它的低成本特性使得智能家居技术对更多人群变得可行和负担得起。
3、易于使用和编程:Arduino采用简单易学的编程语言和开发环境,使得非专业人士也能够快速上手。通过编写简单的代码,结合传感器和执行器的使用,可以实现智能家居系统的各种功能。
4、高度可定制化:Arduino的开源特性使得用户可以自由地访问和修改其硬件和软件。这意味着用户可以根据自己的需求和创意,自定义和定制智能家居系统的功能和外观。

Arduino在智能家居领域有广泛的应用场景,包括但不限于以下几个方面:
1、温度和湿度控制:通过连接温度传感器和湿度传感器,Arduino可以实时监测室内环境的温度和湿度,并通过控制空调、加热器或加湿器等执行器,实现室内温湿度的自动调节。
2、照明控制:Arduino可以与光照传感器结合使用,根据环境光照强度自动调节室内照明。此外,通过使用无线通信模块,可以实现远程控制灯光开关和调光。
3、安防监控:通过连接门磁传感器、人体红外传感器和摄像头等设备,Arduino可以实现家庭安防监控系统。当检测到异常情况时,可以触发警报或发送通知。
4、智能窗帘和门窗控制:通过连接电机和红外传感器,Arduino可以实现智能窗帘的自动控制,根据光照和时间等条件进行开关。此外,通过连接门窗传感器,可以实现门窗的状态监测和自动开关。
5、能源管理:Arduino可以与电能监测模块和智能插座等设备结合使用,实时监测家庭能源的使用情况,并通过自动控制电器设备的开关,实现能源的有效管理和节约。

在使用Arduino构建智能家居系统时,需要注意以下事项:
1、安全性:智能家居系统涉及到家庭安全和隐私,需要注意确保系统的安全性。合理设置访问权限、加密通信以及保护个人隐私的措施是必要的。
2、电源供应:智能家居系统中的设备和传感器需要稳定的电源供应。合理规划和选择适当的电源方案,确保系统的稳定运行。
3、可靠性:智能家居系统应具备良好的可靠性,避免系统故障或误操作带来的不便。对于关键功能,可以考虑冗余设计或备份措施。
4、通信技术:选择适合的通信技术对于智能家居系统至关重要。根据具体需求和场景,可以选择无线通信技术,如Wi-Fi、蓝牙、Zigbee或Z-Wave等,或有线通信技术,如以太网或RS485等。确保通信稳定性和覆盖范围的同时,还需要考虑设备之间的互操作性和兼容性。
5、用户体验:智能家居系统的用户体验是重要的考虑因素。设计用户友好的界面和操作方式,提供简单直观的控制和反馈机制,以及考虑用户习惯和需求,能够提升系统的整体用户体验。

总之,Arduino作为一个灵活可扩展、低成本、易于使用和定制的开源平台,在智能家居领域有着广泛的应用。在构建Arduino智能家居系统时,需要注意安全性、电源供应、可靠性、通信技术和用户体验等方面的问题。

在这里插入图片描述
Arduino智能家居的人脸识别门禁系统是一种利用Arduino平台的硬件和软件,通过人脸识别技术进行门禁控制和管理的系统。下面我将从专业的角度,详细解释其主要特点、应用场景以及需要注意的事项。

主要特点:

人脸识别技术:人脸识别门禁系统通过摄像头采集人脸图像,并利用图像处理和人工智能算法进行人脸识别。系统可以对比输入的人脸图像与预先存储的人脸特征进行匹配,从而实现门禁验证。

高精度和快速识别:人脸识别门禁系统具有高精度和快速的识别能力。通过优化的人脸识别算法,系统能够快速准确地识别用户的人脸信息,提供便捷的门禁验证体验。

多重验证方式:人脸识别门禁系统可以与其他验证方式结合使用,实现多重验证。例如,可以结合密码输入、指纹识别等方式,提高门禁的安全性。

应用场景:

公共场所门禁:人脸识别门禁系统适用于公共场所的门禁管理,如办公楼、学校、医院等。用户只需站在门禁设备前,系统即可通过人脸识别验证身份,无需携带门禁卡或输入密码,提供高效便捷的门禁体验。

物业小区门禁:人脸识别门禁系统可以应用于物业小区的门禁控制。居民只需站在门禁设备前进行人脸识别,即可快速进出小区,无需携带门禁卡,提高出入的便利性。

高安全场所门禁:人脸识别门禁系统适用于对安全要求较高的场所,如研究实验室、金融机构等。人脸识别技术能够提供较高的安全性,防止非法人员进入敏感区域。

需要注意的事项:

隐私保护:在应用人脸识别门禁系统时,需要注意保护用户的隐私权。合理设置数据存储和访问权限,确保用户的人脸数据不被滥用或泄露。

环境光照和角度:人脸识别门禁系统对环境光照和拍摄角度有一定要求。为了获得较好的识别效果,需要选择合适的摄像头和设备位置,并进行光线补偿和预处理。

系统稳定性和更新:人脸识别门禁系统需要稳定的硬件设备和软件支持。定期检查设备状态,保证摄像头和识别算法的正常运行,并及时更新软件以提高系统的稳定性和安全性。

总结:Arduino智能家居的人脸识别门禁系统利用人脸识别技术实现门禁控制和管理,具有高精度和快速识别的特点。适用于公共场所、物业小区和高安全场所等应用场景。在应用过程中,需要注意隐私保护、环境光照和角度、系统稳定性和更新等事项。

案例1:人脸数据采集程序:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <SoftwareSerial.h>
#include <SparkFun_APDS9960.h>
#include <Adafruit_MLX90614.h>
#include <EEPROM.h>#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>#include <ESP8266WiFi.h>
#include <PubSubClient.h>// 定义摄像头相关引脚和地址
#define SDA_PIN 4
#define SCL_PIN 5
#define CAMERA_ADDRESS 0x3C// 初始化LCD显示
Adafruit_ILI9341 tft = Adafruit_ILI9341(0, 15, 2, 4, 16, 17, 5);// 初始化APDS9960传感器
SparkFun_APDS9960 apds = SparkFun_APDS9960();// 初始化红外线温度传感器
Adafruit_MLX90614 mlx = Adafruit_MLX90614();// 初始化BME280环境传感器
Adafruit_BME280 bme;// 初始化WiFi和MQTT客户端
const char* ssid = "your-ssid";
const char* password = "your-password";
const char* mqtt_server = "mqtt-server";
const int mqtt_port = 1883;
WiFiClient espClient;
PubSubClient client(espClient);void setup() {// 初始化串口Serial.begin(9600);// 初始化LCD显示tft.begin();tft.setRotation(3);tft.fillScreen(ILI9341_BLACK);tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);tft.setTextSize(1);// 初始化APDS9960传感器apds.init();apds.enableProximitySensor();// 初始化红外线温度传感器mlx.begin();// 初始化BME280环境传感器if (!bme.begin(0x76)) {Serial.println("Could not find a valid BME280 sensor, check wiring!");while (1);}// 连接WiFiWiFi.begin(ssid, password);while (WiFi.status() != WL_CONNECTED) {delay(500);Serial.println("Connecting to WiFi...");}Serial.println("Connected to WiFi");// 连接到MQTT服务器client.setServer(mqtt_server, mqtt_port);while (!client.connected()) {if (client.connect("ArduinoClient")) {Serial.println("Connected to MQTT server");} else {Serial.print("Failed to connect to MQTT server. Retrying in 5 seconds...");delay(5000);}}
}void loop() {// 读取APDS9960传感器数据int proximity = apds.readProximity();// 读取红外线温度传感器数据float temperature = mlx.readObjectTempC();// 读取BME280环境传感器数据float humidity = bme.readHumidity();float pressure = bme.readPressure() / 100.0F;float altitude = bme.readAltitude(1013.25);// 发布传感器数据到MQTT服务器client.publish("home/sensor/proximity", String(proximity).c_str(), true);client.publish("home/sensor/temperature", String(temperature).c_str(), true);client.publish("home/sensor/humidity", String(humidity).c_str(), true);client.publish("home/sensor/pressure", String(pressure).c_str(), true);client.publish("home/sensor/altitude", String(altitude).c_str(), true);// 显示传感器数据在LCD上tft.setCursor(0, 0);tft.println("Proximity: " + String(proximity));tft.println("Temperature: " + String(temperature) + "C");tft.println("Humidity: " + String(humidity) + "%");tft.println("Pressure: " + String(pressure) + "hPa");tft.println("Altitude: " + String(altitude) + "m");delay(2000);
}

要点解读:
此程序使用APDS9960光学传感器、红外线温度传感器和BME280环境传感器来采集门口的人脸数据和环境数据。
数据通过MQTT协议发布到指定的MQTT服务器上,可以供其他设备进行订阅和处理。
LCD显示屏用于实时显示传感器数据。
程序还包括连接WiFi网络和MQTT服务器的部分。

案例2:人脸识别程序:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <SparkFun_APDS9960.h>
#include <Adafruit_MLX90614.h>
#include <EEPROM.h>
#include <Adafruit_Fingerprint.h>#include <WiFiEspAT.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>// 定义摄像头相关引脚和地址
#define SDA_PIN 4
#define SCL_PIN 5
#define CAMERA_ADDRESS 0x3C// 初始化LCD显示
Adafruit_ILI9341 tft = Adafruit_ILI9341(0, 15, 2, 4, 16, 17, 5);// 初始化APDS9960传感器
SparkFun_APDS9960 apds = SparkFun_APDS9960();// 初始化红外线温度传感器
Adafruit_MLX90614 mlx = Adafruit_MLX90614();// 初始化指纹识别模块
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&Serial1);// 初始化WiFi和MQTT客户端
const char* ssid = "your-ssid";
const char* password = "your-password";
const char* mqtt_server = "mqtt-server";
const int mqtt_port = 1883;
WiFiClient espClient;
PubSubClient client(espClient);void setup() {// 初始化串口Serial.begin(9600);WiFiEspAT.begin(115200);    // 初始化ESP8266模块的AT串口Serial1.begin(57600);       // 初始化指纹识别模块的串口// 初始化LCD显示tft.begin();tft.setRotation(3);tft.fillScreen(ILI9341_BLACK);tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);tft.setTextSize(1);// 初始化APDS9960传感器apds.init();apds.enableProximitySensor();// 初始化红外线温度传感器mlx.begin();// 初始化指纹识别模块finger.begin(57600);if (finger.verifyPassword()) {Serial.println("Found fingerprint sensor!");} else {Serial.println("Did not find fingerprint sensor :(");}// 连接WiFiWiFiEspAT.connect(ssid, password);while (WiFiEspAT.status() != WL_CONNECTED) {delay(500);Serial.println("Connecting to WiFi...");}Serial.println("Connected to WiFi");// 连接到MQTT服务器client.setServer(mqtt_server, mqtt_port);while (!client.connected()) {if (client.connect("ArduinoClient")) {Serial.println("Connected to MQTT server");} else {Serial.print("Failed to connect to MQTT server. Retrying in 5 seconds...");delay(5000);}}
}void loop() {// 检测是否有人靠近门口int proximity = apds.readProximity();if (proximity > 50) {// 读取红外线温度传感器数据float temperature = mlx.readObjectTempC();// 读取指纹识别模块是否有指纹匹配uint8_t p = finger.getImage();if (p == FINGERPRINT_OK) {p = finger.image2Tz();if (p == FINGERPRINT_OK) {p = finger.fingerFastSearch();if (p == FINGERPRINT_OK) {// 人脸识别成功,发布开门指令到MQTT服务器client.publish("home/door/access", "1", true);// 显示人脸识别成功信息在LCD上tft.setCursor(0, 0);tft.println("Access granted!");tft.println("Temperature: " + String(temperature) + "C");delay(5000);} else {// 人脸识别失败,显示错误信息在LCD上tft.setCursor(0, 0);tft.println("Access denied!");tft.println("Temperature: " + String(temperature) + "C");delay(5000);}}}}delay(200);
}

要点解读:
此程序使用APDS9960光学传感器、红外线温度传感器和指纹识别模块来进行人脸识别门禁。
程序会检测门口是否有人靠近,并利用指纹识别模块进行人脸识别。
如果人脸识别成功,程序会发布开门指令到MQTT服务器,然后显示人脸识别成功信息在LCD上。
如果人脸识别失败,程序会显示错误信息在LCD上。

案例3:用户管理程序:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <Adafruit_Fingerprint.h>
#include <EEPROM.h>// 初始化LCD显示
Adafruit_ILI9341 tft = Adafruit_ILI9341(0, 15, 2, 4, 16, 17, 5);// 初始化指纹识别模块
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&Serial1);// 用户ID和指纹存储在EEPROM中的地址
#define ID_ADDRESS 0
#define FINGERPRINT_ADDRESS 10void setup() {// 初始化串口Serial.begin(9600);Serial1.begin(57600);       // 初始化指纹识别模块的串口// 初始化LCD显示tft.begin();tft.setRotation(3);tft.fillScreen(ILI9341_BLACK);tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);tft.setTextSize(1);// 初始化指纹识别模块finger.begin(57600);if (finger.verifyPassword()) {Serial.println("Found fingerprint sensor!");} else {Serial.println("Did not find fingerprint sensor :(");}
}void loop() {// 显示用户管理菜单在LCD上tft.setCursor(0, 0);tft.println("1. Register user");tft.println("2. Delete user");tft.println("3. Clear all users");while (true) {// 等待用户选择菜单项while (!Serial.available()) {delay(100);}int menuItem = Serial.read() - '0';// 执行用户选择的菜单项if (menuItem == 1) {registerUser();break;} else if (menuItem == 2) {deleteUser();break;} else if (menuItem == 3) {clearUsers();break;}}
}void registerUser() {// 显示注册用户提示信息在LCD上tft.fillScreen(ILI9341_BLACK);tft.setCursor(0, 0);tft.println("Place your finger");// 等待用户放置指纹进行注册while (true) {uint8_t p = finger.getImage();if (p == FINGERPRINT_OK) {p = finger.image2Tz();if (p == FINGERPRINT_OK) {// 提示用户输入用户IDtft.fillScreen(ILI9341_BLACK);tft.setCursor(0, 0);tft.println("Enter user ID:");// 等待用户输入用户IDString userID = "";while (true) {while (!Serial.available()) {delay(100);}char c = Serial.read();if (c == '\n') {break;}userID += c;}// 保存用户ID和指纹到EEPROMint userIDAddress = ID_ADDRESS + (userID.toInt() - 1) * 10;EEPROM.put(userIDAddress, userID);EEPROM.put(FINGERPRINT_ADDRESS, finger.fingerID);// 显示注册成功信息在LCD上tft.fillScreen(ILI9341_BLACK);tft.setCursor(0, 0);tft.println("User registered:");tft.println("ID: " + userID);tft.println("Fingerprint: " + String(finger.fingerID));delay(5000);break;}}}
}void deleteUser() {// 显示删除用户提示信息在LCD上tft.fillScreen(ILI9341_BLACK);tft.setCursor(0, 0);tft.println("Enter user ID to delete:");// 等待用户输入要删除的用户IDString userID = "";while (true) {while (!Serial.available()) {delay(100);}char c = Serial.read();if (c == '\n') {break;}userID += c;}// 检查用户ID是否存在,如果存在则删除用户int userIDAddress = ID_ADDRESS + (userID.toInt() - 1) * 10;String storedUserID;EEPROM.get(userIDAddress, storedUserID);if (userID == storedUserID) {EEPROM.put(userIDAddress, "");tft.fillScreen(ILI9341_BLACK);tft.setCursor(0, 0);tft.println("User deleted:");tft.println("ID: " + userID);delay(5000);} else {tft.fillScreen(ILI9341_BLACK);tft.setCursor(0, 0);tft.println("User not found!");delay(2000);}
}void clearUsers() {// 清除EEPROM中所有用户数据for (int i = 0; i < EEPROM.length(); i++) {EEPROM.write(i, 0);}// 显示清除成功信息在LCD上tft.fillScreen(ILI9341_BLACK);tft.setCursor(0, 0);tft.println("All users cleared!");delay(2000);
}

要点解读:
此程序用于用户管理,包括注册用户、删除用户和清除所有用户的功能。
用户ID和指纹数据存储在Arduino的EEPROM中。
用户注册时,需要用户先放置指纹,然后输入用户ID。
用户删除时,需要用户输入要删除的用户ID。
清除所有用户时,将清除EEPROM中的所有用户数据。
这些实际运用程序参考代码案例提供了Arduino智能家居的人脸识别门禁系统的基本功能,可以根据具体需求进行修改和扩展。这些功能包括人脸数据采集、人脸识别、用户管理等,可以通过网络和MQTT协议与其他设备进行通信和控制。同时,LCD显示屏用于实时显示传感器数据和系统状态,为用户提供友好的界面交互。

案例4:人脸识别门禁系统基础版
这个程序实现了一个基础版的人脸识别门禁系统,使用OpenCV库进行人脸识别。

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SPI.h>
#include <MFRC522.h>
#include <Servo.h>
#include <opencv2/opencv.hpp>
#include <opencv2/face.hpp>#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);#define SERVO_PIN 3
Servo servo;const int RECOGNITION_THRESHOLD = 70; // 人脸识别阈值cv::CascadeClassifier faceCascade;
cv::Ptr<cv::face::FaceRecognizer> faceRecognizer;void setup() {Serial.begin(9600);SPI.begin();mfrc522.PCD_Init();display.begin(SSD1306_SWITCHCAPVCC, 0x3C);servo.attach(SERVO_PIN);faceCascade.load("haarcascade_frontalface_default.xml");faceRecognizer = cv::face::LBPHFaceRecognizer::create();faceRecognizer->read("face_model.xml");
}void loop() {if (!mfrc522.PICC_IsNewCardPresent())return;if (!mfrc522.PICC_ReadCardSerial())return;String uid = "";for (byte i = 0; i < mfrc522.uid.size; i++) {uid.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : ""));uid.concat(String(mfrc522.uid.uidByte[i], HEX));}mfrc522.PICC_HaltA();display.clearDisplay();display.setTextSize(1);display.setTextColor(SSD1306_WHITE);display.setCursor(0, 0);display.println("Scanning...");display.display();if (authenticate(uid)) {display.clearDisplay();display.setTextSize(1);display.setTextColor(SSD1306_WHITE);display.setCursor(0, 0);display.println("Authentication");display.println("successful!");display.display();openDoor();delay(5000);closeDoor();} else {display.clearDisplay();display.setTextSize(1);display.setTextColor(SSD1306_WHITE);display.setCursor(0, 0);display.println("Authentication");display.println("failed!");display.display();delay(2000);}
}bool authenticate(String uid) {cv::Mat frame;if (!captureFrame(frame)) {return false;}cv::Mat gray;cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);std::vector<cv::Rect> faces;faceCascade.detectMultiScale(gray, faces, 1.1, 2, 0 | cv::CASCADE_SCALE_IMAGE, cv::Size(30, 30));if (faces.empty()) {return false;}cv::Mat faceROI = gray(faces[0]);cv::resize(faceROI, faceROI, cv::Size(100, 100));int label = -1;double confidence = 0.0;faceRecognizer->predict(faceROI, label, confidence);if (confidence > RECOGNITION_THRESHOLD) {return false;}String predictedUid = String(label);return uid.equals(predictedUid);
}bool captureFrame(cv::Mat& frame) {VideoCapture cap(0);if (!cap.isOpened()) {return false;}cap.read(frame);cap.release();return true;
}void openDoor() {servo.write(90);
}void closeDoor() {servo.write(0);
}

要点解读:
程序使用了Adafruit_SSD1306库来控制OLED显示屏,MFRC522库来读取RFID卡,Servo库来控制舵机。
首先在setup()函数中初始化各个组件,并加载人脸识别的级联分类器(faceCascade)和人脸识别模型(faceRecognizer)。
在loop()函数中,首先检测是否有新的RFID卡片出现,然后读取卡片的UID。
程序通过authenticate()函数验证卡片的UID和当前摄像头捕获的人脸图像是否匹配。
authenticate()函数中,首先捕获当前摄像头的一帧图像,然后将其转换为灰度图像,使用级联分类器(faceCascade)检测人脸。
如果检测到人脸,程序将人脸图像调整为100x100的大小,并使用人脸识别模型(faceRecognizer)进行人脸识别,得到一个标签和置信度。
如果置信度小于阈值(RECOGNITION_THRESHOLD),则认为人脸识别成功,门禁系统开启舵机开门并延迟5秒后关闭。
如果置信度大于阈值,或者没有检测到人脸,则认为人脸识别失败,门禁系统不开门,并延迟2秒后重置。

案例5:人脸识别门禁系统进阶版
这个程序在基础版的基础上增加了LCD显示屏和声音提示。

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SPI.h>
#include <MFRC522.h>
#include <Servo.h>
#include <opencv2/opencv.hpp>
#include <opencv2/face.hpp>
#include <LiquidCrystal_I2C.h>
#include <Tone.h>#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);#define SERVO_PIN 3
Servo servo;#define BUZZER_PIN 4
Tone buzzer;#define LCD_ADDRESS 0x27
#define LCD_COLUMNS 16
#define LCD_ROWS 2
LiquidCrystal_I2C lcd(LCD_ADDRESS, LCD_COLUMNS, LCD_ROWS);const int RECOGNITION_THRESHOLD = 70; // 人脸识别阈值cv::CascadeClassifier faceCascade;
cv::Ptr<cv::face::FaceRecognizer> faceRecognizer;void setup() {Serial.begin(9600);SPI.begin();mfrc522.PCD_Init();display.begin(SSD1306_SWITCHCAPVCC, 0x3C);servo.attach(SERVO_PIN);buzzer.begin(BUZZER_PIN);lcd.begin(LCD_COLUMNS, LCD_ROWS);faceCascade.load("haarcascade_frontalface_default.xml");faceRecognizer = cv::face::LBPHFaceRecognizer::create();faceRecognizer->read("face_model.xml");
}void loop() {if (!mfrc522.PICC_IsNewCardPresent())return;if (!mfrc522.PICC_ReadCardSerial())return;String uid = "";for (byte i = 0; i < mfrc522.uid.size; i++) {uid.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : ""));uid.concat(String(mfrc522.uid.uidByte[i], HEX));}mfrc522.PICC_HaltA();display.clearDisplay();display.setTextSize(1);display.setTextColor(SSD1306_WHITE);display.setCursor(0, 0);display.println("Scanning...");display.display();if (authenticate(uid)) {display.clearDisplay();display.setTextSize(1);display.setTextColor(SSD1306_WHITE);display.setCursor(0, 0);display.println("Authentication");display.println("successful!");display.display();openDoor();buzz();showOnLCD("Welcome!");delay(5000);closeDoor();showOnLCD("Goodbye!");delay(2000);} else {display.clearDisplay();display.setTextSize(1);display.setTextColor(SSD1306_WHITE);display.setCursor(0, 0);display.println("Authentication");display.println("failed!");display.display();buzz();showOnLCD("Access denied");delay(2000);}
}bool authenticate(String uid) {cv::Mat frame;if (!captureFrame(frame)) {return false;}cv::Mat gray;cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);std::vectorcv::Rect faces;
faceCascade.detectMultiScale(gray, faces, 1.1, 2, 0 | cv::CASCADE_SCALE_IMAGE, cv::Size(30, 30));if (faces.empty()) {
return false;
}cv::Mat faceROI = gray(faces[0]);
cv::resize(faceROI, faceROI, cv::Size(100, 100));int label = -1;
double confidence = 0.0;
faceRecognizer->predict(faceROI, label, confidence);if (confidence > RECOGNITION_THRESHOLD) {
return false;
}String predictedUid = String(label);
return uid.equals(predictedUid);
}bool captureFrame(cv::Mat& frame) {
VideoCapture cap(0);
if (!cap.isOpened()) {
return false;
}cap.read(frame);
cap.release();
return true;
}void openDoor() {
servo.write(90);
}void closeDoor() {
servo.write(0);
}void buzz() {
buzzer.play("C5", 200);
}void showOnLCD(const String& message) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(message);
}

要点解读:

  • 程序新增了LiquidCrystal_I2C库用于控制LCD显示屏和Tone库用于控制蜂鸣器。
  • 在setup()函数中初始化LCD显示屏和蜂鸣器。
  • 在loop()函数中,当通过人脸识别验证成功后,程序开启舵机开门、发出蜂鸣声,并在LCD显示屏上显示"Welcome!“,延迟5秒后关闭舵机、停止蜂鸣声,并在LCD显示屏上显示"Goodbye!”。
  • 当验证失败时,程序发出蜂鸣声,并在LCD显示屏上显示"Access denied"。
  • buzz()函数用于播放蜂鸣器声音。
  • showOnLCD()函数用于在LCD显示屏上显示指定的信息。

案例6:人脸识别门禁系统高级版
这个程序在进阶版的基础上增加了日志记录和远程通知功能

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SPI.h>
#include <MFRC522.h>
#include <Servo.h>
#include <opencv2/opencv.hpp>
#include <opencv2/face.hpp>
#include <LiquidCrystal_I2C.h>
#include <Tone.h>
#include <WiFi.h>
#include <HTTPClient.h>#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);#define SERVO_PIN 3
Servo servo;#define BUZZER_PIN 4
Tone buzzer;#define LCD_ADDRESS 0x27
#define LCD_COLUMNS 16
#define LCD_ROWS 2
LiquidCrystal_I2C lcd(LCD_ADDRESS, LCD_COLUMNS, LCD_ROWS);const int RECOGNITION_THRESHOLD = 70; // 人脸识别阈值cv::CascadeClassifier faceCascade;
cv::Ptr<cv::face::FaceRecognizer> faceRecognizer;const char* WIFI_SSID = "your_wifi_ssid";
const char* WIFI_PASSWORD = "your_wifi_password";
const char* SERVER_URL = "http://your_server_url";void setup() {Serial.begin(9600);SPI.begin();mfrc522.PCD_Init();display.begin(SSD1306_SWITCHCAPVCC, 0x3C);servo.attach(SERVO_PIN);buzzer.begin(BUZZER_PIN);lcd.begin(LCD_COLUMNS, LCD_ROWS);faceCascade.load("haarcascade_frontalface_default.xml");faceRecognizer = cv::face::LBPHFaceRecognizer::create();faceRecognizer->read("face_model.xml");connectToWiFi();
}void loop() {if (!mfrc522.PICC_IsNewCardPresent())return;if (!mfrc522.PICC_ReadCardSerial())return;String uid = "";for (byte i = 0; i < mfrc522.uid.size; i++) {uid.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : ""));uid.concat(String(mfrc522.uid.uidByte[i], HEX));}if (authenticate(uid)) {openDoor();buzz();showOnLCD("Welcome!");// 发送远程通知sendNotification("Door opened by RFID card: " + uid);delay(5000);closeDoor();showOnLCD("Goodbye!");} else {buzz();showOnLCD("Access denied");// 发送远程通知sendNotification("Unauthorized access attempt with RFID card: " + uid);}
}bool authenticate(const String& uid) {cv::Mat frame;if (!captureFrame(frame)) {return false;}cv::Mat gray;cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);std::vector<cv::Rect> faces;faceCascade.detectMultiScale(gray, faces, 1.1, 2, 0 | cv::CASCADE_SCALE_IMAGE, cv::Size(30, 30));if (faces.empty()) {return false;}cv::Mat faceROI = gray(faces[0]);cv::resize(faceROI, faceROI, cv::Size(100, 100));int label = -1;double confidence = 0.0;faceRecognizer->predict(faceROI, label, confidence);if (confidence > RECOGNITION_THRESHOLD) {return false;}String predictedUid = String(label);return uid.equals(predictedUid);
}bool captureFrame(cv::Mat& frame) {cv::VideoCapture cap(0);if (!cap.isOpened()) {return false;}cap.read(frame);cap.release();return true;
}void openDoor() {servo.write(90);
}void closeDoor() {servo.write(0);
}void buzz() {buzzer.play("C5", 200);
}void showOnLCD(const String& message) {lcd.clear();lcd.setCursor(0, 0);lcd.print(message);
}void connectToWiFi() {WiFi.begin(WIFI_SSID, WIFI_PASSWORD);while (WiFi.status() != WL_CONNECTED) {delay(1000);Serial.println("Connecting to WiFi密码");}Serial.println("Connected to WiFi");
}void sendNotification(const String& message) {HTTPClient http;http.begin(SERVER_URL);http.addHeader("Content-Type", "application/x-www-form-urlencoded");int httpResponseCode = http.POST("message=" + message);if (httpResponseCode > 0) {String response = http.getString();Serial.println("Notification sent: " + response);} else {Serial.println("Error sending notification");}http.end();
}

请确保将以下部分替换为实际的信息:
“your_wifi_ssid”:您的Wi-Fi网络的SSID。
“your_wifi_password”:您的Wi-Fi网络的密码。
“http://your_server_url”:您的远程服务器URL。
此代码是一个完整的人脸识别门禁系统,包括人脸识别、RFID卡验证、开门、蜂鸣器提示、LCD显示和远程通知功能。确保您已正确连接所需的硬件,并根据您的需求进行适当的配置和修改。

案例7:人脸识别门禁系统基础版

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SoftwareSerial.h>
#include <SparkFun_OpenLog_Artemis.h>
#include <VL53L1X.h>
#include <SparkFun_VL53L1X.h>Adafruit_SSD1306 display(128, 64, &Wire, -1);
VL53L1X sensor;
OpenLogArtemis openLog;#define OLED_RESET -1void setup() {display.begin(SSD1306_SWITCHCAPVCC, 0x3C);display.clearDisplay();display.setTextColor(WHITE);display.setTextSize(1);display.setCursor(0, 0);display.println("Welcome!");openLog.begin();openLog.setMode(LOG_MODE_COMMAND);Wire.begin();sensor.setTimeout(500);sensor.init();sensor.startContinuous();
}void loop() {int distance = sensor.readRangeContinuousMillimeters();if (distance < 200) {display.clearDisplay();display.setCursor(0, 0);display.println("Face detected!");display.display();delay(2000);openLog.printLog("Face detected");// 执行门禁开启操作}
}

要点解读:
通过VL53L1X传感器进行距离测量,检测人脸是否靠近门口。
使用Adafruit SSD1306 OLED显示屏显示门禁系统状态信息。
当检测到距离小于200毫米时,认为有人脸靠近门口,显示“Face detected!”在OLED显示屏上,并记录日志。
可以根据需要在门禁开启操作的部分添加相关代码。

案例8::人脸识别门禁系统进阶版

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SoftwareSerial.h>
#include <SparkFun_OpenLog_Artemis.h>
#include <VL53L1X.h>
#include <SparkFun_VL53L1X.h>
#include <Adafruit_MLX90614.h>Adafruit_SSD1306 display(128, 64, &Wire, -1);
VL53L1X sensor;
OpenLogArtemis openLog;
Adafruit_MLX90614 mlx;#define OLED_RESET -1void setup() {display.begin(SSD1306_SWITCHCAPVCC, 0x3C);display.clearDisplay();display.setTextColor(WHITE);display.setTextSize(1);display.setCursor(0, 0);display.println("Welcome!");openLog.begin();openLog.setMode(LOG_MODE_COMMAND);Wire.begin();sensor.setTimeout(500);sensor.init();sensor.startContinuous();mlx.begin();
}void loop() {int distance = sensor.readRangeContinuousMillimeters();if (distance < 200) {display.clearDisplay();display.setCursor(0, 0);display.println("Face detected!");float temperature = mlx.readObjectTempC();display.setCursor(0, 20);display.print("Temperature: ");display.print(temperature);display.println("C");display.display();delay(2000);openLog.printLog("Face detected");// 执行门禁开启操作}
}

要点解读:
在基础版的基础上,添加了MLX90614红外温度传感器,用于检测人脸的体温。
使用Adafruit MLX90614库读取人脸的体温,并显示在OLED显示屏上。
可以根据需要在门禁开启操作的部分添加相关代码。

案例9:人脸识别门禁系统高级版

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SoftwareSerial.h>
#include <SparkFun_OpenLog_Artemis.h>
#include <VL53L1X.h>
#include <SparkFun_VL53L1X.h>
#include <Adafruit_MLX90614.h>
#include <SparkFun_GridEYE_Arduino_Library.h>Adafruit_SSD1306 display(128, 64, &Wire, -1);
VL53L1X sensor;
OpenLogArtemis openLog;
Adafruit_MLX90614 mlx;
GridEYE grideye;#define OLED_RESET -1void setup() {display.begin(SSD1306_SWITCHCAPVCC, 0x3C);display.clearDisplay();display.setTextColor(WHITE);display.setTextSize(1);display.setCursor(0, 0);display.println("Welcome!");openLog.begin();openLog.setMode(LOG_MODE_COMMAND);Wire.begin();sensor.setTimeout(500);sensor.init();sensor.startContinuous();mlx.begin();grideye.begin();grideye.setMode(MODE_NORMAL);grideye.setInterruptMode(MODE_DIFFERENCE);grideye.setInterruptThreshold(2);
}void loop() {int distance = sensor.readRangeContinuousMillimeters();if (distance < 200) {display.clearDisplay();display.setCursor(0, 0);display.println("Face detected!");float temperature = mlx.readObjectTempC();display.setCursor(0, 20);display.print("Temperature: ");display.print(temperature);display.println("C");display.display();delay(2000);openLog.printLog("Face detected");grideye.readPixels();if (grideye.isInterruptTriggered()) {display.clearDisplay();display.setCursor(0, 0);display.println("Motion detected!");display.display();delay(2000);openLog.printLog("Motion detected");// 执行门禁开启操作}}
}

要点解读:
在进阶版的基础上,添加了GridEYE红外热像仪传感器,用于检测人体活动。
使用SparkFun GridEYE库读取红外热像仪传感器的数据,并检查是否有运动发生。
如果检测到运动发生,显示“Motion detected!”在OLED显示屏上,并记录日志。
可以根据需要在门禁开启操作的部分添加相关代码。这些案例提供了不同级别的人脸识别门禁系统的示例代码,可以根据需求对其进行修改和扩展。这些代码案例仅供参考,实际应用中可能需要根据具体硬件和库的使用方式进行适当的调整。

请注意,以上案例只是为了拓展思路,可能存在错误、不适用或者不能通过编译的情况。不同的硬件平台、使用场景和Arduino版本可能会导致不同的使用方法。在实际编程中,您需要根据您自己的硬件配置、使用场景和具体需求进行调整,并进行多次实际测试。需要正确连接硬件并了解所使用的传感器和设备的规范和特性非常重要。对于涉及到硬件操作的代码,请确保在使用之前充分了解和确认所使用的引脚和电平等参数的正确性和安全性。

在这里插入图片描述

这篇关于雕爷学编程】Arduino 手册之智能家居的人脸识别门禁系统的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/742921

相关文章

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。

Go Playground 在线编程环境

For all examples in this and the next chapter, we will use Go Playground. Go Playground represents a web service that can run programs written in Go. It can be opened in a web browser using the follow

深入理解RxJava:响应式编程的现代方式

在当今的软件开发世界中,异步编程和事件驱动的架构变得越来越重要。RxJava,作为响应式编程(Reactive Programming)的一个流行库,为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJava的核心概念、优势以及如何在实际项目中应用它。 文章目录 💯 什么是RxJava?💯 响应式编程的优势💯 RxJava的核心概念

函数式编程思想

我们经常会用到各种各样的编程思想,例如面向过程、面向对象。不过笔者在该博客简单介绍一下函数式编程思想. 如果对函数式编程思想进行概括,就是f(x) = na(x) , y=uf(x)…至于其他的编程思想,可能是y=a(x)+b(x)+c(x)…,也有可能是y=f(x)=f(x)/a + f(x)/b+f(x)/c… 面向过程的指令式编程 面向过程,简单理解就是y=a(x)+b(x)+c(x)

arduino ide安装详细步骤

​ 大家好,我是程序员小羊! 前言: Arduino IDE 是一个专为编程 Arduino 微控制器设计的集成开发环境,使用起来非常方便。下面将介绍如何在不同平台上安装 Arduino IDE 的详细步骤,包括 Windows、Mac 和 Linux 系统。 一、在 Windows 上安装 Arduino IDE 1. 下载 Arduino IDE 打开 Arduino 官网

Java并发编程之——BlockingQueue(队列)

一、什么是BlockingQueue BlockingQueue即阻塞队列,从阻塞这个词可以看出,在某些情况下对阻塞队列的访问可能会造成阻塞。被阻塞的情况主要有如下两种: 1. 当队列满了的时候进行入队列操作2. 当队列空了的时候进行出队列操作123 因此,当一个线程试图对一个已经满了的队列进行入队列操作时,它将会被阻塞,除非有另一个线程做了出队列操作;同样,当一个线程试图对一个空

单片机毕业设计基于单片机的智能门禁系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍程序代码部分参考 设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订

生信代码入门:从零开始掌握生物信息学编程技能

少走弯路,高效分析;了解生信云,访问 【生信圆桌x生信专用云服务器】 : www.tebteb.cc 介绍 生物信息学是一个高度跨学科的领域,结合了生物学、计算机科学和统计学。随着高通量测序技术的发展,海量的生物数据需要通过编程来进行处理和分析。因此,掌握生信编程技能,成为每一个生物信息学研究者的必备能力。 生信代码入门,旨在帮助初学者从零开始学习生物信息学中的编程基础。通过学习常用