Amazon Kinesis Video Streamsの映像をAmazon Rekognition Videoで解析する #reinvent

はじめに

先日AWS re:Invent 2017で発表されたAmazon Rekognition VideoAmazon Kinesis Video Streams。今回はRekognitionのドキュメントにあるWorking with Streaming Videosに則って、Amazon Kinesis Video Streamsの映像をAmazon Rekognition Videoで解析してみたいと思います。

構成は以下の通り。

やってみた

IAM Roleの作成

IAM管理画面で[ロール]-[ロールの作成]ボタンをクリックします。

[ロールの作成]画面で[AWSサービス]-[Rekognition]を選択し、[アクセス権限]ボタンをクリックします。

[アタッチされたアクセス権限ポリシー]画面で[AmazonRekognitionServiceRole]が表示されていることを確認し、[確認]ボタンをクリックします。

[確認]画面で[ロール名]を適当につけて、[ロールの作成]ボタンをクリックします。

以下のようにIAMロールが出来上がります。ARNをメモっときます。

コレクションの作成

IndexFacesによって検出した顔を蓄積するコレクションを作成します。

$ aws rekognition create-collection \
>     --collection-id "MyCollection" \
>     --region us-west-2

{
    "CollectionArn": "aws:rekognition:us-west-2:XXXXXXXXXX:collection/MyCollection",
    "FaceModelVersion": "2.0",
    "StatusCode": 200
}

対象の顔を保存する

検出させたい顔を決めます。まず、Rekognitionと同じリージョンのS3バケットに顔画像ファイルをアップロードします。

次に、index-facesで顔画像ファイルから顔を検出し、コレクションに蓄積します。

$ aws rekognition index-faces \
>       --image '{"S3Object":{"Bucket":"MyBucket","Name":"smokeymonkey.jpg"}}' \
>       --collection-id "MyCollection" \
>       --detection-attributes "ALL" \
>       --region us-west-2
{
    "FaceRecords": [
        {
            "FaceDetail": {
                "Confidence": 99.99945068359375,
                "Eyeglasses": {
                    "Confidence": 100.0,
                    "Value": true
                },
(---snip---)

Kinesis Video Streamを作成する

次に映像を流し込むためのKinesis Video Streamを作成します。

Kinesis Video Stream管理画面で[Kinesisビデオストリームを作成する]ボタンをクリックします。

[ストリーム設定]画面で[ストリーム名]を設定し、[ストリームの作成]ボタンをクリックします。

Kinesis Video Streamが作成されました。

Kinesis Streamを作成する

今回の仕組みでは、Kinesis Video StreamのデータをRekognition Videoが解析します。その解析結果を受け取るKinesisのData Streamを作成します。

Kinesis Data Stream管理画面で[Create Kinesis steam]ボタンをクリックします。

[Create Kinesis stream]画面で[Kinesis stream name]を設定します。[Number of shards]は1とします。[Create Kinesis stream]ボタンをクリックします。

Kinesis streamが作成されます。

StreamProcessorを作成する

Rekognition Videoによる解析を管理するStreamProcessorを作成します。

$ aws rekognition create-stream-processor \
>   --name "MyStreamProcessorForCam" \
>   --input '{"KinesisVideoStream": {"Arn": "arn:aws:kinesisvideo:us-west-2:XXXXXXXXXX:stream/AmazonRekognition-VideoStream/XXXXXXX"}}' \
>   --stream-processor-output '{"KinesisDataStream": {"Arn": "arn:aws:kinesis:us-west-2:XXXXXXXXXX:stream/AmazonRekognitionAnalysisStream"}}' \
>   --role-arn "arn:aws:iam::XXXXXXXXXX:role/AmazonRekognitionMyDataStream" \
>   --settings '{"FaceSearch": {"CollectionId": "MyCollection","FaceMatchThreshold": 85.5}}' \
>   --region us-west-2

{
    "StreamProcessorArn": "arn:aws:rekognition:us-west-2:XXXXXXXXXX:streamprocessor/MyStreamProcessorForCam"
}

作成したStreamProcessorを確認します。

$ aws rekognition describe-stream-processor --name MyStreamProcessorForCam --region us-west-2
{
    "Status": "STOPPED",
    "Name": "MyStreamProcessorForCam",
    "LastUpdateTimestamp": 1513326474.815,
    "Settings": {
        "FaceSearch": {
            "FaceMatchThreshold": 80.0,
            "CollectionId": "MyCollection"
        }
    },
    "RoleArn": "arn:aws:iam::XXXXXXXXXX:role/AmazonRekognitionMyDataStream",
    "StreamProcessorArn": "arn:aws:rekognition:us-west-2:XXXXXXXXXX:streamprocessor/MyStreamProcessorForCam",
    "Output": {
        "KinesisDataStream": {
            "Arn": "arn:aws:kinesis:us-west-2:XXXXXXXXXX:stream/AmazonRekognitionAnalysisStream"
        }
    },
    "Input": {
        "KinesisVideoStream": {
            "Arn": "arn:aws:kinesisvideo:us-west-2:XXXXXXXXXX:stream/AmazonRekognition-VideoStream/1513326097286"
        }
    },
    "CreationTimestamp": 1513326474.814
}

StreamProcessorを開始する

さて、準備が出来ましたので、StreamProcessorを開始します。

$ aws rekognition start-stream-processor --name MyStreamProcessorForCam --region us-west-2

開始したことを確認します。

$ aws rekognition describe-stream-processor --name MyStreamProcessorForCam --region us-west-2
{
    "Status": "STARTING",
    "Name": "MyStreamProcessorForCam",
    "LastUpdateTimestamp": 1513326537.853,
    "Settings": {
        "FaceSearch": {
            "FaceMatchThreshold": 80.0,
            "CollectionId": "MyCollection"
        }
    },
    "RoleArn": "arn:aws:iam::XXXXXXXXXX:role/AmazonRekognitionMyDataStream",
    "StreamProcessorArn": "arn:aws:rekognition:us-west-2:XXXXXXXXXX:streamprocessor/MyStreamProcessorForCam",
    "Output": {
        "KinesisDataStream": {
            "Arn": "arn:aws:kinesis:us-west-2:XXXXXXXXXX:stream/AmazonRekognitionAnalysisStream"
        }
    },
    "Input": {
        "KinesisVideoStream": {
            "Arn": "arn:aws:kinesisvideo:us-west-2:XXXXXXXXXX:stream/AmazonRekognition-VideoStream/1513326097286"
        }
    },
    "CreationTimestamp": 1513326474.814
}

Kinesis Video Streamに映像を送る

以下のブログを参考に、Kinesis Video Streamに映像を送ります。

Kinesis Streamからデータを確認する

ではまず、Kinesis StreamのShard IDを確認します。

$ aws kinesis describe-stream --stream-name AmazonRekognitionAnalysisStream --region us-west-2

{
    "StreamDescription": {
        "KeyId": null,
        "EncryptionType": "NONE",
        "StreamStatus": "ACTIVE",
        "StreamName": "AmazonRekognitionAnalysisStream",
        "Shards": [
            {
                "ShardId": "shardId-000000000000",
                "HashKeyRange": {
                    "EndingHashKey": "340282366920938463463374607431768211455",
                    "StartingHashKey": "0"
                },
                "SequenceNumberRange": {
                    "StartingSequenceNumber": "49579830162359776046801059936907549632651709008440197122"
                }
            }
        ],
        "StreamARN": "arn:aws:kinesis:us-west-2:XXXXXXXXXX:stream/AmazonRekognitionAnalysisStream",
        "EnhancedMonitoring": [
            {
                "ShardLevelMetrics": []
            }
        ],
        "StreamCreationTimestamp": 1513326267.0,
        "RetentionPeriodHours": 24
    }
}

Shardを指定して、ループでレコードを取得します。

$ SHARD_ITERATOR=$(aws kinesis get-shard-iterator --shard-id shardId-000000000000 --shard-iterator-type TRIM_HORIZON --stream-name AmazonRekognitionAnalysisStream --query 'ShardIterator' --region us-west-2)

$ while :
 do 
   aws kinesis get-records --shard-iterator $SHARD_ITERATOR  --region us-west-2 
 done

するとこんなデータが取れます。

{
            "Data": "eyJJbnB1dEluZm9ybWF0aW9uIjp7IktpbmVzaXNWaWRlbyI6eyJTdHJlYW1Bcm4iOiJhcm46YXdzOmtpbmVzaXN2aWRlbzp1cy13ZXN0LTI6NDA2OTEwMjA3OTcwOnN0cmVhbS9BbWF6b25SZWtvZ25pdGlvbi1WaWRlb1N0cmVhbS8xNTEzMzI2MDk3Mjg2IiwiRnJhZ21lbnROdW1iZXIiOiI5MTM0Mzg1MjMzMzE4MTQzMjgyODQzNjk1NjQzNjU5MzYxMzYzMDk3Njk3ODUwOCIsIlNlcnZlclRpbWVzdGFtcCI6MS41MTMzMjY3MTU4MjFFOSwiUHJvZHVjZXJUaW1lc3RhbXAiOjQxMjI2LjU5OCwiRnJhbWVPZmZzZXRJblNlY29uZHMiOjAuMH19LCJTdHJlYW1Qcm9jZXNzb3JJbmZvcm1hdGlvbiI6eyJTdGF0dXMiOiJSVU5OSU5HIn0sIkZhY2VTZWFyY2hSZXNwb25zZSI6W3siRGV0ZWN0ZWRGYWNlIjp7IkJvdW5kaW5nQm94Ijp7IkhlaWdodCI6MC40MzYxMTExMiwiV2lkdGgiOjAuMjQ1MzEyNSwiTGVmdCI6MC40MDE1NjI1LCJUb3AiOjAuMTM0NzIyMjJ9LCJDb25maWRlbmNlIjo5OS45NDkxOTYsIkxhbmRtYXJrcyI6W3siWCI6MC40NzQ1MDA4LCJZIjowLjI4Nzk3MjQyLCJUeXBlIjoiZXllTGVmdCJ9LHsiWCI6MC41NzIwMjM0NSwiWSI6MC4yNzk4NDU3NywiVHlwZSI6ImV5ZVJpZ2h0In0seyJYIjowLjUxNDgxNzYsIlkiOjAuMzE1ODY3MzMsIlR5cGUiOiJub3NlIn0seyJYIjowLjQ4NDUxMjE1LCJZIjowLjQ2MDc0MjI2LCJUeXBlIjoibW91dGhMZWZ0In0seyJYIjowLjU2NDA4MzkzLCJZIjowLjQ1MjA4NjksIlR5cGUiOiJtb3V0aFJpZ2h0In1dLCJQb3NlIjp7IlBpdGNoIjoyMi44MzIwODMsIlJvbGwiOi0yLjYyNjA3ODgsIllhdyI6LTcuMTIxNjR9LCJRdWFsaXR5Ijp7IkJyaWdodG5lc3MiOjQyLjIyMDgyLCJTaGFycG5lc3MiOjk5Ljk5NjcxfX0sIk1hdGNoZWRGYWNlcyI6W3siU2ltaWxhcml0eSI6ODEuMDIyODEsIkZhY2UiOnsiQm91bmRpbmdCb3giOnsiSGVpZ2h0IjowLjI4MzYyOSwiV2lkdGgiOjAuMjgzMzMzLCJMZWZ0IjowLjQxNzcwOCwiVG9wIjowLjE2NDc1NX0sIkZhY2VJZCI6IjI3N2IyNGMzLTEzYmUtNDE2Zi1iYjFkLTI2NjY5NzljYWIwYSIsIkNvbmZpZGVuY2UiOjk5Ljk5OTUsIkltYWdlSWQiOiJlZWJlNDQwZi1kYmFjLTdiMjktMzc0Mi1hNWU1YTQ5ZDk0N2YifX0seyJTaW1pbGFyaXR5Ijo4MC40MDcxOCwiRmFjZSI6eyJCb3VuZGluZ0JveCI6eyJIZWlnaHQiOjAuNTExMzU1LCJXaWR0aCI6MC41MTEzNTUsIkxlZnQiOjAuMTgyNDE4LCJUb3AiOjAuMTgxNjg1fSwiRmFjZUlkIjoiMDNiZWU2ZjAtNjc2ZC00NzQwLTg3NjQtZTlhODk1NDY2ZjRkIiwiQ29uZmlkZW5jZSI6OTkuOTk5NSwiSW1hZ2VJZCI6ImNlNjM4YjU4LWNiMTktZmIxZi1mZDg1LWI0ZWIwNjg1OTM4NSJ9fSx7IlNpbWlsYXJpdHkiOjgwLjMyNjU4NCwiRmFjZSI6eyJCb3VuZGluZ0JveCI6eyJIZWlnaHQiOjAuNjA2NjY3LCJXaWR0aCI6MC42MDY2NjcsIkxlZnQiOjAuMjc2NjY3LCJUb3AiOjAuMjQxMTExfSwiRmFjZUlkIjoiMTljY2M2ZmYtMTJjMi00MzQ1LThmOTUtYzg3MDJlZjkxZGMwIiwiQ29uZmlkZW5jZSI6OTkuOTk5OSwiSW1hZ2VJZCI6ImE4ZDQ3ZmEyLTRlYTQtNzM2Ni1jNjk1LWIyNmRiNGQ5ODM5OSJ9fV19XX0=",
            "PartitionKey": "45811272-8f2a-4e4c-b430-768fc203be8c",
            "ApproximateArrivalTimestamp": 1513326718.807,
            "SequenceNumber": "49579830162359776046801059965445452530474676505196625922"
        },

このDataはBase64でエンコードされているので、BASE64などを使ってデコードすると、以下のような情報が入っていることが分かります。

{
	"InputInformation": {
		"KinesisVideo": {
			"StreamArn": "arn:aws:kinesisvideo:us-west-2:XXXXXXXXXX:stream/AmazonRekognition-VideoStream/1513326097286",
			"FragmentNumber": "91343852333181432828436956436593613630976978508",
			"ServerTimestamp": 1513326715.821,
			"ProducerTimestamp": 41226.598,
			"FrameOffsetInSeconds": 2
		}
	},
	"StreamProcessorInformation": {
		"Status": "RUNNING"
	},
	"FaceSearchResponse": [
		{
			"DetectedFace": {
				"BoundingBox": {
					"Height": 0.37916666,
					"Width": 0.21328124,
					"Left": 0.421875,
					"Top": 0.15555556
				},
				"Confidence": 99.5095,
				"Landmarks": [
					{
						"X": 0.48145723,
						"Y": 0.27962288,
						"Type": "eyeLeft"
					},
					{
						"X": 0.5748005,
						"Y": 0.2726727,
						"Type": "eyeRight"
					},
					{
						"X": 0.5204049,
						"Y": 0.30154547,
						"Type": "nose"
					},
					{
						"X": 0.49123827,
						"Y": 0.4395248,
						"Type": "mouthLeft"
					},
					{
						"X": 0.5679146,
						"Y": 0.42800653,
						"Type": "mouthRight"
					}
				],
				"Pose": {
					"Pitch": 24.182444,
					"Roll": -2.5030267,
					"Yaw": -7.812156
				},
				"Quality": {
					"Brightness": 40.79603,
					"Sharpness": 99.99453
				}
			},
			"MatchedFaces": []
		}
	]
}

ということで、Amazon Kinesis Video Streamsの映像をAmazon Rekognition Videoで解析し、DetectedFaceが出来たことがわかりました!

さいごに

動態解析や窓口での顧客解析などに活用できそうですね!