0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Amazon Rekognitionで映像解析システムを構築してみた

Last updated at Posted at 2025-06-28

はじめに

AWS Kinesis Video Streamsに配信された映像データをリアルタイムで解析し、人物や物体を検出するシステムを作ってみました!解析にはAmazon Rekognitionを使っています。映像データをそのまま解析させると料金が高額になってしまうので、映像データからフレームを抽出し、画像ファイルを解析することにしました。

image.png

今回は、Kinesis Video Streamsで映像を受信できている状態から構築しています。
映像を受信するまでの手順は別の記事にまとめているので参考にしてもらえればと思います!

構築手順

1. IAMロール作成

まずはLambdaの実行ロールと必要なポリシーを設定します。

必要なポリシー:

  • AWSLambdaBasicExecutionRole (Lambda実行)
  • AmazonKinesisVideoStreamsReadOnlyAccess (映像取得)
  • AmazonRekognitionReadOnlyAccess (解析)
  • AmazonS3FullAccess (解析結果保存)
  • AmazonSNSFullAccess (メール通知)

2. Lambda関数の作成

  • ランタイム: Python 3.11
  • メモリ: 1024MB
  • タイムアウト: 15秒
  • メモリ不足のエラーが出たので128MBから1024MBに増やしました。
  • フレーム抽出に使用するOpenCVの依存ライブラリのnumpy 1.24.3との互換性の問題でPython 3.12でエラーが出たのでPython 3.11で設定しました。

3. OpenCVレイヤー構築

LambdaでOpenCVを使用するためにはカスタムレイヤーが必要です。Dockerを使用してLinux環境でOpenCVをビルドした後、S3にアップロードしてレイヤーに設定しています。

4. SNSの作成

トピックとサブスクリプションを設定するだけなので割愛します。

5. Lambda関数の実装

コードをLambda関数にデプロイします。処理の流れは↓のようになっています。

  1. Kinesis Video Streamsからデータ取得
  2. OpenCVでフレーム抽出・最適化
  3. Rekognitionで物体検出
  4. 結果の可視化処理
  5. S3保存・SNS通知

全て記載すると長くなるので、要点を絞って紹介します。

フレーム抽出

def extract_frame_lightweight(video_data):
    # Lambda一時ディスクに保存
    temp_path = '/tmp/temp_video.mp4'
    with open(temp_path, 'wb') as f:
        f.write(video_data)
    
    # OpenCV設定
    cap = cv2.VideoCapture(temp_path)
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 360)
    
    ret, frame = cap.read()
    cap.release()
    
    # 解像度調整
    frame_resized = cv2.resize(frame, (640, 360), 
                              interpolation=cv2.INTER_LINEAR)
    
    # JPEG圧縮(品質70%)
    encode_params = [cv2.IMWRITE_JPEG_QUALITY, 70]
    _, buffer = cv2.imencode('.jpg', frame_resized, encode_params)
    
    return {
        'frame_bytes': buffer.tobytes(),
        'original_frame': frame_resized.copy(),
        'file_size_kb': len(buffer.tobytes()) // 1024
    }

解析にかかるコストの削減、リアルタイム性を向上させることを目的とした処理です。
映像データからフレームを抽出して、解像度と画質を落としています。

  • 解像度削減:1280x720 → 640x360
  • JPEG品質調整:70%
  • 単一フレーム処理:1フレームのみ抽出

Rekognitionの呼び出し

Rekognitionのパラメータを調整し、処理速度と検出精度を改善します。

def analyze_with_rekognition_optimized(image_bytes):
    # 最適化されたRekognition呼び出し
    response = rekognition.detect_labels(
        Image={'Bytes': image_bytes},
        MaxLabels=5,
        MinConfidence=80.0,
        Features=['GENERAL_LABELS']
    )
    
    # 結果の軽量化処理
    labels = []
    for label in response['Labels'][:3]:  # 上位3つのみ
        label_info = {
            'Name': label['Name'],
            'Confidence': round(label['Confidence'], 1)
        }
        
        # バウンディングボックス(最初の1つのみ)
        if 'Instances' in label and label['Instances']:
            instance = label['Instances'][0]
            label_info['BoundingBox'] = {
                'Left': round(instance['BoundingBox']['Left'], 2),
                'Top': round(instance['BoundingBox']['Top'], 2),
                'Width': round(instance['BoundingBox']['Width'], 2),
                'Height': round(instance['BoundingBox']['Height'], 2)
            }
        
        labels.append(label_info)
    
    return {
        'labels': labels,
        'label_count': len(labels),
        'confidence_avg': round(sum(l['Confidence'] for l in labels) / len(labels), 1) if labels else 0
    }

検出するラベル数は3つに絞っていて、信頼度が80%以上の結果のみ採用するようにしています。検出された物の内、最初の1つにだけバウンディングボックスが付くようにしました。

6. EventBridgeの設定

LambdaをトリガーするためにEventBridgeを使用しています。とりあえず、スケジュールを指定して定期実行していますが実際に利用するときは何らかのイベントと連動するような形でトリガーする仕組みを作りたいですね。

実行結果

実行されるとS3に解析結果が保存され、メールに記載されたURLから確認することができます。簡単な解析の例になりますが、ペットボトルのコーラが映った映像を解析した例がこちらです!

image.png

Beverage:99.7%、Soda:99.7%、Coke:99.6%といったように正しく検知してくれました。

まとめ

Rekognitionを使ってリアルタイムな解析をすることができました!
解析のリアルタイム性についてですが、EventBridgeでLambdaをトリガーしてからS3に解析結果が格納されるまで約2秒でした。Kinesis Video Streamsへの配信遅延も考慮するとシステム全体としての遅延は10秒程です。十分実用可能な範囲じゃないでしょうか。
今後はユースケースに応じた機能拡張も考えてみたいと思います!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?