4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【30日でAWSをマスターするハンズオン問題集】Day:29 Amazon Rekognitionのラベル検索で犬か猫を判定するシステムを作ろう

4
Posted at

こちらの投稿は2025 Japan AWS Jr.Championsの有志メンバーで作成した『30日間で主要AWSサービスを構築できるようになる』をテーマにした初学者向けのハンズオン問題集のDAY29になります:santa_tone2:

問題集の趣旨や作成に至るまでの経緯は以下の記事をご覧いただければと思います。

📝 概要

項目 内容
所要時間 約1時間
メインサービス Amazon S3, AWS Lambda, Amazon Rekognition
学べること Amazon Rekognitionの基礎知識、他サービスへの接続方法
想定費用 約10円(※実行回数により変動します。)

🎯 課題内容

Amazon RekognitionによってS3にアップロードされた画像が犬 or 猫か画像判定するシステムを作成します。

📊 アーキテクチャ図

architecture-image

🔧 実装機能

  • Amazon S3に画像が置かれたことをトリガーにAWS Lambdaが動きます
  • AWS Lambdaが、Amazon Rekognitionにリクエストを投げ、画像のラベルを取得します
  • AWS Lambdaで応答結果のラベルに「dog」 or 「cat」のラベルが含まれているか判定します
  • 判定結果をAmazon DynamoDBに登録します

💡 実装のヒント

AWS LambdaからAmazon Rekognitionの接続方法 AWS LambdaからAmazon Rekognitionの接続方法には、ラベル検出を使用します。
詳しくは以下ドキュメントをご覧ください。
Amazon Rekognition 公式ドキュメント
DynamoDBの構成について 結果を確認できるカラムを追加しましょう。
その他にもあったほうが良いカラムを考えてみましょう。(例: ラベル、インプットの画像情報等)

✅ 完成後のチェックポイント

  • 画像をS3にアップロードするとトリガー設定しているLambdaが起動する
  • LambdaがAmazon Rekognitionにリクエストを投げ応答を取得できている
  • DynamoDBに画像の判定結果が登録されている

🧰 使用資材

Lambdaのサンプルコード(オリジナルで作成しても良いですが、こちらのサンプルを使用しても構いません。)
import json
import boto3
import logging
import datetime


# ログ設定
logger = logging.getLogger()
logger.setLevel(logging.INFO)

# AWSクライアントの初期化
rekognition = boto3.client('rekognition')
dynamodb = boto3.resource('dynamodb')

# TODO:DynamoDBテーブル名は対応する名前に書き換えてください
# 今回は、ハンズオンのためDB名をハードコーディングしていますが、本来はLambdaの環境変数に設定するのがベターです。
# 参考:https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html
TABLE_NAME = 'image_classification_results'
table = dynamodb.Table(TABLE_NAME)

def lambda_handler(event, context):
  try:
      # S3イベントから情報を取得
      record = event['Records'][0]
      bucket_name = record['s3']['bucket']['name']
      object_key = record['s3']['object']['key']
      
      logger.info(f"Processing image: {object_key} from bucket: {bucket_name}")
      
      # Rekognitionでラベル検出
      response = rekognition.detect_labels(
          Image={
              'S3Object': {
                  'Bucket': bucket_name,
                  'Name': object_key
              }
          },
          MaxLabels=10,
          MinConfidence=70
      )
      
      # 犬か猫かを判定
      classification_result = classify_animal(response['Labels'])
      
      # DynamoDBに結果を保存
      save_to_dynamodb(bucket_name, object_key, classification_result, response['Labels'])
      
      logger.info(f"Classification result for {object_key}: {classification_result}")
  
  except Exception as e:
      logger.error(f"Error processing image: {str(e)}")
      raise e
  
  return {
      'statusCode': 200,
      'body': json.dumps('Image classification completed successfully')
  }

def classify_animal(labels):
  """
  ラベルから犬か猫かを判定する関数
  """
  dog_confidence_per = 0
  cat_confidence_per = 0
  
  for label in labels:
      label_name = label['Name'].lower()
      confidence_per = label['Confidence']
      # ラベルが犬 or 猫の場合、各ラベルの信頼度を合計する
      if label_name == 'dog':
          dog_confidence_per += confidence_per
      elif label_name == 'cat':
          cat_confidence_per += confidence_per
  
  # 判定ロジック
  # 犬 or 猫のラベルが検出されなかったらunknownを登録
  if dog_confidence_per == 0 and cat_confidence_per == 0:
      return 'unknown'
  # 両方検出された場合は信頼度の高い方を選択
  if dog_confidence_per > cat_confidence_per:
      return 'dog'
  else:
      return 'cat'

def save_to_dynamodb(bucket_name, object_key, classification, all_labels):
  """
  DynamoDBに結果を保存する関数
  """
  try:
      # タイムスタンプを追加
      timestamp = datetime.datetime.utcnow().isoformat()

      # DynamoDBアイテムを作成(キーは作成したDynamoDBの仕様に応じて変更してください)
      item = {
          'timestamp': timestamp, # パーティションキー
          'classification': classification, # 判定結果
          # 以下は任意のキー
          'image_key': object_key, 
          'bucket_name': bucket_name,
          'all_labels': set_all_labels(all_labels)
      }
      
      # DynamoDBに保存
      table.put_item(Item=item)
      logger.info(f"Successfully saved classification result to DynamoDB for {object_key}")
      
  except Exception as e:
      logger.error(f"Error saving to DynamoDB: {str(e)}")
      raise e

def set_all_labels(all_labels):
  """
  登録する値を整形する
  """
  all_labels_list = []
  # 登録する値を整形
  for label in all_labels:
      label_obj = {
          'name': label['Name'],
          'confidence': str(label['Confidence'])
      }
      all_labels_list.append(label_obj)
  return all_labels_list

🔗 リファレンスリンク

🛠️ 解答・構築手順(クリックで開く)

解答と構築手順を見る

✅ ステップ1:AWS S3 の作成

  1. AWS マネジメントコンソールを開く
  2. 「Amazon S3」→「バケットを作成」
  3. バケット名を入力(その他はデフォルト設定で可)
  4. 「バケットを作成」ボタンをクリック

✅ ステップ2:DynamoDB の作成

  1. 「Amazon DynamoDB」→「テーブル」→「テーブルの作成」
  2. テーブル名:image_classification_results
  3. パーティションキー:timestamp(文字列) (ソートキーは任意、その他デフォルト)
    • パーテーションキーはtimestampでなくても一意になる値であれば問題ありません。
  4. 「テーブルの作成」ボタンをクリック

✅ ステップ3:AWS Lambda の作成

  1. AWS マネジメントコンソールを開く
  2. 「AWS Lambda」→「関数の作成」
  3. ランタイム:任意の言語(サンプルコードではPythonを使用しています。)
  4. IAMロールを設定し、作成する
    1. Lambdaと一緒にIAMロールを作成する場合
      • アクセス権限 → 「デフォルトの実行ロールを変更」をクリック
      • 「基本的な Lambda アクセス権限で新しいロールを作成」を選択し、「関数の作成」ボタンをクリック
    2. IAMロールが作成済みの場合
      • アクセス権限 → 「デフォルトの実行ロールを変更」をクリック
      • 「既存のロール使用する」を選択し、作成済みのIAMロールを選択
      • 「関数の作成」ボタンをクリック
      • 既存のロールには以下のポリシーがついていることを想定しています
          {
              "Version": "2012-10-17",
              "Statement": [
                  {
                      "Effect": "Allow",
                      "Action": "logs:CreateLogGroup",
                      "Resource": "arn:aws:logs:{リージョン}:{アカウントID}:*"
                  },
                  {
                      "Effect": "Allow",
                      "Action": [
                          "logs:CreateLogStream",
                          "logs:PutLogEvents"
                      ],
                      "Resource": [
                          "arn:aws:logs:{リージョン}:{アカウントID}:log-group:/aws/lambda/{Lambda関数名}:*"
                      ]
                  }
              ]
          }
      
    ⚠️ 1 or 2のどちらを選んだ場合もAmazon DynamoDB、Amazon S3、Amazon Rekognitionへのアクセスを許可する必要があります!
    • Lambda関数作成後、タブの「設定」→ アクセス権限 → ロール名をクリック →IAM画面で適切なポリシーが設定されているか確認してください
    • AWS管理ポリシーの場合は、以下ポリシーが設定されていればOKです
      • AmazonRekognitionFullAccess
      • AmazonDynamoDBFullAccess
      • AmazonS3FullAccess
        ※今回はハンズオンのためフルアクセスを付与していますが、
        実際は最低限の権限に絞ることが推奨されます
  5. Lambda関数作成後、「トリガーを追加」ボタンをクリック
  6. ソースはS3を選択し、ステップ1で作成したバケットを選択し、トリガーに設定する
  7. コードを記述(サンプルコードを使用する場合は、使用資材のコードを張り付けてください)

✅ ステップ4:動作確認

  • S3に添付の任意の画像(以下のような犬か猫が映っている画像)をアップロードすると画像判定結果がDynamoDBに登録されているか?
  • アップロード画像の例(参照: pixabay
sample-upload-image
  1. S3アップロード
  • コンソールから対象バケットに判定したい画像をアップロードします。
s3-upload
  1. Amazon DynamoDBの出力結果
  • Amazon DynamoDBの判定結果のカラム(ハンズオンだとclassification)に判定結果が登録されていれば成功です!
dynamodb-result

🧹 片付け(リソース削除)

  • AWS Lambda 関数を削除
  • Amazon DynamoDB テーブルを削除
  • Amazon S3を削除

🏁 おつかれさまでした!

この課題では 基本サービスとAmazon Rekognitionのラベル検出の使用方法と他AWSサービスとの接続の力が身につきます!

次回は応用編としてRekognitionの他API機能にも挑戦してみましょう!

4
0
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
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?