01 前言
基于云端实时视频智能检测的功能,在居家安防监控领域有着较高的价值。这一场景的实现通常如下图所示分为如下几个阶段:视频流产生(Producer)、视频流存储(Storage)、视频流处理(Consumer)。
当前使用低成本的网络摄像头(硬件资源有限,不支持边缘推理计算)+云端存储推理实现家用及中小商户安防监控成为一个流行的方式。在实际的应用过程中往往需要根据 AI 场景的复杂性、多样性、成本的考量、技术难度差异选择适合当前现状的方案。例如基于成本优化的考虑,我们希望采用图片作为智能检测的数据输入,发送用户告警通知的媒体信息通常也是图片格式,因此通常需要从视频流中提取图片,但从视频流中抽取图片往往需要维护可扩展的计算资源来将视频转码为图片格式,这对没有的专业领域技术积累的团队来说是个不小的挑战。本文将详细介绍如何使用 Amazon 新推出的 Amazon Kinesis Video Streams Images 来简化云端抽图。
相关产品介绍
▌Amazon Kinesis Video Streams 是一项完全托管的 Amazon 服务,您可以使用 Kinesis Video Streams 捕获来自数百万种源(包括智能手机、安全摄像头、网络摄像头、车载摄像头、无人机及其他源)的海量实时视频数据传输到 Amazon云,或者构建应用程序以进行实时视频处理或进行面向批处理的视频。
▌Amazon Kinesis Video Stream Images 是 KVS 上一组完全托管的 API,它提供了如下的功能特性:
● 以完全托管的方式从 KVS 视频流中抽取图片并保存到 S3。
● 使用 KVS Consumer 侧提供的 GetImages API 按需从 KVS 视频流中抽取图片。
● 基于标签 KVS Producer 端的标签,自动触发 Amazon SNS 的通知。
借助上述功能,您可以构建视频流检测的通知,基于视频流中的抽取的图片构建智能视频检测应用。
▌Amazon Rekognition 提供预先训练和可定制的计算机视觉(CV)功能,可从您的图像和视频中提取信息和获得洞察力。提供高精度的人脸分析检测、人脸比较和人脸搜索、标签文本检测等功能。Amazon Rekognition 基于同样由 Amazon 计算机视觉科学家开发的成熟且高度可扩展的深度学习技术,每天能够分析数十亿图像和视频。它不需要机器学习专业知识即可使用。Amazon Rekognition 包含一个简单易用的 API,该 API 可快速分析存储在 Amazon S3 中的任何图像或视频文件。
02 Amazon Kinesis Video Stream
Images 方案分析
方案概述
Kinesis Video Stream Images 方案整体架构分为:设备端、Amazon 云端、用户应用端。
▌设备端
为带有一定视频检测能力的摄像头设备、通过集成 KVS SDK 作为 KVS 的 Producer 向云端 KVS Stream 推送视频流,并基于摄像头设备的检测能力给 KVS MKV 数据打 Tag,这些 Tag 的用途一是作为 KVS Image API 的触发标志,二是作为业务逻辑处理的依据。
▌Amazon 云端
● Amazon Kinesis Video Stream :提供设备视频持久化存储、视频检索、视频在线查看、视频下载等能力,并向Rekognition提供用于视频检测的数据。
● Amazon Rekognition:提供自动执行视频和图像分析的能力,包括基于视频或图像的内容审核、人脸检测、人脸比较、标签检测等完全托管的能力,并且可以方便的与 KVS、S3、SNS 等服务集成。
● Amazon S3:提供视频检测结果的存储。
● Amazon SNS:完全托管的发布/订阅消息收发、SMS、电子邮件和移动推送通知在本方案中提供通知发送的能力。
该方案的整体架构图如下:
方案说明
▌视频流 Producer(设备)
设备端通常是带有一定检测能力的摄像头设备,集成 KVS Prouder SDK。借助自身的视频检测能力给视频帧打标签,并使用 KVS prouder SDK 将视频流推送到云端。
▌视频流 Processor(云端)
云端视频流 Processor 通过 Amazon Service 提供如下处理能力:
● 视频云存:KVS Video Streams 是 Amazon 在云端的视频流存储资源,它可以提供视频数据的持久化存储,并提供视频检测和回放的API以实现复杂的需求场景。
● 抽图:通过 KVS 您可以使用 KVS GetMedia 或 GetImages API 从视频流中抽取图片、发送告警通知、智能视频检测处理。
● 通知告警:采用 SNS 与 KVS images 无缝集成的方式,您只需调用 API 进行一些简单的配置就可以构建视频通知告警的方案。
● 智能视频检测:云端的视频检测实现方式有三种:基于 Sagemaker、基于 Rekognition、基于 EC2 自建模型。
▌视频流 Consumer(应用端):
应用端通常是 APP,集成 KVS Consumer SDK 和消息推送服务,可以从 KVS 中按需回看视频或者查看存储在 S3 中的图片。
03 方案集成验证
实验准备工作
▌准备 Amazon 资源
● 准备 Amazon 账户并配置用户权限
1、本次实验需要用到的 Amazon 资源都在 Ireland Region 中创建,您需要提前准备好一个 Amazon account。
2、在 Amazon IAM 中创建一个 Admin User,赋予 arn:aws:iam::aws:policy/AdministratorAccess 策略,后续的资源创建都使用这个用户来操作。
3、在 Amazon IAM 的 Admin User 创建一个 AKSK,并记录下来,后面的实验环境需要用到。创建 IAM User AKSK 的方法请参考如下的文档:
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html
● 创建 Cloud9 用于模拟 KVS Producer 和 Consumer
创建 Amazon Cloud9 的方法请参考如下的文档:
https://catalog.us-east-1.prod.workshops.aws/workshops/b95b9381-baf0-4bef-ba31-63817d54c2a6/en-US/lab-1/cloud9
注意:由于默认创建的 Cloud9 的存储空间有限,建议在执行后面的操作之前先扩展 Cloud9 的空间,如何扩展 Cloud9 的存储空间请参照如下链接中的 Disk Space Expansion 章节。
https://catalog.us-east-1.prod.workshops.aws/workshops/b95b9381-baf0-4bef-ba31-63817d54c2a6/en-US/lab-1/cloud9
● 在 Cloud9 中配置 profile
在 Cloud9 的终端中执行如下命令配置 profile:
$ aws configure --profile your-profile-name
AWS Access Key ID [None]:your AWS Access Key ID
AWS Secret Access Key [None]:your AWS Secret Access Key
Default region name [None]: eu-west-1
Default output format [None]: json
● 创建 Amazon S3 Bucket 用于保存从 KVS 中抽取的图片
aws s3 mb s3://sample-bucket-name --region eu-west-1
● 创建 SNS 用于 KVS 将抽帧结果通知到相关服务
注意上面创建的 Cloud9、S3 Bucket 和 SNS 需要位于同一个 Amazon 的 Region。如下图所示:
● 创建云端的 Kinesis Video Stream
▌模拟 KVS Producer 设备端环境准备
● 安装工程依赖
sudo apt-get update
sudo apt-get install -y cmake git gcc g++ autoconf
sudo apt-get install -y libssl-dev libcurl4-openssl-dev liblog4cplus-dev pkg-config
● 样例工程编译
1、下载工程代码
git clone --recursive https://github.com/awslabs/amazon-kinesis-video-streams-producer-c.git
2、工程代码
mkdir -p amazon-kinesis-video-streams-producer-c/build
cd amazon-kinesis-video-streams-producer-c/build
cmake .. -DBUILD_TEST=TRUE
make
▌模拟 KVS Consumer 端环境准备
● 安装工程依赖
sudo apt update
sudo apt install software-properties-common
sudo add-apt-repository ppa:deadsnakes/ppa
● 将 Python 版本更新到3.7
Consumer 端的代码依赖于 Python3.7 您需要按如下操作将 Python 的版本升级到3.7。
执行如下命令查看Python的版本,如果版本是python3.6需要将Python版本更新到3.7
python3 —version
如果您的Python版本已经是python3.7可以跳过下面的步骤,如果是python3.6执行如下的操作
sudo apt install python3.7
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 1
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.7 2
sudo update-alternatives --config python3
Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/bin/python3.7 2 auto mode
1 /usr/bin/python3.6 1 manual mode
2 /usr/bin/python3.7 2 manual mode
Press <enter> to keep the current choice[*], or type selection number:0
选择0
再次执行python3 —version
Python 3.7.13
● 安装样例工程代码的依赖
1.下载工程代码
git clone https://github.com/arch-team/amazon-kinesis-video-streams-time-lapse-video-main.git
2.更新pip工具
sudo python3 -m pip install -U pip
sudo python3 -m pip install -U setuptools
sudo apt-get update
sudo apt-get install ffmpeg libsm6 libxext6 -y
● 在 Cloud9 中配置 profile
在 Cloud9 的终端中执行如下命令配置 profile:
export AWS_SESSION_TOKEN=your-SessionToken
export AWS_DEFAULT_REGION=eu-west-1
export AWS_ACCESS_KEY_ID=your AccessKeyId
export AWS_SECRET_ACCESS_KEY=your SecretAccessKey
● 执行 KVS Consumer 样例代码
python3 main.py —stream-name your-stream-name
—start-time 2022-05-31T09:40:33 # 开始时间
—end-time 2022-05-31T09:42:19 # 结束时间
—duration 3 # 采用周期
—width 1920 —height 1080 # 图片分辨率
—output-path result1.mp4
自动从 KVS 中抽图流程说明
基于 KVS Image 功能之 Auto Image Generation 的处理流程如下图所示:
▌执行 UpdateImageGenerationConfiguration 配置 KVS 自动抽图
UpdateImageGenerationConfiguration 是配置 KVS 图片抽取参数的 API,通过该 API 您可以配置 KVS 自动抽图的采样周期、图片保存的 S3 存储桶、图片格式、图片像素等信息。
● 准备 update-image-generation-input.json 文件
{
"StreamName": "TestStream", # 为您在3.1.1中创建的KVS Stream的名称
"ImageGenerationConfiguration": {
"Status": "ENABLED", # ENABLED或DISABLE 控制该项功能的启用或禁止
"DestinationConfig": {
"DestinationRegion": "us-east-1", # 为您在3.1.1中创建的S3所在的Region,本实验使用eu-west-1
"Uri": "s3://bucket-name" # bucket-name为您在3.1.1中创建的S3的Bucket名称
},
"SamplingInterval": 3000, # 抽取图片的间隔时间
"ImageSelectorType": "PRODUCER_TIMESTAMP", # 时间类型
"Format": "JPEG", # 图片格式
"FormatConfig": {
"JPEGQuality": "80"
},
"WidthPixels": 320, # 图片像素
"HeightPixels": 240 # 图片像素
}
}
● 执行 UpdateImageGenerationConfiguration API
aws kinesisvideo update-image-generation-configuration
--cli-input-json file://./update-image-generation-input.json
▌执行 UpdateNotificationConfiguration 配置 KVS 基于 SNS 通知下发
UpdateNotificationConfiguration 是配置基于 SNS 自动化通知下发的 API,通过该 API 配置 KVS Stream 之后,当 KVS 接受到 producer 发送到带有 AWS_KINESISVIDEO_NOTIFICATION 标签的帧后,会触发 SNS 通知。
● 准备 update-notification-configuration.json 文件
{
"NotificationConfiguration": {
"DestinationConfig": {
"Uri": "string" # SNS ARN
},
"Status": "string" # ENABLED或DISABLE 控制该项功能的启用或禁止
},
"StreamARN": "string", # StreamARN 与 StreamName二者选填一个,用于标识KVS
"StreamName": "string"
}
该命令执行如果报权限错误,您需要在该命令中指定 profile, 在上面的命令后加上 –profile your profile name
● 执行 UpdateNotificationConfiguration API
aws kinesisvideo update-notification-configuration —cli-input-json file://./updateNotificationConfiguration.json
注意:
1、执行 UpdateImageGenerationConfiguration 或 UpdateNotificationConfiguration 后,KVS Stream 的自动图片抽取和基于 SNS 需要1分钟之后才能生效。
2、UpdateImageGenerationConfiguration 采样的时间间隔最小是3秒钟,如果您想要提高采样频率可以联系 Amazon support 来提升。
▌Cloud9 模拟 KVS Producer 推送视频流
● 获取临时 token
执行如下命令:aws sts get-session-token —profile your profile name 获取临时 token。
"Credentials": {
"AccessKeyId": "your AccessKeyId",
"SecretAccessKey": "your SecretAccessKey",
"SessionToken": "your SessionToken",
"Expiration": "2022-05-30T21:03:10Z"
}
● 配置环境变量
export AWS_SESSION_TOKEN=your SessionToken
export AWS_DEFAULT_REGION=eu-west-1
export AWS_ACCESS_KEY_ID=your AccessKeyId
export AWS_SECRET_ACCESS_KEY=your SecretAccessKey
● 执行 Producer Sample 推送视频流
status = putKinesisVideoFrame(data->streamHandle, &frame);
if (data->firstFrame) {
startUpLatency = (DOUBLE)(GETTIME() - data->startTime) / (DOUBLE) HUNDREDS_OF_NANOS_IN_A_MILLISECOND;
DLOGD("Start up latency: %lf ms", startUpLatency);
data->firstFrame = FALSE;
}
else if (frame.flags == FRAME_FLAG_KEY_FRAME) {
if(gKeyFrameCount%KEYFRAME_EVENT_INTERVAL == 0)
{
//reset to 0 to avoid overflow in long running applications
gKeyFrameCount = 0;
switch (gEventsEnabled) {
// NOTIFICATION标签
case 1:
putKinesisVideoEventMetadata(data->streamHandle, STREAM_EVENT_TYPE_NOTIFICATION, NULL);
break;
// IMAGE_GENERATION标签
case 2:
putKinesisVideoEventMetadata(data->streamHandle, STREAM_EVENT_TYPE_IMAGE_GENERATION, NULL);
break;
// NOTIFICATION和IMAGE_GENERATION标签
case 3:
putKinesisVideoEventMetadata(data->streamHandle, STREAM_EVENT_TYPE_NOTIFICATION | STREAM_EVENT_TYPE_IMAGE_GENERATION, NULL);
break;
default:
break;
}
}
gKeyFrameCount++;
}
Producer 端视频帧无标签,这时不会触发自动抽图和 Notification。
./kvsAudioVideoStreamingSample kvs-images-lab 600 ../samples aac
Producer 端给视频帧打上 STREAM_EVENT_TYPE_IMAGE_GENERATION,仅自动抽图。
./kvsAudioVideoStreamingSample kvs-images-lab 600 ../samples aac image
Producer 端给视频帧打上 STREAM_EVENT_TYPE_NOTIFICATION,仅 notification。
./kvsAudioVideoStreamingSample kvs-images-lab 600 ../samples aac notification
Producer 端给视频帧打上 STREAM_EVENT_TYPE_IMAGE_GENERATION 和 STREAM_EVENT_TYPE_IMAGE_GENERATION 两种标签,自动抽图并发送 notification。
./kvsAudioVideoStreamingSample kvs-images-lab 600 ../samples aac both
▌KVS Stream 自动抽图结果
● S3 object key 说明如下图所示:由如下字段组成:file-extension
1.ImagePrefix - Value of AWS_KINESISVIDEO_IMAGE_PREFIX.
2.AccountID - Account ID under which the stream is created.
3.StreamName - Name of the stream for which the image is generated.
4.ImageTimecode - Epoch timecode in the fragment at which the image is generated.
5.RandomID - Random GUID.
6.file-extension - JPG or PNG based on the Image format requested.
● S3 object Metadata
{
// KVS S3 object metadata
x-amz-meta-aws_kinesisvideo_fragment_number : 'string',
x-amz-meta-aws_kinesisvideo_producer_timestamp: 'number',
x-amz-meta-aws_kinesisvideo_server_timestamp: 'number',
// Optional key value pair sent as part of the MKV tags
custom_key_1: custom_value_1,
custom_key_2: custom_value_2,
}
您可以基于其中的 aws_kinesisvideo_fragment_number、timestamp 和 Producer 自定义 tag 来满足具体的业务场景,比如使用 aws_kinesisvideo_fragment_number 对 kvs 视频流进行定位回放等。
▌KVS Stream 基于 SNS 的通知结果
{
"StreamArn": "your kvs stream arn",
"FragmentNumber": "91343852333182293998949405270547347888495435985",
"FragmentStartProducerTimestamp": 1653905243571,
"FragmentStartServerTimestamp": 1653905243687,
"NotificationType": "PERSISTED"
}
基于 KVS GetImage 抽图流程
GetImages 是 KVS 最新推出的一个 API,使用该 API 您可以采用完成托管的方式从存储在 KVS Stream 视频流中按照您期望的方式抽取图片。您可以将该图片用于机器学习推理,如对视频流进行人形、宠物、车辆等物体检测或者推送给最终用户进行预览。
▌KVS GetImages API 说明
● KVS GetImages Request 参数
{
"StreamARN": "string", # KVS stream标识
"StreamName": "string",
"Format": "string", # 返回图片的格式 JPEG|PNG
"FormatConfig": {
"string": "string"
},
"HeightPixels": number, # 图片像素
"WidthPixels": number # 图片像素
"ImageSelectorType": "string", # PRODUCER_TIMESTAMP | SERVER_TIMESTAMP
"MaxResults": number, # 返回图片最大数量
"NextToken": "string",
"SamplingInterval": number, # 采样的时间间隔
"StartTimestamp": number, # 抽图的开始时间
"EndTimestamp": number, # 抽图的结束时间
}
● KVS GetImages Response 参数
{
"Images": [ # GetImages API 返回的图片集合
{
"Error": "string",
"ImageContent": "string", # 图片数据采用BASE64编码后的内容
"TimeStamp": number
}
],
"NextToken": "string"
}
▌KVS GetImages 实验步骤
● 按照2.3 Cloud9 模拟 KVS Producer 推送视频流到对应的 KVS Stream
● 记录下上一步骤中 KVS Producer 推流中 terminal 中打印的时间
2022-05-31 14:00:33 DEBUG logStreamMetric(): Total elementary frame rate (fps): 25.000000
2022-05-31 14:00:33 DEBUG logStreamMetric(): Average API call retry count for client: 0.000000
2022-05-31 14:00:33 DEBUG postReadCallback(): Wrote 65524 bytes to Kinesis Video. Upload stream handle: 0
2022-05-31 14:00:33 DEBUG postReadCallback(): Wrote 39363 bytes to Kinesis Video. Upload stream handle: 0
2022-05-31 14:00:33 DEBUG postReadCallback(): Wrote 25886 bytes to Kinesis Video. Upload stream handle: 0
2022-05-31 14:00:33 DEBUG postWriteCallback(): Curl post body write function for stream with handle: kvs-images-lab and upload handle: 0 returned: {"EventType":"RECEIVED","FragmentTimecode":0,"FragmentNumber":"91343852333182358371831448110348590349566628324"}
2022-05-31 14:00:33 DEBUG postReadCallback(): Wrote 20922 bytes to Kinesis Video. Upload stream handle: 0
2022-05-31 14:00:33 DEBUG postWriteCallback(): Curl post body write function for stream with handle: kvs-images-lab and upload handle: 0 returned: {"EventType":"BUFFERING","FragmentTimecode":1800,"FragmentNumber":"91343852333182358376783208267490111901301663845"}
2022-05-31 14:00:33 DEBUG postReadCallback(): Wrote 17251 bytes to Kinesis Video. Upload stream handle: 0
2022-05-31 14:00:33 DEBUG postReadCallback(): Wrote 20494 bytes to Kinesis Video. Upload stream handle: 0
2022-05-31 14:00:33 DEBUG postReadCallback(): Wrote 709 bytes to Kinesis Video. Upload stream handle: 0
2022-05-31 14:00:33 DEBUG postWriteCallback(): Curl post body write function for stream with handle: kvs-images-lab and upload handle: 0 returned: {"EventType":"PERSISTED","FragmentTimecode":0,"FragmentNumber":"91343852333182358371831448110348590349566628324"}
● 如下图所示执行1.2 模拟 KVS Consumer 端环境准备的样例代码
核心代码说明:如下图是基于 Python 代码
""" Fetch a frame at the timestamp and write it to the video writer """
try:
res = kvs_am_client.get_images(
StreamName=args.stream_name,
ImageSelectorType='SERVER_TIMESTAMP',
StartTimestamp=timestamp,
EndTimestamp=timestamp + datetime.timedelta(seconds=3),
SamplingInterval=3000,
Format='JPEG',
WidthPixels=args.width,
HeightPixels=args.height,
MaxResults=3,
)
except kvs_am_client.exceptions.ResourceNotFoundException as e:
print(f"{e} at {timestamp}")
return
for image in res["Images"]:
if "Error" not in image:
content = image["ImageContent"]
path = "/tmp/image.jpg"
print(f"Write a frame at {timestamp}")
with open(path, "wb") as fw:
fw.write(base64.b64decode(content))
cv2_image = cv2.imread(path)
writer.write(cv2_image)
return
print(f"Couldn't find a valid image frame at {timestamp}")
运行 main.py,并传入封装好的参数
python3 main.py —stream-name your stream name
—start-time 2022-05-31T09:40:33 # 开始时间
—end-time 2022-05-31T09:42:19 # 结束时间
—duration 3 # 采用周期
—width 1920 —height 1080 # 图片分辨率
—output-path result1.mp4
● 观测 KVS Images GetImages 抽取图片,如下图所示 Consumer 端抽取图片成功
Couldn't find a valid image frame at 2022-05-31 09:40:33
Write a frame at 2022-05-31 09:40:35
Write a frame at 2022-05-31 09:40:37
Write a frame at 2022-05-31 09:40:39
Write a frame at 2022-05-31 09:40:41
Write a frame at 2022-05-31 09:40:43
Write a frame at 2022-05-31 09:40:45
Write a frame at 2022-05-31 09:40:47
Write a frame at 2022-05-31 09:40:49
04 结束语
在端到端的处理流程中,按照检测数据输入来源、输入数据格式、数据处理方案、智能检测方式这几个维度的可选的组合有如下几种技术方案可供选择。Amazon 提供的云服务能力可以很好的支持这些方案的实现。
● 智能检测部署位置对比分析
● 智能检测输入数据格式对比分析
● 智能检测输入数据处理对比分析
● 智能检测方案对比分析
实际应用中您可以根据 AI 场景的复杂度、团队的技术储备、成本、项目交付周期这几个维度选择适合当前状况的方案。
05 参考资料
Kinesis Video Streams Images 官方文档:
https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/images.html
C 语言版本的 KVS Producer 包含了 KVS Images 功能的样例代码:
https://github.com/awslabs/amazon-kinesis-video-streams-producer-c
CPP 语言版本的 KVS Producer 包含了 KVS Images 功能的样例代码:
https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp
Python 语言版本的 KVS 包含了 KVS Images 功能的样例代码:
https://github.com/arch-team/amazon-kinesis-video-streams-time-lapse-video-main
本篇作者
孙进华
亚马逊云科技资深解决方案架构师,负责帮助客户进行上云架构的设计和咨询。加入亚马逊云科技前自主创业负责电商平台搭建和车企电商平台整体架构设计。曾就职于全球领先的通讯设备公司,担任高级工程师,负责 LTE 设备系统的多个子系统的开发与架构设计。在高并发、高可用系统架构设计、微服务架构设计、数据库、中间件、IoT 等方面有着丰富的经验。
徐开
亚马逊云科技物联网实验室 解决方案架构师,主要负责物联网解决方案,致力于 Amazon IoT 相关技术的推广与应用
版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。