我如何使用 AWS Serverless 创建一个门铃 简介 架构 工作原理 输出代码 一些经验教训 可能的改进

2025-05-24

我如何使用 AWS Serverless 创建门铃

简介

建筑学

工作原理

输出

代码

一些经验教训

可能的改进

简介

最近,我工作的地方举办了一场黑客马拉松,我和我的一位同事使用 AWS 无服务器服务 + 树莓派创建了一个智能门铃。

每当有人点击“门铃”按钮时,它都会捕捉一张图片,并通过 Amazon Rekognition 人脸库检查图片上的人脸是否已被索引。然后,它会向 Slack 发送一条消息,其中包含缩放后的图片,并带有带有时间戳的水印,该水印会显示图片上的人数以及人脸库中已收录的人员姓名。

这篇文章描述了我们如何构建这个项目以及一些学习内容。

建筑学

无服务器贝尔架构

图片:建筑

无服务器贝尔状态机

图片:状态机

工作原理

有两个主要组成部分——人脸索引和人脸识别。

人脸索引

  1. 我们用 VueJS 创建了一个简单的前端,托管在 S3 bucket 上。在这里,我们要求上传一张包含人脸和姓名的图片。

  2. 上传后,我们通过 API 网关代理一个 lambda 函数来创建一个预签名的 url,并使用这个生成的预签名的 url,将图像上传到 s3 存储桶,并将人的姓名作为元数据值。

  3. 一旦图像上传到 s3 存储桶,就会有一个 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/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

部署

  1. 首先在您要部署堆栈的区域中创建 AWS Rekognition 集合:

    aws rekognition create-collection \
    --collection-id serverless-bell-faces-collection
    
  2. 克隆 GitHub 仓库。其中包含多个目录,用于不同的目的,如下所述:

    • 后端 - 需要使用 SAM 部署源代码
    • face_index_frontend - 人脸索引前端的源代码
    • 测试 -无需使用 Raspberry Pi即可进行本地测试,您可以使用此代码测试人脸识别功能。这将上传提供的图像,类似于 Pi 将图像上传到 S3。
    • scripts_in_pi - 在 Pi 中使用的简单 python 脚本,它将从相机模块捕获图像并上传到 s3。
  3. 在 cli 中,转到/backend目录

  4. 运行命令:sam build --use-container
    这将构建具有必要依赖项的 python 函数。

  5. 然后,要部署资源,请运行:sam deploy -g
    这将要求您输入要在 AWS 中创建的堆栈的详细信息,包括堆栈名称、区域、Rekognition 人脸集合和 slack url。

    请确保在与 Rekognition 人脸集合相同的区域中创建堆栈。

  6. 部署完成后,复制这些输出值,因为它们是后续步骤中需要的:FaceIndexHostingS3Bucket, FaceIndexWebsiteURL, GeneratePresignedUrl, GeneratePresignedUrlForTesting, FaceDetectUploadBucketName

  7. 现在转到face_index_frontend人脸索引前端源代码所在的目录。

  8. 创建新.env文件复制.env.example。对于VUE_APP_GENERATE_URL_API变量,使用GeneratePresignedUrl输出值。

  9. 运行npm install以安装所需的模块,然后运行npm run build以构建项目。这将创建dist目录。

  10. 然后,我们将目录内容上传dist到 S3,用作 S3 托管网站。使用输出的值FaceIndexHostingS3Bucket作为 S3 存储桶。

    aws s3 cp dist s3://[BucketName] --recursive
    
  11. 现在您将能够使用输出值访问人脸索引网站:FaceIndexWebsiteURL

  12. 上传一张带有姓名的脸部图像,您将看到该脸部在脸部集合中的索引。
    aws rekognition list-faces --collection-id "serverless-bell-faces-collection"

在 Raspberry Pi 中

  1. 使用相机模块和 AWS 配置文件设置 Raspberry PI。

  2. 使用目录中的示例脚本scripts_in_pi捕获图像并将其上传到 S3。

    bucket-name用输出值替换FaceDetectUploadBucketName
    根据您的设置使用相关的 gpiozero 按钮编号。

  3. 一旦捕获,您就可以在 Slack 频道中看到该消息。

无需 Raspberry Pi 的本地测试

  1. 转到testing目录。

  2. 创建新.env文件复制.env.example。对于VUE_APP_GENERATE_URL_API变量,使用GeneratePresignedUrlForTesting输出值。

  3. 运行npm installnpm run serve

  4. 通过提供的网址,您可以访问前端来上传图像来检测人脸。

  5. 上传后,您可以在 Slack 频道中看到该消息。

一些经验教训

  1. 在 Rekognition 人脸集合中,ExternalImageId仅允许使用字母数字字符。因此,为了存储中间包含多个空格的姓名,我们必须将空格替换为下划线,检索时则反之亦然。

  2. 当从 S3 文件上传触发 lambda 函数时,lambda 将不会接收已上传文件的元数据。因此,要检索文件的元数据,需要再次读取该文件。

  3. 在 SAM 中,无法在函数引用的策略对象中使用自动生成的 S3 存储桶名称因此
    ,我们必须自行构建 S3 存储桶名称,而不是像此处所述,使用随机名称由 SAM 生成 S3 存储桶。

可能的改进

  1. 实现人脸索引前端、API、Lambda 函数的身份验证。
  2. 处理 Step 函数执行中的失败场景。
  3. 处理EXIF orientation上传图像的数据以获得正确的方向。

请随意尝试一下并告诉我您的想法。

文章来源:https://dev.to/aws-builders/how-i-created-a-door-bell-with-aws-serverless-3n9j
PREV
解决方案架构师技巧 - 5 种架构图类型
NEXT
React 组件中的 7 种代码异味