发布于: Aug 11, 2022

Amazon Rekognition 是一个人工智能图像检测平台,下面我们就以个人防护设备的识别为例,详细介绍一下他的工作原理。

工作原理

要检查图像中的 PPE,您可以调用 DetectProtectiveEquipment
API 并传递输入图像。您可以提供输入图像(JPG 或 PNG 格式),将其作为原始字节或者存储在 Amazon Simple Storage Service (Amazon S3) 存储桶内的对象。您也可以选择使用 SummarizationAttributes (ProtectiveEquipmentSummarizationAttributes)输入参数来请求关于佩戴所需PPE、未佩戴所需PPE或者不确定人员的摘要信息。

下图所示,为示例输入图像以及在 Amazon Rekognition PPE 检测控制台上看到的来自 DetectProtectiveEquipment 的相应输出。在此示例中,我们将口罩作为必要PPE,并将 80% 设定为摘要属性中的最低置信度阈值。我们收到一项汇总结果,表明图像中有4人佩戴有脸部覆盖物,且置信度得分均超过 80%(人物标识符 0、1、2、3)。它还在每位人员的分析结果中提出完整的保真度 API 响应。请注意,此功能不会执行人脸识别或者面部比较,也无法识别出检测到的人物。

以下,为控制台内指向此示例图像的 DetectProtectiveEquipment API 请求。

{
    "Image": {
        "S3Object": {
            "Bucket": "console-sample-images",
            "Name": "ppe_group_updated.jpg"
        }
    },
    "SummarizationAttributes": {
        "MinConfidence": 80,
        "RequiredEquipmentTypes": [
            "FACE_COVER"
        ]
    }
}

DetectProtectiveEquipment API 的响应为 JSON 结构,能够在每张图像中包含最多15位检测到的人物,并对各个人物的身体部位(面部、头部、左手与右手)、画面中的PPE类型以及 PPE 是否覆盖相应身体部位进行检测。来自此图像 DetectProtectiveEquipment API 的完整 JSON 响应如下:

"ProtectiveEquipmentModelVersion": "1.0",
    "Persons": [
        {
            "BodyParts": [
                {
                    "Name": "FACE",
                    "Confidence": 99.07738494873047,
                    "EquipmentDetections": [
                        {
                            "BoundingBox": {
                                "Width": 0.06805413216352463,
                                "Height": 0.09381836652755737,
                                "Left": 0.7537466287612915,
                                "Top": 0.26088595390319824
                            },
                            "Confidence": 99.98419189453125,
                            "Type": "FACE_COVER",
                            "CoversBodyPart": {
                                "Confidence": 99.76295471191406,
                                "Value": true
                            }
                        }
                    ]
                },
                {
                    "Name": "LEFT_HAND",
                    "Confidence": 99.25702667236328,
                    "EquipmentDetections": []
       },
                {
                    "Name": "RIGHT_HAND",
                    "Confidence": 80.11490631103516,
                    "EquipmentDetections": []
                },
                {
                    "Name": "HEAD",
                    "Confidence": 99.9693374633789,
                    "EquipmentDetections": [
                        {
                            "BoundingBox": {
                                "Width": 0.09358207136392593,
                                "Height": 0.10753925144672394,
                                "Left": 0.7455776929855347,
                                "Top": 0.16204142570495605
                            },
                            "Confidence": 98.4826889038086,
                            "Type": "HEAD_COVER",
                            "CoversBodyPart": {
                                "Confidence": 99.99744415283203,
                                "Value": true
                            }
                        }
                    ]
                }
            ],
            "BoundingBox": {
                "Width": 0.22291666269302368,
                "Height": 0.82421875,
                "Left": 0.7026041746139526,
                "Top": 0.15703125298023224
            },
            "Confidence": 99.97362518310547,
            "Id": 0
        },
        {
            "BodyParts": [
                {
                    "Name": "FACE",
                    "Confidence": 99.71298217773438,
                    "EquipmentDetections": [
                        {
                            "BoundingBox": {
                                "Width": 0.05732834339141846,
                                "Height": 0.07323434203863144,
                                "Left": 0.5775181651115417,
                                "Top": 0.33671364188194275
                            },
                            "Confidence": 99.96135711669922,
                            "Type": "FACE_COVER",
                            "CoversBodyPart": {
                                "Confidence": 96.60395050048828,
                                "Value": true
                            }
                        }
                    ]
                },
                {
                    "Name": "LEFT_HAND",
                    "Confidence": 98.09618377685547,
                    "EquipmentDetections": []
                },
                {
                    "Name": "RIGHT_HAND",
                    "Confidence": 95.69132995605469,
                    "EquipmentDetections": []
                },
                {
                    "Name": "HEAD",
                    "Confidence": 99.997314453125,
                    "EquipmentDetections": [
                        {
                            "BoundingBox": {
                                "Width": 0.07994530349969864,
                                "Height": 0.08479492366313934,
                                "Left": 0.5641391277313232,
                                "Top": 0.2394576370716095
                            },
                            "Confidence": 97.718017578125,
                            "Type": "HEAD_COVER",
                            "CoversBodyPart": {
                                "Confidence": 99.9454345703125,
                                "Value": true
                            }
                        }
                    ]
                }
            ],
            "BoundingBox": {
                "Width": 0.21979166567325592,
                "Height": 0.742968738079071,
                "Left": 0.49427083134651184,
                "Top": 0.24296875298023224
            },
            "Confidence": 99.99588012695312,
            "Id": 1
        },
        {
            "BodyParts": [
                {
                    "Name": "FACE",
                    "Confidence": 98.42090606689453,
                    "EquipmentDetections": [
                        {
                            "BoundingBox": {
                                "Width": 0.05756797641515732,
                                "Height": 0.07883334159851074,
                                "Left": 0.22534936666488647,
                                "Top": 0.35751715302467346
                            },
                            "Confidence": 99.97816467285156,
                            "Type": "FACE_COVER",
                            "CoversBodyPart": {
                                "Confidence": 95.9388656616211,
                                "Value": true
                            }
                        }
                    ]
                },
                {
                    "Name": "LEFT_HAND",
                    "Confidence": 92.42487335205078,
                    "EquipmentDetections": []
                },
                {
                    "Name": "RIGHT_HAND",
                    "Confidence": 96.88029479980469,
                    "EquipmentDetections": []
                },
                {
                    "Name": "HEAD",
                    "Confidence": 99.98686218261719,
                    "EquipmentDetections": [
                        {
                            "BoundingBox": {
                                "Width": 0.0872764065861702,
                                "Height": 0.09496871381998062,
                                "Left": 0.20529428124427795,
                                "Top": 0.2652358412742615
                            },
                            "Confidence": 90.25578308105469,
                            "Type": "HEAD_COVER",
                            "CoversBodyPart": {
                                "Confidence": 99.99089813232422,
                                "Value": true
                            }
                        }
                    ]
                }
            ],
            "BoundingBox": {
                "Width": 0.19479165971279144,
                "Height": 0.72265625,
                "Left": 0.12187500298023224,
                "Top": 0.2679687440395355
            },
            "Confidence": 99.98648071289062,
            "Id": 2
        },
        {
            "BodyParts": [
                {
                    "Name": "FACE",
                    "Confidence": 99.32310485839844,
                    "EquipmentDetections": [
                        {
                            "BoundingBox": {
                                "Width": 0.055801939219236374,
                                "Height": 0.06405147165060043,
                                "Left": 0.38087061047554016,
                                "Top": 0.393160879611969
                            },
                            "Confidence": 99.98370361328125,
                            "Type": "FACE_COVER",
                            "CoversBodyPart": {
                                "Confidence": 98.56526184082031,
                                "Value": true
                            }
                        }
                    ]
                },
                {
                    "Name": "LEFT_HAND",
                    "Confidence": 96.11709594726562,
                    "EquipmentDetections": []
                },
                {
                    "Name": "RIGHT_HAND",
                    "Confidence": 80.49284362792969,
                    "EquipmentDetections": []
                },
                {
                    "Name": "HEAD",
                    "Confidence": 99.91870880126953,
                    "EquipmentDetections": [
                        {
                            "BoundingBox": {
                                "Width": 0.08105235546827316,
                                "Height": 0.07952981442213058,
                                "Left": 0.36679577827453613,
                                "Top": 0.2875025272369385
                            },
                            "Confidence": 98.80988311767578,
                            "Type": "HEAD_COVER",
                            "CoversBodyPart": {
                                "Confidence": 99.6932144165039,
                                "Value": true
                            }
                        }
                    ]
                }
            ],
            "BoundingBox": {
                "Width": 0.18541666865348816,
                "Height": 0.6875,
                "Left": 0.3187499940395355,
                "Top": 0.29218751192092896
            },
            "Confidence": 99.98927307128906,
            "Id": 3
        }
    ],
    "Summary": {
        "PersonsWithRequiredEquipment": [
            0,
            1,
            2,
            3
        ],
        "PersonsWithoutRequiredEquipment": [],
        "PersonsIndeterminate": []
    }
}

部署 Amazon Rekognition PPE 检测

根据您的实际用例、摄像机与环境设置,大家可以使用不同的方法来分析本地摄像机内容,借此进行 PPE 检测。由于 DetectProtectiveEquipment API 仅接受图像作为输出,因此您可以设定预期频率(例如每 1 秒、2 秒或 5 秒,或者每次检测到运动时)从流式传输或存储的视频中提取画面帧,并使用 DetectProtectiveEquipment API 分析这些帧。您还可以为覆盖不同区域的摄像机设置不同的帧摄取频率。例如,您可以在繁忙或重要的地点设置较高的频率,而为相对普通的区域设定较低的频率。以此为基础,您可以控制网络带宽要求,更高效地将重要图像发送至 Amazon Web Services 云进行处理。

以下架构所示,为如何设计无服务器工作流以处理来自摄像机的画面帧并进行 PPE 检测。

我们在 Amazon Rekognition PPE 检测的 GitHub repo 中包含一个用于实现这套参考架构的演示Web应用程序。此 Web 应用程序能够从网络摄像机视频提要中提取帧,并将其发送至部署在 Amazon Web Services 云端的解决方案。在使用 DetectProtectiveEquipment API 分析图像时,Web 应用程序中的摘要输出将以近实时方式显示。通过以下示例 GIF,我们可以看到网络摄像机以每2秒钟一次的频率进行帧采样时,检测到的面部、头部与手部覆盖物检测结果。根据实际使用需求,您可以将采样率调整为更高或更低的频率。截屏中显示出完整的演示应用程序输出,包括 PPE 以及 PPE 磨损情况的预测。

口罩检测

手套检测

头盔检测

完整的演示 Web 应用程序输出结果

使用这款应用程序及解决方案,您可以使用 Amazon Simple Notification Service 生成通知。尽管未在演示解决方案中体现(但参考架构中有所包含),您仍然可以存储 PPE 检测结果,以供后续通过 Amazon Web Services Glue、Amazon Athena 以及 Amazon QuickSight 等 Amazon Web Services 服务创建 PPE 检测事件的匿名报告。您还可以选择在特定时间之内将提取到的图像存储在 Amazon S3 当中,借此进行监管审计。关于部署演示 Web 应用程序及解决方案的说明,请参阅Amazon Rekognition PPE检测 GitHub repo。

除了通过 Amazon API Gateway 发送图像之外,您还可以将图像直接发送至S3 存储桶。以此为基础,您可以将其他元数据(包括摄像机位置、时间以及其他摄像机信息)存储为 Amazon S3 对象元数据。图像处理完成之后,您可以根据组织的数据保留策略要求,通过 S3 存储桶的生命周期策略立即将其删除、或者设置时间窗口以定期进行数据清理。大家可以使用以下参考架构设计出这样一套替代性的工作流。

从视频系统中提取图像帧

根据您所使用的摄像机设置与视频管理系统,大家可以使用制造商提供的 SDK 提取图像帧。对于支持 HTTP 或 RTSP 流的摄像机,以下代码示例演示了如何从摄像机的提要中以所需频率提取图像帧,并使用 DetectProtectiveEquipment API 对其进行处理。

import cv2
import boto3
import time
from datetime import datetime
import json

def processFrame(videoStreamUrl):
    cap = cv2.VideoCapture(videoStreamUrl)
    ret, frame = cap.read()
    if ret:
        hasFrame, imageBytes = cv2.imencode(".jpg", frame)
        if hasFrame:
            session = boto3.session.Session()
            rekognition = session.client('rekognition')
            response = rekognition. detect_protective_equipment(
                    Image={
                        'Bytes': imageBytes.tobytes(),
                    }
                )
            print(response)
    cap.release()

# 视频流
videoStreamUrl = "rtsp://@192.168.10.100"
frameCaptureThreshold = 300

while (True):
    try:
        processFrame(videoStreamUrl)
    except Exception as e:
        print("Error: {}.".format(e))

    time.sleep(frameCaptureThreshold)

要从存储的视频中提取图像帧,您可以使用 Amazon Web Services Elemental MediaConvert 或者 FFmpeg 及 OpenCV 等其他工具。以下代码所示,为如何在存储的视频中提取图像帧并使用 DetectProtectiveEquipment API 进行处理:

import json
import boto3
import cv2
import math
import io

videoFile = "video file"
rekognition = boto3.client('rekognition')        
ppeLabels = []    
cap = cv2.VideoCapture(videoFile)
frameRate = cap.get(5) #帧率
while(cap.isOpened()):
    frameId = cap.get(1) #当前帧数
    print("Processing frame id: {}".format(frameId))
    ret, frame = cap.read()
    if (ret != True):
        break
    if (frameId % math.floor(frameRate) == 0):
        hasFrame, imageBytes = cv2.imencode(".jpg", frame)

        if(hasFrame):
            response = rekognition. detect_protective_equipment(
                Image={
                    'Bytes': imageBytes.tobytes(),
                }
            )
        
        for person in response["Persons"]:
            person["Timestamp"] = (frameId/frameRate)*1000
            ppeLabels.append(person)

print(ppeLabels)

with open(videoFile + ".json", "w") as f:
    f.write(json.dumps(ppeLabels)) 

cap.release()

检测其他及自定义PPE

DetectProtectiveEquipment API 能够涵盖大部分常见的 PPE,但如果您的用例需要识别特定于业务需求的其他设备,则可以使用 Amazon Rekognition 自定义标签。例如,您可以使用 Amazon Rekognition 自定义标签快速训练自定义模型,提供包含待检测内容的标记图像以识别安全眼镜、高识别度背心或者其他自定义 PPE。使用 Amazon Rekognition 自定义标签不需要任何机器学习专业知识。在您训练好自定义模型并准备进行推理时,则可并行调用 DetectProtectiveEquipment 与 Amazon Rekognition 自定义标签模型,借此检测所有必要的PPE,并合并结果以供进一步处理。关于使用 Amazon Rekognition 自定义标签检测高识别度背心(包括带有说明的示例解决方案)的更多详细信息,请参阅自定义 PPE 检测 GitHub repo。您可以使用以下参考架构图以设计出将 DetectProtectiveEquipment 与 Amazon Rekognition
Custom Labels PPE 将结合的检测解决方案。

总结

在本文中,我们展示了如何使用检测(DetectProtectiveEquipment API)来自动分析图像及视频帧,借此检查员工及客户是否正确佩戴个人防护设备,例如口罩、头盔与手套等。我们介绍了多种实现方法,包括从摄像机、存储视频以及流式视频中提取图像帧。最后,我们还介绍了如何使用Amazon Rekognition自定义标签来识别特定实际业务需求的其他设备。

要使用您自己的图像测试PPE检测,请登录至 Amazon Rekognition 控制台,而后将图像上传至 Amazon Rekognition PPE 检测控制台演示当中。关于 API输入、输出、限制及建议的更多详细信息,请参阅 Amazon Rekognition PPE 检测说明文档。要了解客户对此项功能的看法,或者思考是否需要合作伙伴帮助您的组织构建端到端 PPE 检测解决方案,请参阅 Amazon Rekognition 工作场所安全网页。

相关文章