全景应用程序监控

c8be34b29ab6b56a52374f2f2632ec59.jpeg

实时智能视频分析应用程序开发和边缘设备部署是一项技巧任务。在过去几年中,行业参与者建立了支持这一活动的平台。著名的例子包括NVIDIA Metropolis、英特尔的OpenVINO和AWS Panorama。

这些解决方案使视频分析应用程序开发的某些方面更加简单,但在生产中部署视频分析应用之前仍有许多问题需要处理。这篇文章介绍了SkyLine,它是一系列开源工具中的第一个,使开发AWS全景应用程序更简单。

AWS Panorama是一个机器学习设备和软件框架,允许你在边缘部署视频分析应用程序。有关部署全景应用程序的详细介绍和分步教程,请参阅在AWS Panorama的边缘部署对象检测器模型。

https://towardsdatascience.com/deploy-an-object-detector-model-at-the-edge-on-aws-panorama-9b80ea1dd03a

AWS Panorama框架简化了视频分析应用程序开发的许多方面,包括摄像机连接管理、视频解码、帧提取、模型优化和加载、显示输出管理、应用程序的空中部署以及其他功能。然而,一些任务仍然具有挑战性,包括当模型不能按预期工作时的诊断任务。

介绍SkyLine

获得全景应用程序正确功能的视觉反馈的唯一可用方法是将显示器物理连接到设备的HDMI端口。显示器将显示设备上部署的单个应用程序的输出视频流。

然而,物理访问设备并不总是可行的。SkyLine允许将任何全景应用程序的输出视频重新流到外部服务,例如AWS Kinesis视频流。此功能可以非常方便地远程监控应用程序。

SkyLine是如何工作的?

SkyLine实例化了一个GStreamer管道,其头部有一个appsrc元素。OpenCV VideoWriter不是将连续帧保存到视频文件,而是流式传输到输出接收器。

打开VideoWriter实例时,用户应指定输出流的帧宽度和高度以及帧速率。你可以手动设置这些参数,或者让SkyLine根据输入维度和向其输入新帧的频率推断这些参数。如果使用此自动配置功能,某些帧(默认为100)将在流传输开始时被丢弃,因为SkyLine将使用它们来计算帧速率的统计数据并测量帧尺寸。

如果发送不同大小的帧,SkyLine将调整输入大小,但这会带来性能损失。你还需要以每秒帧参数中指定的频率向SkyLine发送新帧。如果帧以不同的频率发送,视频片段将在Kinesis视频流中失去同步,你将无法顺利播放视频。

SkyLine是一个抽象基类,用于处理GStreamer管道的状态机。具体的实现Kvskyline将帧发送到Amazon Kinesis视频流服务。扩展SkyLine以支持其他服务很容易,特别是如果已经有了GStreamer插件。

将SkyLine集成到全景应用程序中

配置Docker容器

SkyLine依赖于自定义编译的外部库。所有这些库必须在应用程序的docker容器中正确编译和配置,才能使SkyLine正常工作。这些库包括:

  • GStreamer 1.0安装了标准插件包、libav、工具和开发库;

  • OpenCV 4.2.0,使用GStreamer支持和Python绑定编译;

  • numpy(通常由全景应用程序的基本docker镜像安装)。

如果你想使用Kvskyline,将视频流传输到Amazon Kinesis视频流的SkyLine实现,它还需要以下库:

  • 亚马逊Kinesis视频流(KVS)SDK,使用GStreamer插件支持编译;

  • 环境变量GST_PLUGIN_PATH,配置为指向KVS Producer SDK GStreamer插件的编译二进制文件所在的目录;

  • 环境变量LD_LIBRARY_PATH,包括由KVS Producer SDK编译的第三方开源依赖项;

  • boto3(通常由全景应用程序的基本docker镜像安装)。

在SkyLine的源代码存储库中,示例文件夹中提供了一个示例Dockerfile,它显示了如何在任何容器中正确安装这些库和SkyLine。

在大多数情况下,只需将示例中的相关部分复制到应用程序的Dockerfile即可。请注意,第一次编译docker容器时,可能需要一个小时才能正确编译所有库。

为KVSSkyLine设置AWS IAM权限

KVSSkyLine使用Amazon Kinesis Video Streams(KVS)Producer库将处理过的帧发送到KVS服务。

KVS Producer需要AWS证书。它可以使用与全景应用程序角色关联的凭据,但你必须明确配置它。

KVSSkyLine需要权限才能执行以下操作:

kinesisvideo:DescribeStream
kinesisvideo:GetStreamingEndpoint
kinesisvideo:PutMedia

如果KVSSkyLine需要在首次使用时自动创建Kinesis视频流,则还应包括kinesisvideo:CreateStream操作。

允许KVSSkyLine将数据写入Kinesis视频流的示例策略如下:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "kinesisvideo:DescribeStream",
                "kinesisvideo:CreateStream",
                "kinesisvideo:GetDataEndpoint",
                "kinesisvideo:PutMedia"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
设置凭据

AWS安全凭证有两种类型:静态和临时。

前者永远不会过期,如果发生泄漏,你应该手动使其无效并重新配置应用程序。因此,强烈建议不要在生产环境中使用它们。

静态AWS凭据的示例包括IAM用户的Access Key Id 和Secret Access Key。

169c3f04e94a8c17b8a5aac015b27f52.jpeg

临时凭据在预定义期限后过期。如果发生泄漏,它们只能在有效期内使用,通常为几个小时左右。

临时凭证可以在到期前续订,以便延长其寿命,也可以在到期后更换新凭证。此过程需要使用此类型凭据的应用程序进行额外协调。临时凭据包括AWS Access Key Id, Secret Access Key, 和Session Token。

如果要使用静态凭据进行测试,请在AWS帐户中创建一个IAM用户,并向该用户附加类似于上面的策略。你应该将此用户配置为具有对AWS资源的编程访问权限,并获取用户的AWS密钥:在应用程序的代码中创建KVSInlineCredentialsHandler或KVSEnvironmentCredentials Handler实例,以将这些凭据直接传递给GStreamer管道定义中的KVS Producer插件或作为环境变量。

由于这些凭据不会过期,因此不建议在生产环境中使用此配置。即使在开发和测试环境中,你也应该采取适当的安全措施来保护这些凭证:永远不要在源代码中硬编码它们。相反,请使用AWS Secret Manager或类似服务为你的应用程序提供这些参数。

KVSSkyLine还可以使用Panorama Application Role将应用程序的凭据传递给KVS Producer。这些凭据是临时的,意味着它们将在几个小时内到期,用户应在到期前续订。

Producer库需要文本文件中的临时凭据。KVSFileCredentialsHandler管理凭据的续订,并定期使用新凭据更新文本文件。如果要使用此方法,请将类似于上面示例的策略附加到应用程序角色。

请记住,如果在KVSFileCredentialsHandler刷新凭据后,Panorama应用程序-KVS集成仍然有效,请始终测试它。让你的应用程序运行几个小时,并定期检查它是否继续将视频流传输到KVS。

续订凭据时,你还可以在应用程序的CloudWatch日志中找到诊断信息。

环境变量

KVSSkyLine需要两个环境变量才能让GStreamer找到KVS Producer插件。这些变量的名称是GST_PLUGIN_PATH和LD_LIBRARY_PATH。他们指向KVS Producer GStreamer插件的文件夹及其第三方依赖项。

在提供的示例Dockerfile中,这些变量的正确值被写入名为/panorama/.env的配置文件。你应该将此文件的路径传递给KVSSkyLine,或者确保这些环境变量包含正确的值。

用法示例

初始化KVSSkyLine实例时,应传递创建流的AWS区域名称、流名称和凭据处理程序实例。如果要手动配置帧速率和帧的尺寸,还应在此处设置它们。

当指定了这两个参数时,SkyLine将跳过预热期,并将第一帧直接发送到KVS。当你准备好发送帧时,调用start_streaming方法以打开GStreamer管道。

调用此方法后,你需要定期向调用put方法的流发送新帧,频率在帧速率中指定或由KVSSkyLine推断。你可以停止并重新启动同一KVSSkyLine实例上的流。

以下示例使用临时凭据:

import panoramasdk
from backpack.kvs import KVSSkyLine, KVSFileCredentialsHandler

# You might want to read these values from Panorama application parameters
stream_region = 'us-east-1'
stream_name = 'panorama-video'

# The example Dockerfile writes static configuration variables to this file
# If you change the .env file path in the Dockerfile, you should change it also here
DOTENV_PATH = '/panorama/.env'

class Application(panoramasdk.node):

    def __init__(self):
        super().__init__()
        # ...
        credentials_handler = KVSFileCredentialsHandler()
        self.skyline = KVSSkyLine(
            stream_region=stream_region,
            stream_name=stream_name,
            credentials_handler=credentials_handler,
            dotenv_path=DOTENV_PATH
        )
        # This call opens the streaming pipeline:
        self.skyline.start_streaming()

    # called from video processing loop:
    def process_streams(self):
        streams = self.inputs.video_in.get()

        for idx, stream in enumerate(streams):
            
            # Process the stream, for example with:
            # self.process_media(stream)

            # TODO: eventually multiplex streams to a single frame
            if idx == 0:
                self.skyline.put(stream.image)

如果一切正常,你可以在AWS控制台的Kinesis视频流页面上观看重播视频。当然,你可以在将图像发送到SkyLine之前对其进行修改:根据深度学习模型的推断结果在其上绘制注释。

注释

注释和注释驱动程序提供了在不同渲染后端上绘制注释的统一方法。目前,实现了两个注释驱动程序:

  • PanoramaMediaAnnotationDriver允许你在panoramasdk.media上绘图

  • OpenCVImageAnnotationDriver允许你在OpenCV图像(numpy数组)对象上绘图。

5083d6e3f51bc564665338e78c632fd0.jpeg

该库可以绘制两种类型的注释:标签和框。

使用注释

根据可用的后端,你可以在视频帧处理循环的开始处创建一个或多个注释驱动程序实例。

你需要在python集合(例如,在列表中)中收集要绘制在帧上的所有注释。处理完成后,可以对任意数量的驱动程序调用rendermethod,并传递相同的注释集合。

注释中使用的所有坐标均标准化为[0;1)范围。

示例用法:

import panoramasdk
from backpack.annotation import (
    Point, LabelAnnotation, RectAnnotation, TimestampAnnotation,
    OpenCVImageAnnotationDriver, 
    PanoramaMediaAnnotationDriver
)

class Application(panoramasdk.node):

    def __init__(self):
        super().__init__()
        # self.skyline = ... 
        self.panorama_driver = PanoramaMediaAnnotationDriver()
        self.cv2_driver = OpenCVImageAnnotationDriver()

    # called from video processing loop:
    def process_streams(self):
        streams = self.inputs.video_in.get()
        for idx, stream in enumerate(streams):
            annotations = [
                TimestampAnnotation(),
                RectAnnotation(point1=Point(0.1, 0.1), point2=Point(0.9, 0.9)),
                LabelAnnotation(point=Point(0.5, 0.5), text='Hello World!')
            ]
            self.panorama_driver.render(annotations, stream)

            # TODO: eventually multiplex streams to a single frame
            if idx == 0:
                rendered = self.cv2_driver.render(annotations, stream.image.copy())
                # self.skyline.put(rendered)

Postface

即使SkyLine是一个有用的工具,它的使用可能会引起两个问题,你应该仔细考虑。我们不鼓励在生产环境中使用SkyLine:它是一种开发辅助工具或调试工具。

第一个问题是技术性的。目前,Panorama应用程序中的应用程序代码无法直接访问机载GPU;因此,SkyLine完成的所有视频编码都在设备的CPU上运行。这种行为可能会降低设备的速度:使用SkyLine传输单个输出流可能需要设备CPU容量的10-30%。

第二个问题与数据保护有关。Panorama设备旨在保护正在处理的视频流。它有两个以太网接口,用于将摄像机网络(通常为闭路局域网)与设备的互联网接入分开。使用SkyLine,你可以将视频流从受保护的闭路摄像机网络中继到公共互联网。在使用SkyLine之前,你应该仔细检查应用程序和摄像头网络的数据保护要求。此外,你还负责按照AWS共享责任模型的要求,对SkyLine使用的所有AWS凭证进行保密。

Backpack

SkyLine是Backpack的一部分,Backpack是一组更广泛的工具,旨在帮助在AWS Panorama上进行软件开发。其他组件将在未来的帖子中介绍,请继续关注并关注我们以获得更新。

Backpack是开源的,可在GitHub上使用。你可以在基于ARM64的系统上构建和运行示例docker容器。

例如,假设你已经在一个t4g类型的EC2实例上设置了Panorama Test Utility。在这种情况下,你可以使用EC2实例上的以下命令在此容器中构建和启动shell:

$ git clone https://github.com/Neosperience/backpack.git
$ cd backpack/examples
$ docker build . -t my_backpack_example:1.0
$ docker run -it my_backpack_example:1.0 bash

该容器也可以用基于M1 ARM的新芯片在MacBook Pro上构建和执行。

Backpack库中有大量文档。你可以在线阅读详细的API文档:

https://s3.eu-west-1.amazonaws.com/github-ci.experiments.neosperience.com/Neosperience/backpack/docs/index.html

或使用shell中的解释器:

root@my_backpack_example:/# python3

>>> import backpack.skyline, backpack.kvs, backpack.annotation
>>> help(backpack.skyline)
>>> help(backpack.kvs)
>>> help(backpack.annotation)

你还可以尝试Backpack中的其他SkyLine实现。例如,RTSPSkyLine允许你在应用程序容器中托管RTSP服务器,并使用RTSP客户端直接连接到全景设备,以监控应用程序。

☆ END ☆

如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 woshicver」,每日朋友圈更新一篇高质量博文。

扫描二维码添加小编↓

1e9fa052a32720381565010f3c343cb4.jpeg

☆ END ☆

如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 woshicver」,每日朋友圈更新一篇高质量博文。

扫描二维码添加小编↓

d44243d561ae65500cab7a27eccc55ab.jpeg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值