简体   繁体   English

使用 Python 解析和渲染 Kinesis Video Streams 并获取输入帧的图像表示

[英]Using Python to parse and render Kinesis Video Streams and get an image representation of the input frame

I have set up a pipeline in which, I live stream the video to Kinesis Video Stream (KVS), which sends the frames to Amazon Rekognition for face recognition, which further sends them to Kinesis Data Stream (KDS).我已经设置了一个管道,我将视频 stream 直播到 Kinesis Video Stream (KVS),后者将帧发送到 Amazon Rekognition 进行人脸识别,后者进一步将它们发送到 Kinesis Data Stream (KDS)。 Finally, KDS sends the results to a lambda.最后,KDS 将结果发送到 lambda。

For a frame on which face recognition has been conducted, I get the JSON of the following format: https://docs.aws.amazon.com/rekognition/latest/dg/streaming-video-kinesis-output-reference.html对于已进行人脸识别的帧,我得到以下格式的JSON:https://docs.aws.amazon.com/rekognition/latest/dg/streaming-video-kinesis-output-reference.html

My AIM is: Using this JSON, I somehow want to get an image representation of the frame which was recorded by the KVS.我的目标是:使用这个 JSON,我想以某种方式获得 KVS 记录的帧的图像表示。

What have I tried:我试过什么:

This JSON provides me with the Fragment Number.这个 JSON 为我提供了片段编号。

I use this fragment number and make a call to the get_media_for_fragment_list我使用这个片段编号并调用get_media_for_fragment_list

The above call returns a key called Payload in response.上面的调用返回一个名为Payload的键作为响应。

I have been trying to somehow render this payload into an image.我一直在尝试以某种方式将此有效载荷渲染成图像。

However, I fail to do this every time as I do not know how to make sense out of this payload and decode it.然而,我每次都没有这样做,因为我不知道如何理解这个有效载荷并对其进行解码。

Following is the code snippet.以下是代码片段。

    def getFrameFromFragment(fragment):
         client = boto3.client('kinesis-video-archived-media',endpoint_url=data_endpoint_for_kvs)
         response = client.get_media_for_fragment_list(
             StreamName='kvs1',
             Fragments=[
                fragment,
             ]
         )
         payload = response['Payload']
         print(payload.read())

How do I use this payload to get an image?如何使用此有效负载获取图像?

I know of parsers that exist in Java: https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/examples-renderer.html我知道 Java 中存在的解析器: https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/examples-renderer.html

However, I wanted to know of a solution in Python.但是,我想知道 Python 中的解决方案。

In case my question statement is wrong or doesn't make sense, feel free to ask me more about this issue.如果我的问题陈述有误或没有意义,请随时向我询问有关此问题的更多信息。

Thanks for the help.谢谢您的帮助。 :) :)

The response from GetMedia is the stream which is in MKV packaging format. GetMedia 的响应是 MKV 打包格式的流。 First, you would need to use some Python library that extracts the frames from the MKV format ( https://github.com/vi/mkvparse or alike).首先,您需要使用一些从 MKV 格式( https://github.com/vi/mkvparse或类似格式)中提取帧的 Python 库。 Next, your stream is likely to be encoded.接下来,您的流很可能会被编码。 For example H264.例如 H264。 You will also need to decode the frame in order to get the actual bitmap of the image if that's what you need.如果您需要,您还需要解码帧以获得图像的实际位图。 There are few software based decoders seem to be available for Python: https://github.com/DaWelter/h264decoder似乎很少有基于软件的解码器可用于 Python: https : //github.com/DaWelter/h264decoder

I am not familiar with these projects though.虽然我不熟悉这些项目。

After receiving the payload using the following code,使用以下代码接收有效负载后,

kvs_stream = kvs_video_client.get_media(
                 StreamARN="ARN", 
                 StartSelector= 
                              {'StartSelectorType':'FRAGMENT_NUMBER',
                               'AfterFragmentNumber': decoded_json_from_stream['InputInformation']['KinesisVideo']['FragmentNumber']
                              }
                                       )

you can use,您可以使用,

 frame = kvs_stream['Payload'].read()

to receive to get the frame from the payload.接收以从有效载荷中获取帧。 Now you can open an mvi file and write this frame to it and then extract a particular frame using openCV from this mvi file.现在您可以打开一个 mvi 文件并将这个帧写入其中,然后使用 openCV 从这个 mvi 文件中提取一个特定的帧。

with open('/tmp/stream.avi', 'wb') as f:
                f.write(frame)
                cap = cv2.VideoCapture(file.mvi)
                #use frame for further processing

The payload that you are getting is in MKV format : https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_reader_GetMediaForFragmentList.html#API_reader_GetMediaForFragmentList_ResponseSyntax .您获得的有效负载采用 MKV 格式: https : //docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_reader_GetMediaForFragmentList.html#API_reader_GetMediaForFragmentList_ResponseSyntax To get an image, you just need to get a key frame in that fragment and convert it to an image.要获取图像,您只需要获取该片段中的关键帧并将其转换为图像。

Following code snippet can be used.可以使用以下代码片段。 Further you can modify the data that you fetch in one round for further optimization using the .read() method.此外,您可以使用.read()方法修改您在一轮中获取的数据以进行进一步优化。 You can then you the video fname as per your requirement.然后您可以根据您的要求获得视频fname

client = boto3.client('kinesis-video-media', endpoint_url=dataEndPoint)
response = client.get_media(
                    StreamARN=streamARN,
                    StartSelector={
                            'StartSelectorType': 'FRAGMENT_NUMBER',
                            'AfterFragmentNumber': fragmentID}
                    )
fname = '/tmp/'+fragmentID+'-'+serverTimestamp+'.webm'
with open(fname, 'wb+') as f:
    chunk = response['Payload'].read(1024*8)
    while chunk:
        f.write(chunk)
        chunk = response['Payload'].read(1024*8)
return fname

See this AWS code sample repo:请参阅此 AWS 代码示例存储库:

https://github.com/aws-samples/amazon-kinesis-video-streams-consumer-library-for-python https://github.com/aws-samples/amazon-kinesis-video-streams-consumer-library-for-python

This parses Kinesis Video GetMedia chunks to MKV fragments and individual frames as JPEG/PNG or NDArray's in pure python.这会将 Kinesis Video GetMedia 块解析为 MKV 片段和单个帧,如 JPEG/PNG 或 NDArray 的纯 python。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM