我是如何用 Amazon Serverless 创建一个门铃的
声明:
本文转自 DEV Community 网站,文章翻译由开发者社区提供;
点击下方链接,查看英文原文:
介绍
不久前,我所在的公司举办了一场黑客松活动,我和一个同事一起,用 AWS Serverless 服务和 raspberry pi 创建了一个智能门铃。
每当有人点击“门铃”按钮,它就会拍下一张图片,并通过 Amazon Rekognition 的人脸集合来检查图片上的人脸是否已经被索引。它会向 Slack 发送一条消息,其中包含带有水印和时间戳的缩放图像,并说明图片上的人数和人名(如果他们已经存在于人脸集合中)。
这篇博文描述了我们如何建立这个项目以及一些经验。
架构
图片:架构
图片:状态机
它是如何运行的
包括两个主要组成部分——人脸索引和人脸识别。
人脸索引
1.我们用 VueJS 创建了一个简单的前端,托管在一个 S3 桶上。在这里,我们需要上传一张带有人脸和姓名的图片。
2.上传图片之后,我们通过 API 网关代理一个 lambda 函数来创建一个预签名的 url,利用这个生成的预签名 url,我们把图片上传到 s3 bucket,把姓名作为元数据值。
3.图片上传到 s3 bucket 后,就会触发一个 lambda 函数,它将检测图片中的人脸,并在预先定义的 AWS Rekognition 集合(人脸集合)中创建一个条目,以外部 id 命名。
人脸识别
1.利用 Raspberry pi 及其相机模块、无焊面包板和一个按钮,我们创建了当按下按钮时的图像采集部分——门铃。
2.这张采集的图片被上传到 AWS S3,触发一个 lambda 函数来初始化 Step 函数的执行。
3.在 Step 函数中,有两个平行流程。
4.一个流程会检测图片中的人脸,并在人脸集合中进行搜索。这个函数将输出检测到的人脸总数。如果有识别出的人脸,它会输出这些人脸的姓名。
5.另一个流程会调整图片的大小,并创建一个带有时间戳的水印。所有这些功能都使用了 lambda 函数。
6.在完成这两个流程后,会触发另一个 lambda 函数来编写和发送消息到 Slack 频道。
输出
在 Slack 频道中,输出如下:
图片:输出示例
此时,(我的儿子)Wanuja 和 Thenuja 已经被索引到人脸集合中,而我没有。
代码
查看完整的源代码: https://github.com/pubudusj/s...
如何设置
您可以使用 AWS SAM 框架轻松部署该堆栈。
先决条件:
AWS SAM cli + AWS profile 设置
npm (用于构建前端)
Slack Webhook URL
在 https://api.slack.com/apps/,创建一个 Slack 应用。启用'Incoming web hook'并将创建的 webhook 添加到工作区,选择一个频道。这将产生一个 webhook 网址,其格式为:https://hooks.slack.com/servi...
部署
1.首先在您要部署堆栈的区域创建一个 AWS Rekognition 集合。
2.aws rekognition create-collection \
3.--collection-id serverless-bell-faces-collection
4.复制该 github repo. 以下是用于不同目的的若干个目录:
backend - s 需要使用 SAM 部署的源代码
face_index_frontend - 人脸索引前端的源代码
testing - 对于不使用 Raspberry pi 的本地测试,可以使用这个代码来测试人脸识别功能。这会上传所提供的图片,类似于 Pi 将图片上传到 s3。
scripts_in_pi - Pi 内部使用的简单 python 脚本,它从摄像头模块采集图像并上传至 s3。
5.在 cli 中,转到 /backend 目录
6.运行命令:Sam build --use-container 建立具有必要依赖性的 python 函数。
7.然后,为部署资源,运行:sam deploy -g 您需要输入要在 AWS 中创建的堆栈的详细信息,包括堆栈名称、区域、Rekognition 人脸集合和 slack url。请确保您创建的堆栈与 Rekognition 人脸集合在同一地区。
8.部署完成后,复制这些输出值,在接下来的步骤中需要使用:FaceIndexHostingS3Bucket, FaceIndexWebsiteURL, GeneratePresignedUrl, GeneratePresignedUrlForTesting, FaceDetectUploadBucketName
9.现在进入 face_index_frontend 目录,人脸索引前端的源代码位于此处。
10.创建新的 .env 文件,复制 .env.example。对于 VUE_APP_GENERATE_URL_API 变量,使用 GeneratePresignedUrl 输出值 。
11.运行 npm install 来安装需要的模块,然后运行 npm run build 来构建项目。这将创建 dist 目录。
12.然后,把 dist 目录的内容上传到 s3,作为 s3 托管的网站。使用输出 FaceIndexHostingS3Bucket 的值作为 s3 bucket。
13.aws s3 cp dist s3://[BucketName] --recursive
14.现在,可以使用输出值 FaceIndexWebsiteURL 访问人脸索引网站。
15.上传一张带有姓名的人脸图像,您会看到该人脸被索引到人脸集合中。
aws rekognition list-faces --collection-id "serverless-bell-faces-collection"
Raspberry pi
1.用相机模块和 AWS 配置文件来设置 Raspberry PI。
2.使用 scripts_in_pi 目录下的示例脚本来采集和上传图片到 S3。用输出值 FaceDetectUploadBucketName 替换 bucket-name。根据您的设置,使用相关的 gpiozero 按钮编号。
3.采集图片之后,您可以在 Slack 频道中查看消息。
不使用 Raspberry pi 的本地测试
1.进入 testing 目录。
2.创建新的 .env 文件,复制 .env.example。对于 VUE_APP_GENERATE_URL_API 变量,使用 GeneratePresignedUrlForTesting 输出值。
3.运行 npm install 和 npm run serve
4.通过提供的 URL,您可以访问前端,上传图片来检测人脸。
5.上传图片后,您可以在 Slack 频道中查看消息。
一些经验
1.在 Rekognition 人脸集合中,ExternalImageId 只能包含字母和数字字符。因此,在存储中间带有多个空格的姓名时,我们必须用下划线代替空格,当检索时也是如此。
2.当从 S3 文件上传触发一个 lambda 函数时,lambda 不会收到上传文件的元数据。因此,要检索文件的元数据,需要再次读取文件。
3.在 SAM 中,无法在函数的策略对象中使用自动生成的 S3 bucket 的名称——参考。
正因为如此,我们必须为 S3 bucket 创建名称,而不是像此处介绍的 SAM 随机生成 S3 bucket 名称。
可能的改进
1.为人脸索引前端、API、Lambda 函数实施认证。
2.在 Step 函数执行中处理失败的情况。
3.处理上传图片的 EXIF orientation 数据,以获得正确的定向。
您可以尝试以上方法,欢迎与我交流您的观点。
文章作者:Pubudu Jayawardana
Pubudu Jayawardana for AWS Community Builders
评论