AWSコンソールだけで画像認識パイプラインを構築する手順【S3 + Lambda + Rekognition / SAM版との比較付き】

AWS Basic
スポンサーリンク
スポンサーリンク

はじめに

「S3に画像をアップロードしたら、自動で中身を分析してほしい」——そんな仕組みを、AWSコンソールのみでゼロから構築するハンズオンです。

Amazon Rekognition の DetectLabels API を使うと、画像に写っている物体・シーン・動物などを自動で検出できます。犬の写真をアップロードすれば「Dog(信頼度98%)」「Animal(97%)」といったラベルが返ってきます。

ユーザー
  ↓ JPEG / PNG をアップロード
S3 バケット(UploadBucket)
  ↓ ObjectCreated イベント(自動)
Lambda(DetectFunction)
  ↓ rekognition:DetectLabels(S3Object を指定)
Amazon Rekognition
  ↓ [{"name": "Dog", "confidence": 98.5}, ...] を返す
Lambda
  ↓ print(JSON)
CloudWatch Logs

このハンズオンで体験できること:

  • S3 トリガー — S3 へのアップロードを契機に Lambda を自動起動する仕組み
  • Rekognition DetectLabels — 画像内の物体・シーン・動物を検出してラベルと信頼度を返す API
  • IAM 権限管理 — Lambda から S3・Rekognition を呼び出すために必要な権限の追加手順
  • S3Object 参照 — 画像データを Lambda に転送せず S3 の場所を直接 Rekognition に渡す効率的な方法

この記事は SAM版ハンズオン の比較記事です。
コンソール操作で S3・Lambda・Rekognition の連携を視覚的に学び、SAM と何が違うのかを比較したい方向けです。


Amazon検索[本 AWS 開発]

スポンサーリンク

キーワード解説

用語意味
DetectLabelsRekognition API。画像内の物体・シーンを検出してラベル名と信頼度を返す
信頼度(Confidence)ラベルが正確であるかどうかの確度(0〜100%)。今回は70%以上のみ返す
S3Object 参照画像データを Lambda に転送せず、S3 の場所を Rekognition に渡す方式
S3 イベント通知S3 バケットへのオブジェクト作成・削除などをトリガーに Lambda を呼び出す仕組み
実行ロールLambda が他の AWS サービスを操作するために使う IAM ロール
無料枠最初の12ヶ月 / 月5,000枚まで無料。超過後は $0.001/枚

スポンサーリンク

使用するAWSサービス

サービス役割料金
S3画像のアップロード先バケット月5GBまで無料
LambdaS3 イベントを受けて Rekognition を呼び出す月100万リクエスト・400,000 GB-秒まで無料
Rekognition画像ラベル検出(DetectLabels)最初の12ヶ月 / 月5,000枚まで無料
IAMLambda の実行権限管理無料
CloudWatch LogsLambda の実行ログ(ラベル検出結果)月5GBまで無料

全体の作業順序

① S3 バケットを作成する
      ↓
② Lambda 関数を作成する(コード入力・タイムアウト設定)
      ↓
③ Lambda の実行ロールに権限を追加する
  (S3: GetObject / Rekognition: DetectLabels)
      ↓
④ Lambda に S3 トリガーを追加する
      ↓
⑤ 動作テスト(画像をアップロード → ログを確認)
      ↓
⑥ リソースの削除

① S3 バケットを作成する

AWSコンソール → S3 → 「バケットを作成」

設定項目
バケット名my-rekognition-upload(グローバルユニークな名前)
リージョンアジアパシフィック(東京)ap-northeast-1
その他デフォルトのまま

「バケットを作成」をクリック。

控えておく情報:

  • バケット名(削除時・IAMポリシー設定時に使用)

バケット名のグローバルユニークについて:
S3 のバケット名は全 AWS アカウントで一意である必要があります。my-rekognition-upload- に自分のアカウントIDや日付を追加すると重複を避けられます。


② Lambda 関数を作成する

AWSコンソール → Lambda → 「関数の作成」

設定項目
作成方法一から作成
関数名DetectFunction
ランタイムPython 3.12
アーキテクチャx86_64
実行ロール「基本的な Lambda アクセス権限で新しいロールを作成」(デフォルト)

「関数の作成」をクリック。

タイムアウトの設定

「設定」タブ → 「一般設定」→「編集」

設定項目
タイムアウト30

「保存」をクリック。

タイムアウトを 30 秒にする理由:
Rekognition API の呼び出しには数秒かかることがあります。デフォルト(3秒)では Rekognition のレスポンスを待ちきれずタイムアウトするため、余裕を持って 30 秒に設定します。

コードの入力

「コード」タブ → lambda_function.py を開いて既存の内容を全て置き換える。

import json
import urllib.parse
import boto3

rekognition = boto3.client("rekognition")


def lambda_handler(event, context):
    for record in event["Records"]:
        bucket = record["s3"]["bucket"]["name"]
        key = urllib.parse.unquote_plus(record["s3"]["object"]["key"])

        print(json.dumps({"status": "start", "bucket": bucket, "key": key}))

        response = rekognition.detect_labels(
            Image={
                "S3Object": {
                    "Bucket": bucket,
                    "Name": key,
                }
            },
            MaxLabels=10,
            MinConfidence=70,
        )

        labels = [
            {
                "name": label["Name"],
                "confidence": round(label["Confidence"], 1),
            }
            for label in response["Labels"]
        ]

        result = {
            "bucket": bucket,
            "key": key,
            "label_count": len(labels),
            "labels": labels,
        }
        print(json.dumps(result, ensure_ascii=False))

    return {"processedCount": len(event["Records"])}

「Deploy」ボタンをクリックしてコードを保存する。

コードのポイント:

ポイント説明
rekognition = boto3.client("rekognition") をグローバルに置くLambda のコールドスタート時に1回だけ初期化。ウォームスタート時は再利用されパフォーマンスが向上する
urllib.parse.unquote_plus(key)日本語や空白を含むファイル名は S3 イベントで URL エンコードされるため、デコードが必要
S3Object 参照画像データを Lambda のメモリに転送せず S3 の場所を Rekognition に渡す。メモリ効率が良い
MinConfidence=70信頼度 70% 未満のラベルは結果から除外。全件見たい場合は 0 に変更して Deploy する

③ Lambda の実行ロールに権限を追加する

デフォルトの実行ロールは CloudWatch Logs への書き込みのみ。
S3 からの読み取りと Rekognition の呼び出し権限を追加する。

Lambda → DetectFunction → 「設定」タブ → 「アクセス権限」→ 実行ロール名のリンクをクリック

(例: DetectFunction-role-XXXX)→ IAM コンソールのロール画面が開く。

3-1. Rekognition 権限を追加する

「許可を追加」→「ポリシーをアタッチ」

検索ボックスに Rekognition と入力 → AmazonRekognitionReadOnlyAccess にチェック → 「許可を追加」。

AmazonRekognitionReadOnlyAccess に含まれる主な権限:

  • rekognition:DetectLabels — ラベル検出(今回使用)
  • rekognition:DetectFaces — 顔検出
  • rekognition:DetectText — テキスト検出

3-2. S3 GetObject 権限を追加する

「許可を追加」→「インラインポリシーを作成」

「JSON」タブを選択して以下を入力する(my-rekognition-upload を ① のバケット名に変更):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-rekognition-upload/*"
    }
  ]
}

「次へ」→ ポリシー名: S3ReadForRekognition → 「ポリシーを作成」。

なぜ S3 の権限が必要か:
Rekognition に S3Object を指定した場合、Rekognition が Lambda の IAM ロールを借りて
S3 からオブジェクトを取得します。Lambda ロールに s3:GetObject がないと 403 エラーになります。

SAM版では S3ReadPolicy(SAM 組み込みポリシー)が特定バケットのみに s3:GetObject を自動付与します。
コンソール版では手動でインラインポリシーを作成する必要があります。


④ Lambda に S3 トリガーを追加する

Lambda → DetectFunction → 「設定」タブ → 「トリガー」→「トリガーを追加」

設定項目
ソースS3
バケットmy-rekognition-upload(① で作成したバケット)
イベントタイプすべてのオブジェクト作成イベント(s3:ObjectCreated:*)
プレフィックス空欄(全ファイルを対象)
サフィックス空欄(全形式を対象)

「再帰呼び出し」の確認チェックボックスにチェック → 「追加」をクリック。

再帰呼び出しについて:
Lambda の実行結果を同じバケットに書き込む構成にすると、S3 イベントが再発火して無限ループになります。
今回は S3 への書き込みを行わないため問題ありません。


⑤ 動作テスト

テスト用画像の準備

任意の JPEG または PNG 画像を用意する(例: 犬・猫・風景など)。
ファイルサイズは 15MB 以下 であることを確認する。

画像をアップロードする

方法 A: S3 コンソール

S3 → my-rekognition-upload → 「アップロード」→ ファイルをドラッグ&ドロップ → 「アップロード」

方法 B: AWS CLI

aws s3 cp "C:\Users\yourname\Pictures\dog.jpg" s3://my-rekognition-upload/ --region ap-northeast-1

CloudWatch Logs でラベル検出結果を確認する

Lambda → DetectFunction → 「モニタリング」タブ → 「CloudWatch Logs を表示」

最新のロットストリームを開いて以下のような出力を確認する。

{"status": "start", "bucket": "my-rekognition-upload", "key": "dog.jpg"}
{
  "bucket": "my-rekognition-upload",
  "key": "dog.jpg",
  "label_count": 8,
  "labels": [
    {"name": "Dog", "confidence": 98.5},
    {"name": "Pet", "confidence": 98.5},
    {"name": "Animal", "confidence": 98.5},
    {"name": "Canine", "confidence": 98.5},
    {"name": "Mammal", "confidence": 97.2},
    {"name": "Golden Retriever", "confidence": 85.3},
    {"name": "Grass", "confidence": 76.1},
    {"name": "Outdoors", "confidence": 71.4}
  ]
}
{"processedCount": 1}

MinConfidence: 70 の効果:
信頼度 70% 未満のラベルは結果に含まれません。
全ラベルを確認したい場合は MinConfidence=0 に変更して「Deploy」する。

複数枚でテストする

aws s3 cp "C:\Users\yourname\Pictures\cat.jpg"  s3://my-rekognition-upload/ --region ap-northeast-1
aws s3 cp "C:\Users\yourname\Pictures\city.jpg" s3://my-rekognition-upload/ --region ap-northeast-1

各ファイルのアップロードごとに Lambda が起動し、それぞれのラベル検出結果がログに記録される。

無料枠の管理:
AWS コンソール → Billing → 無料利用枠 → 「Amazon Rekognition」で当月の使用枚数を確認できます。
月5,000枚まで無料のため、学習目的のハンズオンでは通常課金されません。


⑥ リソースの削除

課金を止めるために、ハンズオン完了後は必ず削除してください。

1. S3 バケットのオブジェクトを全て削除する

aws s3 rm s3://my-rekognition-upload --recursive --region ap-northeast-1

2. S3 バケットを削除する

S3 → my-rekognition-upload → 「削除」→ バケット名を入力 → 「削除」

3. Lambda のトリガーを削除する

Lambda → DetectFunction → 「設定」→「トリガー」→ S3 トリガーを選択 → 「削除」

4. Lambda 関数を削除する

Lambda → 関数 → DetectFunction → 「アクション」→「削除」

5. IAM ロールを削除する(任意)

IAM → ロール → DetectFunction-role-XXXX を削除

6. CloudWatch Logs のロググループを削除する(任意)

CloudWatch → ロググループ → /aws/lambda/DetectFunction → 削除

SAM版との大きな違い(SAMのメリット):
SAM版では sam delete 1コマンドで上記すべてのリソースを一括削除できます。


SAMとの対比

SAMの記述コンソールでやること
AWS::S3::BucketS3 → バケットを作成
S3ReadPolicy(SAM組み込み)IAM → ロールにインラインポリシーで s3:GetObject を追加
RekognitionDetectOnlyPolicy(SAM組み込み)IAM → ロールに AmazonRekognitionReadOnlyAccess をアタッチ
Events: Type: S3(ObjectCreated)Lambda → トリガーを追加(S3・全オブジェクト作成イベント)
sam deleteS3を空にしてから削除 + Lambda + IAM + CloudWatch Logs を個別に削除

コンソール版のつまずきポイント:
AccessDeniedException が出た場合、S3 の GetObject 権限(インラインポリシー)と Rekognition の DetectLabels 権限(AmazonRekognitionReadOnlyAccess)の両方が揃っているか確認しましょう。どちらか一方が欠けていてもエラーになります。


トラブルシューティング

症状原因対処
Lambda が動作しない(ログが出ない)S3 トリガーが設定されていない④ の手順で S3 トリガーを追加する
AccessDeniedException for RekognitionLambda ロールに Rekognition 権限がない③-1 の手順で AmazonRekognitionReadOnlyAccess をアタッチ
AccessDenied for S3Lambda ロールに S3 GetObject 権限がない③-2 の手順でインラインポリシーを追加
InvalidImageFormatExceptionJPEG/PNG 以外のファイルをアップロードしたJPEG または PNG ファイルを使用する
ImageTooLargeException15MB を超える画像をアップロードした15MB 以下の画像を使用する
ラベルが 0 件MinConfidence が高すぎるコードの MinConfidence=70 を下げて「Deploy」する
日本語ファイル名でエラーURL エンコードが解除されていないコードに urllib.parse.unquote_plus(key) が含まれているか確認
Lambda がタイムアウトするタイムアウトが短い(デフォルト3秒)② の手順でタイムアウトを 30 秒に変更する

まとめ

今回のハンズオンで体験できたこと:

確認項目内容
S3 トリガー画像アップロードと同時に Lambda が自動起動する仕組みを体験
Rekognition DetectLabels画像に写った物体・動物・シーンが自動でラベル付けされる様子を確認
S3Object 参照画像をLambdaに転送せずS3の場所だけを渡す効率的な連携方法
IAM 権限の設定S3・Rekognition それぞれに必要な権限を個別に追加する手順

コンソール版で実感できたポイント

  • S3 → Lambda → Rekognition という3つのサービスのデータの流れが視覚的に理解できる
  • 実行ロールに必要な権限を1つずつ追加することで、IAM の仕組みが身につく
  • リソースを個別に作成・削除することで、各サービスの独立性と依存関係が明確になる

コンソール版と SAM 版を比較してみる

コンソールで S3・Lambda・Rekognition の連携を理解したら、SAM で同じ構成をコードで定義することで「SAM が何を自動化しているか」が明確になります。S3ReadPolicyRekognitionDetectOnlyPolicy による1行での権限付与など、コンソールでの手動操作がコードに対応しています。


関連記事

Amazon検索[本 AWS 開発]

コメント