我如何使用 AWS Serverless 创建门铃
简介
建筑学
工作原理
输出
代码
一些经验教训
可能的改进
简介
最近,我工作的地方举办了一场黑客马拉松,我和我的一位同事使用 AWS 无服务器服务 + 树莓派创建了一个智能门铃。
每当有人点击“门铃”按钮时,它都会捕捉一张图片,并通过 Amazon Rekognition 人脸库检查图片上的人脸是否已被索引。然后,它会向 Slack 发送一条消息,其中包含缩放后的图片,并带有带有时间戳的水印,该水印会显示图片上的人数以及人脸库中已收录的人员姓名。
这篇文章描述了我们如何构建这个项目以及一些学习内容。
建筑学
图片:建筑
图片:状态机
工作原理
有两个主要组成部分——人脸索引和人脸识别。
人脸索引
-
我们用 VueJS 创建了一个简单的前端,托管在 S3 bucket 上。在这里,我们要求上传一张包含人脸和姓名的图片。
-
上传后,我们通过 API 网关代理一个 lambda 函数来创建一个预签名的 url,并使用这个生成的预签名的 url,将图像上传到 s3 存储桶,并将人的姓名作为元数据值。
-
一旦图像上传到 s3 存储桶,就会有一个 lambda 函数触发,它将检测图像中的人脸,并在预定义的 AWS Rekognition 集合(人脸集合)中创建一个以外部 ID 为名称的条目。
人脸识别
-
我们使用带有摄像头模块、无焊面包板和按钮的 Raspberry pi,创建了按下按钮时的图像捕捉部分 - “门铃”。
-
捕获的图像被上传到 AWS S3,并触发 lambda 函数来初始化 Step 函数的执行。
-
在 Step 函数中,有两个并行流程。
-
一个流程是检测图像中的人脸,并在人脸集合中搜索它们。此函数将输出检测到的人脸总数。如果识别出人脸,它还会输出这些人脸的名称。
-
另一个流程将调整图像大小并创建带有时间戳的水印。所有这些功能都使用了 lambda 函数。
-
完成这两个流程后,将触发另一个 lambda 函数来撰写消息并将其发送到 Slack 频道。
输出
在 Slack 频道中,输出将如下所示:
图片:示例输出
在这里,(我的儿子) Wanuja 和 Thenuja 已经被编入面孔集合索引,而不是我。
代码
完整的源代码可以在以下位置找到:https://github.com/pubudusj/serverless-bell
如何设置
您可以使用 AWS SAM 框架轻松部署堆栈。
先决条件:
- AWS SAM cli + AWS 配置文件设置
- npm(用于构建前端)
- Slack Webhook URL
在https://api.slack.com/apps/创建一个 Slack 应用。启用“传入 Web 钩子”,并将创建的 Web 钩子添加到工作区,并选择相应的通道。这将生成一个 Web 钩子 URL,格式如下:
https://hooks.slack.com/services/XXXX/XXXX/XXXXXX
部署
-
首先在您要部署堆栈的区域中创建 AWS Rekognition 集合:
aws rekognition create-collection \ --collection-id serverless-bell-faces-collection
-
克隆 GitHub 仓库。其中包含多个目录,用于不同的目的,如下所述:
- 后端 - 需要使用 SAM 部署源代码
- face_index_frontend - 人脸索引前端的源代码
- 测试 -无需使用 Raspberry Pi即可进行本地测试,您可以使用此代码测试人脸识别功能。这将上传提供的图像,类似于 Pi 将图像上传到 S3。
- scripts_in_pi - 在 Pi 中使用的简单 python 脚本,它将从相机模块捕获图像并上传到 s3。
-
在 cli 中,转到
/backend
目录 -
运行命令:
sam build --use-container
这将构建具有必要依赖项的 python 函数。 -
然后,要部署资源,请运行:
sam deploy -g
这将要求您输入要在 AWS 中创建的堆栈的详细信息,包括堆栈名称、区域、Rekognition 人脸集合和 slack url。请确保在与 Rekognition 人脸集合相同的区域中创建堆栈。
-
部署完成后,复制这些输出值,因为它们是后续步骤中需要的:
FaceIndexHostingS3Bucket, FaceIndexWebsiteURL, GeneratePresignedUrl, GeneratePresignedUrlForTesting, FaceDetectUploadBucketName
-
现在转到
face_index_frontend
人脸索引前端源代码所在的目录。 -
创建新
.env
文件复制.env.example
。对于VUE_APP_GENERATE_URL_API
变量,使用GeneratePresignedUrl
输出值。 -
运行
npm install
以安装所需的模块,然后运行npm run build
以构建项目。这将创建dist
目录。 -
然后,我们将目录内容上传
dist
到 S3,用作 S3 托管网站。使用输出的值FaceIndexHostingS3Bucket
作为 S3 存储桶。aws s3 cp dist s3://[BucketName] --recursive
-
现在您将能够使用输出值访问人脸索引网站:
FaceIndexWebsiteURL
。 -
上传一张带有姓名的脸部图像,您将看到该脸部在脸部集合中的索引。
aws rekognition list-faces --collection-id "serverless-bell-faces-collection"
在 Raspberry Pi 中
-
使用相机模块和 AWS 配置文件设置 Raspberry PI。
-
使用目录中的示例脚本
scripts_in_pi
捕获图像并将其上传到 S3。bucket-name
用输出值替换FaceDetectUploadBucketName
根据您的设置使用相关的 gpiozero 按钮编号。 -
一旦捕获,您就可以在 Slack 频道中看到该消息。
无需 Raspberry Pi 的本地测试
-
转到
testing
目录。 -
创建新
.env
文件复制.env.example
。对于VUE_APP_GENERATE_URL_API
变量,使用GeneratePresignedUrlForTesting
输出值。 -
运行
npm install
并npm run serve
-
通过提供的网址,您可以访问前端来上传图像来检测人脸。
-
上传后,您可以在 Slack 频道中看到该消息。
一些经验教训
-
在 Rekognition 人脸集合中,
ExternalImageId
仅允许使用字母数字字符。因此,为了存储中间包含多个空格的姓名,我们必须将空格替换为下划线,检索时则反之亦然。 -
当从 S3 文件上传触发 lambda 函数时,lambda 将不会接收已上传文件的元数据。因此,要检索文件的元数据,需要再次读取该文件。
-
在 SAM 中,无法在函数引用的策略对象中使用自动生成的 S3 存储桶名称。因此
,我们必须自行构建 S3 存储桶名称,而不是像此处所述,使用随机名称由 SAM 生成 S3 存储桶。
可能的改进
- 实现人脸索引前端、API、Lambda 函数的身份验证。
- 处理 Step 函数执行中的失败场景。
- 处理
EXIF orientation
上传图像的数据以获得正确的方向。
请随意尝试一下并告诉我您的想法。
文章来源:https://dev.to/aws-builders/how-i-created-a-door-bell-with-aws-serverless-3n9j