人脸解锁智能门
组件和用品
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 2 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 2 | ||||
| × | 2 | ||||
| × | 1 |
必要的工具和机器
|
应用和在线服务
| ||||
| ||||
| ||||
| ||||
|
关于这个项目
欢迎,好奇的朋友!我们生活在一个互联网革命化的时代,现在比以往任何时候都更容易尝试和创新自己,以提出可以对世界各地数百万人产生积极影响的绝妙想法。
曾经想为家中的架子、抽屉、衣柜或门增加一点额外的安全性吗?谈到使用互联网进行创新时,在我们可用的数以千计的平台和工具中,最突出的是 Arduino
和 Bolt IoT
.在这个项目中,我们将修改一个标准货架,使其拥有一个使用人脸验证解锁的安全系统。 我们将构建一个 Windows 窗体应用程序 在 C# 中 可以存储、验证和解锁可信面孔。它使用 FacePlusPlus API
用于人脸验证和 Bolt IoT Cloud API 用于与 Bolt WiFi 模块和 Arduino 通信。我们将 Bolt WiFi 模块与 Arduino Uno 连接 ,这将控制伺服电机锁定/解锁门。
兴奋的?让我们开始吧。
背景
我将这个项目作为 Internshala Trainings 举办的创新挑战和物联网培训的一部分。他们的培训有助于了解处理 API 服务、面向对象编程以及最重要的是使用 Bolt WiFi 模块的基础知识。作为本次培训的一部分完成的 Capstone 项目的概要可以在这里找到。在这个项目的开发过程中,很多这些概念都派上了用场。所以向 Internshala 团队大喊大叫,让这一切成为可能。
第 1 步:构建软件
我们将使用 Visual Studio 构建一个 Windows 窗体应用程序。该应用程序在 Windows 机器上运行,将负责管理授权人脸、使用 FacePlusPlus API 验证人脸以及与 Bolt WiFi 模块通信。我们将使用 C# 进行编码。
启动 Visual Studio 并创建新的 Windows 窗体应用程序项目。如果您完全不熟悉 Visual Studio,我建议您学习使用 Visual Studio 进行 Windows 窗体应用程序开发的基础知识。这和这都是很好的入门资源。
在本教程中,我将仅使用项目中执行主要和重要功能的片段来解释代码。通读整个代码将是乏味且不必要的,因为其中大部分都是不言自明且有据可查的。
我们的 Visual Studio 项目将 3 个库用于各种目的。它们是:
- AForge .NET :一种流行的 .NET 框架,用于在 Windows 中进行图像处理。我们使用它从网络摄像头捕捉图像。
- 螺栓物联网 API .NET :我用 C# 编写的一个非官方客户端库,用于传达 Bolt Cloud API。
- Newtonsoft JSON :一种流行的 .NET 高性能 JSON 框架。用于解析我们项目中的 API 响应。
注意:为了清楚说明上述 API 中不同方法的用法,请参阅此处、此处和此处各自的文档。
开始使用
在开始编码之前,我们需要进行一些设置。
1. Bolt 云 API 凭据
如果您还没有,请访问 cloud.boltiot.com 并设置一个帐户。登录后,将您的 WiFi 模块与 Bolt 云链接。为此,请在您的手机上下载 Bolt IoT Setup App。按照应用程序中给出的说明将您的设备与您的帐户相关联。这涉及将 Bolt 与本地 WiFi 网络配对。成功链接后,您的仪表板将显示您的设备。您现在可以获取设备 ID 和 API 密钥 从仪表板。
2. FacePlusPlus API 凭证
我们在这个项目中依赖的另一个 API 服务是 FacePlusPlus API .它是一个免费平台,提供各种图像识别服务。我们将其用于面部识别。创建一个帐户并转到 FacePlusPlus 控制台。转到 API 密钥
在 Apps
下 然后点击+Get API Key
.记下新生成的 API 密钥 和 API 秘密 .
现在您应该准备好以下内容:
私有只读字符串 BOLT_DEVICE_ID ="BOLTXXXXXX";私有只读字符串 BOLT_API_KEY ="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";私有只读字符串 FPP_API_KEY ="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";私有只读字符串 FPP_API_SECRET ="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
我们创建一个名为 myBolt
的 Bolt 类的新全局实例 ,我们将通过它与 WiFi 模块进行所有未来的通信:
myBolt =new Bolt(BOLT_API_KEY, BOLT_DEVICE_ID);
也就是说,现在让我们看看我们的应用程序如何执行一些核心功能。
1. 锁定/解锁门
我们设计的电路使得当数字引脚 0 为 HIGH
, 门应该被锁上,当数字引脚 3 HIGH
,门应该是开着的。稍后我们讨论电路原理图时会更清楚这一点。
对于锁定,我们使用 DigitalMultiWrite
从库中编写HIGH
的方法 值到 D0 和低值到 D3。这将通知 Arduino 锁门。同样的解锁,我们会写LOW
值为 D0 和 HIGH
D3 的值。这将通知 Arduino 解锁门。我们将在本教程后面讨论 Arduino 代码和电路设计。
执行锁定的代码:
private async Task LockDoor(){ MultiPinConfig multiPinConfig =new MultiPinConfig(); MultiPinConfig.AddPinState(DigitalPins.D0, DigitalStates.High); //锁定信号 multiPinConfig.AddPinState(DigitalPins.D3, DigitalStates.Low); //解锁信号 await myBolt.DigitalMultiWrite(multiPinConfig); multiPinConfig =new MultiPinConfig(); multiPinConfig.AddPinState(DigitalPins.D0, DigitalStates.Low); //锁定信号 multiPinConfig.AddPinState(DigitalPins.D3, DigitalStates.Low); //解锁信号 await myBolt.DigitalMultiWrite(multiPinConfig);}
执行解锁的代码:
private async Task UnlockDoor(){ MultiPinConfig multiPinConfig =new MultiPinConfig(); multiPinConfig.AddPinState(DigitalPins.D0, DigitalStates.Low); //锁定信号 multiPinConfig.AddPinState(DigitalPins.D3, DigitalStates.High); //解锁信号 await myBolt.DigitalMultiWrite(multiPinConfig); multiPinConfig =new MultiPinConfig(); multiPinConfig.AddPinState(DigitalPins.D0, DigitalStates.Low); //锁定信号 multiPinConfig.AddPinState(DigitalPins.D3, DigitalStates.Low); //解锁信号 await myBolt.DigitalMultiWrite(multiPinConfig);}
2. 添加/删除可信面孔
可信人脸的图像数据被编码成 Base64 字符串并存储在机器本地。每张脸的对应名称的列表也被存储。在我们的程序中,要添加人脸,我们首先验证当前帧中是否有可用的人脸。我们使用 FacePlusPlus 的 Detect API 来做到这一点。它返回一个 JSON 响应,其中包含检测到的面部特征。如果没有检测到人脸,响应将是 []
.一旦检测到人脸,我们就会保存图像的 base64 编码字符串和相应的名称。这是添加可信面孔的视频演示。
去除面部非常简单。按删除按钮将从保存的列表中删除图像数据和名称。
添加和保存人脸信息的代码:
//将图片转为base64字符串并添加到列表中。 ImageDataList.Add(ImageToBase64((Image)PreviewBox.Image.Clone()));//将人脸名称添加到listNameList.Add(FaceNameTextBox.Text.Trim()); //将人脸图像数据保存为基本编码字符串,连同其 nameProperties.Settings.Default.Base64ImageData =ImageDataList;Properties.Settings.Default.FaceNames =NameList;Properties.Settings.Default.Save();
删除人脸信息的代码:
//移除listNameList.RemoveAt(e.RowIndex)中指定位置的人脸信息;ImageDataList.RemoveAt(e.RowIndex); //删除后保存列表 faceProperties.Settings.Default.FaceNames =NameList;Properties.Settings.Default.Base64ImageData =ImageDataList;Properties.Settings.Default.Save();
查看所附项目中的代码,其中每一行都以注释的形式解释了流程,以便有一个清晰的想法。
3. 人脸验证
我们通过使用 FacePlusPlus 中的比较 API 来验证人脸是否可信。在这个过程中,我们线性迭代保存列表中的每个人脸,并将其与捕获的图像进行比较。如果 API 返回超过 80% 的置信度,我们将打开大门。
进行此比较的代码如下所示:
WebClient 客户端 =new WebClient(); byte[] response =client.UploadValues("https://api-us.faceplusplus.com/facepp/v3/compare", new NameValueCollection(){ { "api_key", FPP_API_KEY }, { "api_secret", FPP_API_SECRET }, { "image_base64_1", face1Base64}, { "image_base64_2", face2Base64} });});字符串置信度 =JObject.Parse(System.Text.Encoding.UTF8.GetString(response))["confidence"].ToString();
WebClient.UploadValues 方法将请求连同要比较的两个人脸的 base64 编码人脸数据和我们的 API 凭据一起发送到 FacePlusPlus API。使用 Newtonsoft JSON 解析响应 图书馆和信心
值获得。阅读比较 API 文档以清楚地理解参数。
4. 铃听线程
我们计划提供一个物理按钮,类似于呼叫铃铛按钮,以便用户可以在注视摄像头的同时按下以解锁门。为了使这成为可能,我们需要创建一个新的专用线程来持续监听铃铛按钮按下事件。
在本教程的后面,我们将看到如何使用按钮以及它如何制作 Bolt WiFi 模块的 D4 引脚 HIGH
当按钮被按下时。现在,我们只假设上述情况。所以在这个线程中,我们不断DigitalRead
D4 引脚的值。如果它是 HIGH
,我们将其视为铃声事件并进行面部捕获和验证。
这是将在响铃监听线程上连续运行的代码:
while (ListenForBell){ Response R =await myBolt.DigitalRead(DigitalPins.D4); if (R.Value =="1") { RingBell_Click(null, null);线程睡眠(2000); } Thread.Sleep(2000);}
我们停止并在每次迭代之间等待 2 秒。否则会很快耗尽 Bolt Cloud API 的使用配额。
第 2 步:构建 Visual Studio 项目
下载整个项目 这里 .打开 Facebolt Doorlock.sln
Visual Studio 中的文件。解决方案加载后,打开Form1.cs
文件并使用您的 API 凭据更新代码。按名为“开始”的绿色播放按钮,构建并运行程序。
该程序允许您从连接到系统的摄像头设备中进行选择,并查看来自摄像头的实时馈送。您可以添加/删除受信任的面孔。开始人脸监测。一旦程序验证了您的 Bolt 设备的连接性,您就可以直接通过程序按铃或锁门。
图> 图>如果您现在对程序中的面部验证、锁定和解锁的工作方式感到困惑,那没关系。一旦我们看到电路原理图设计和 Arduino 代码,它就会变得更加清晰。我也会在最后分解每个操作的事件流。
第 3 步:电路设计和 Arduino 代码
在我们的电路中,我们打算实现以下功能:
- 红色和绿色 LED 指示灯分别表示锁定和解锁的门状态。
- 用作呼叫铃开关的按钮。按下后,我们的 WinForms 应用程序应验证人脸并在人脸验证成功后开门。
- 另一个用于锁门的按钮。
- 在门铃响起和门锁响起时会发出蜂鸣声的蜂鸣器。
我们项目的电路连接如下图所示:
图>如果您还没有,请从这里下载 Arduino IDE 并将您的 Arduino 连接到系统。在上传代码之前,请确保您已在 IDE 设置中设置了正确的 Arduino 模型和端口。
Arduino 代码:
#include #define ServoPin 4#define LockSignalPin 2#define UnLockSignalPin 3#define BellButtonPin 5#define LockButtonPin 8#define RingBellSignalPin 6#define BuzzerPin 7#define GreenLedPin 9#define RedLedPin 10 Servo我的伺服器; void setup() { pinMode(LockSignalPin, INPUT); pinMode(UnLockSignalPin, INPUT); pinMode(BellButtonPin,输入); pinMode(LockButtonPin, INPUT); pinMode(BuzzerPin, OUTPUT); pinMode(RedLedPin,输出); pinMode(GreenLedPin,输出); pinMode(RingBellSignalPin,输出);数字写入(RedLedPin,低);数字写入(GreenLedPin,低);数字写入(RingBellSignalPin,低); myServo.attach(ServoPin); Serial.begin(9600);} void loop() { int lockButton, lock, unlock, bell;字符数[5]; lock =digitalRead(LockSignalPin);解锁 =digitalRead(UnLockSignalPin); // 检查来自 Bolt 的锁定信号是否为高 if(lock ==HIGH) { // 将电机转动到锁定位置 myServo.write(120); // 设置 LED 指示 digitalWrite(GreenLedPin, LOW);数字写入(RedLedPin,高); // 蜂鸣锁定声音 digitalWrite(BuzzerPin, HIGH);延迟(1000);数字写入(蜂鸣器引脚,低);延迟(1000); } // 检查来自 Bolt 的解锁信号是否为高电平 else if(unlock ==HIGH) { // 将电机转动到解锁位置 myServo.write(0); // 设置 LED 指示 digitalWrite(GreenLedPin, HIGH);数字写入(RedLedPin,低);延迟(2000); } bell =digitalRead(BellButtonPin); if(bell ==HIGH) // 用户按下铃声 betton { // 按下响铃按钮的信号螺栓 digitalWrite(RingBellSignalPin, HIGH); // 呼叫铃声模式!数字写入(蜂鸣器引脚,高);延迟(100);数字写入(蜂鸣器引脚,低);延迟(20);数字写入(蜂鸣器引脚,高);延迟(200);数字写入(蜂鸣器引脚,低);延迟(100);数字写入(蜂鸣器引脚,高);延迟(100);数字写入(蜂鸣器引脚,低);延迟(20);数字写入(蜂鸣器引脚,高);延迟(200);数字写入(蜂鸣器引脚,低);延迟(1500); // 关闭信号 digitalWrite(RingBellSignalPin, LOW); } lockButton =digitalRead(LockButtonPin); if(lockButton ==HIGH) // 用户按下锁定按钮 { // 将电机转动到锁定位置 myServo.write(120); // 设置 LED 指示 digitalWrite(GreenLedPin, LOW);数字写入(RedLedPin,高); // 蜂鸣锁定声音 digitalWrite(BuzzerPin, HIGH);延迟(1000);数字写入(蜂鸣器引脚,低); }}
事件流
现在我们已经准备好 WinForm 应用程序和 Arduino 设计,让我们深入代码并探索每个操作的控制流程。
1.戒指 按钮按下
2.锁定 按钮按下
上述操作也可以直接从 Windows 窗体应用程序执行。
在这里,我们可以观察到 Bolt WiFi 模块 作为 Windows 窗体应用程序和 Arduino 之间的重要无线接口。 Bolt Cloud API 的使用使我们能够扩展我们的项目并在其他平台(如 Android)上构建应用程序,并使用我们的手机解锁门!这种灵活性正是物联网和 Bolt 平台的强大之处。
现在我们已经完成了软件设计部分,让我们继续构建一个可上锁的门机制。
第 4 步:构建硬件
我有一个鞋架,所以在这个项目中,我要用它来演示锁。您可以使用架子、门或衣柜或任何具有可破解锁定机制的东西。这真的取决于你。
图> 图> 图>我们需要建立一个耦合机制,将我们的伺服电机与锁连接起来。为此,我的想法是使用一个瓶子和另一个瓶盖的切口颈部。将瓶颈连接到伺服电机,将盖子连接到锁上。然后我们将使用尼龙线将它们连接起来。每当电机转动时,这将导致锁定/解锁动作。
所需的瓶颈在其瓶盖上钻了一个孔,如下图所示。我们将把它固定在鞋架的锁轴上。
图>另一个瓶盖必须连接到伺服电机上。我们使用铜线将帽连接到电机的转轴。
图> 图>现在我们需要将这两者结合起来。为此,我们使用尼龙线。使用所需长度的线制作一个环,并将线连接到两个盖子上。
图>一旦耦合,它们可以引起相互旋转的动作:
现在我们已经准备好转动机构,是时候进入锁并固定我们的瓶颈了。我们在里面钻了一个洞,所以我们需要做的就是从机架上拧下锁轴,将瓶颈放在它上面,然后重新拧紧锁。
现在唯一要做的就是将伺服电机固定在鞋架上。我们将使用热胶枪将电机密封到机架上。
图>调整螺纹的长度并充分拧紧后,我们就准备好了最后的设置。如下图,伺服电机可以正确锁定和解锁门!
图>您不一定必须使用瓶颈 - 螺纹耦合方法。使用最适合您的锁系统和最方便的方法。
幸运的是,我在机架的正确位置有一个小开口。这让我可以轻松地将伺服电机连接出来。经过一些装饰工作和贴标签,我们最后的智能鞋架现在可以开始使用了。
图> 图> 图> 图> 图>我们现在都准备好了。剩下要做的就是启动电路,在 WinForms 应用程序上添加一个可信的面孔,并在我们的门上享受面锁安全。您需要为 Arduino 和 Bolt WiFi 模块供电。我使用 10000 mAh 移动电源为它们供电。我使用的网络摄像头是 Microsoft LifeCam VX-800。它很旧,但仍然比笔记本电脑的相机好。请查看演示视频。它详细展示了我们项目的工作。
视频演示
观看我们的项目(对视频质量深表歉意):
结论
哈夫..那是相当长的。该项目是 Internshala 物联网培训的成果,由 Bolt IoT 提供支持。虽然这个项目非常简单,但它向我们展示了物联网的潜力以及它如何让人们的日常生活更轻松。
无论如何..这对我来说是一次很棒的学习经历。我希望你们会喜欢构建这个,我很高兴看到你们会想出什么新的创新。最后,我衷心感谢 Internshala 和 Bolt IoT 的培训团队使这次冒险成为可能。
这是一个包装!
代码
- BoltDoorLock.ino
- WinForms 应用程序 - Visual Studio 项目 (Facebolt Doorlock).zip
BoltDoorLock.inoC/C++
Arduino 代码。#include#define ServoPin 4#define LockSignalPin 2#define UnLockSignalPin 3#define BellButtonPin 5#define LockButtonPin 8#define RingBellSignalPin 6#define BuzzerPin 7#define GreenLedPin 9#define RedServLedPin 10;void setup() { pinMode(LockSignalPin, INPUT); pinMode(UnLockSignalPin, INPUT); pinMode(BellButtonPin,输入); pinMode(LockButtonPin, INPUT); pinMode(BuzzerPin, OUTPUT); pinMode(RedLedPin,输出); pinMode(GreenLedPin,输出); pinMode(RingBellSignalPin,输出);数字写入(RedLedPin,低);数字写入(GreenLedPin,低);数字写入(RingBellSignalPin,低); myServo.attach(ServoPin); Serial.begin(9600);}void loop() { int lockButton, lock, unlock, bell;字符数[5]; lock =digitalRead(LockSignalPin);解锁 =digitalRead(UnLockSignalPin); // 检查来自 Bolt 的锁定信号是否为高 if(lock ==HIGH) { // 将电机转动到锁定位置 myServo.write(120); // 设置 LED 指示 digitalWrite(GreenLedPin, LOW);数字写入(RedLedPin,高); // 蜂鸣锁定声音 digitalWrite(BuzzerPin, HIGH);延迟(1000);数字写入(蜂鸣器引脚,低);延迟(1000); } // 检查来自 Bolt 的解锁信号是否为高电平 else if(unlock ==HIGH) { // 将电机转动到解锁位置 myServo.write(0); // 设置 LED 指示 digitalWrite(GreenLedPin, HIGH);数字写入(RedLedPin,低);延迟(2000); } bell =digitalRead(BellButtonPin); if(bell ==HIGH) // 用户按下铃声 betton { // 按下响铃按钮的信号螺栓 digitalWrite(RingBellSignalPin, HIGH); // 呼叫铃声模式!数字写入(蜂鸣器引脚,高);延迟(100);数字写入(蜂鸣器引脚,低);延迟(20);数字写入(蜂鸣器引脚,高);延迟(200);数字写入(蜂鸣器引脚,低);延迟(100);数字写入(蜂鸣器引脚,高);延迟(100);数字写入(蜂鸣器引脚,低);延迟(20);数字写入(蜂鸣器引脚,高);延迟(200);数字写入(蜂鸣器引脚,低);延迟(1500); // 关闭信号 digitalWrite(RingBellSignalPin, LOW); } lockButton =digitalRead(LockButtonPin); if(lockButton ==HIGH) // 用户按下锁定按钮 { // 将电机转动到锁定位置 myServo.write(120); // 设置 LED 指示 digitalWrite(GreenLedPin, LOW);数字写入(RedLedPin,高); // 蜂鸣锁定声音 digitalWrite(BuzzerPin, HIGH);延迟(1000);数字写入(蜂鸣器引脚,低); }}
WinForms 应用程序 - Visual Studio 项目 (Facebolt Doorlock).zipC#
* 解压 zip 文件并在 Visual Studio 中打开 .sln 文件。* 使用您的 API 凭据修改代码。
* 运行项目。
* 添加可信面孔。
* 最后,开始人脸监控。
无预览(仅限下载)。
Bolt IoT Cloud API - 客户端库
这是我编写的一个非官方客户端库,用于与 Bolt Cloud API 进行通信。该库在我们的 WinForms 应用程序中用于与 Bolt WiFi 模块通信。https://github.com/diozz/Bolt-IoT-API-.NET示意图
Fritzing 电路原理图 facebolt_doorlock_2RfOtkPW2i.fzz制造工艺