AWS Lambda 関数によるイメージ分析 - Rekognition

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

AWS Lambda 関数によるイメージ分析

AWS Lambda はサーバーのプロビジョニングや管理をする必要がなく、コードを実行できるコンピューティングサービスです。例えば、アプリケーションコードをホストするサーバーを作成しなくても、モバイルアプリケーションから送信されたイメージを分析できます。以下の手順は、Python を使って DetectCustomLabels を呼び出す Lambda 関数を作成する方法です。この関数は提供されたイメージを分析し、イメージに含まれるラベルのリストを返します。この手順では Python コードの例を記載し、Amazon S3 バケット内またはローカルコンピュータのイメージに対する Lambda 関数の呼び出し方を示しています。

ステップ 1: AWS Lambda 関数を作成する (コンソール)

このステップでは空の AWS 関数と、その関数が DetectCustomLabels オペレーションを呼び出せるようにするための IAM 実行ロールを作成します。これによって、分析用のイメージを格納する Amazon S3 バケットへのアクセス権も付与できます。また、以下の環境変数も指定します。

  • Lambda 関数が使用する Amazon Rekognition Custom Labels モデル。

  • モデルが使用する信頼限界。

ソースコードとオプションのレイヤーは、後で Lambda 関数に追加します。

AWS Lambda 関数を作成するには (コンソール)
  1. AWS Management Console にサインインして AWS Lambda コンソール (https://console.aws.amazon.com/lambda/) を開きます。

  2. [関数の作成] を選択します。詳細については、「コンソールで Lambda 関数を作成する」を参照してください。

  3. 次のオプションを選択します。

    • [一から作成] を選択します。

    • [関数名] に値を入力します。

    • [ランタイム] では、[Python 3.10] を選択します。

  4. [関数を作成] を選択して、AWS Lambda 関数を作成します。

  5. 関数ページで、[設定] タブを選択します。

  6. [環境変数] ペインで、[編集] を選択します。

  7. 次の環境変数を追加します。変数ごとに [環境変数を追加] を選択し、変数のキーと値を入力します。

    キー

    MODEL_ARN

    Lambda 関数で使用するモデルの Amazon リソースネーム (ARN)。モデル ARN は、Amazon Rekognition Custom Labels コンソール内のモデルの詳細ページにある [モデルを使用] タブから取得できます。

    CONFIDENCE

    ラベルの予測におけるモデルの信頼度の最小値 (0~100)。Lambda 関数は、この値より信頼度の低いラベルを返しません。

  8. [保存] を選択して環境変数を保存します。

  9. [アクセス許可] タブの [実行ロール] で、ロールを選択し、IAM コンソールで開きます。

  10. [アクセス許可] タブで [許可の追加]、次に[インラインポリシーの作成] をクリックします。

  11. [JSON] タブを選択し、既存のポリシーを次のポリシーに置き換えます。

    { "Version": "2012-10-17", "Statement": [ { "Action": "rekognition:DetectCustomLabels", "Resource": "*", "Effect": "Allow", "Sid": "DetectCustomLabels" } ] }
  12. [次へ] を選択します。

  13. [ポリシーの詳細]に、「DetectCustomLabels-Access」などのポリシーの名前を入力します。

  14. [ポリシーを作成] を選択します。

  15. 分析用のイメージを Amazon S3 バケットに保存する場合は、ステップ 10~14 を繰り返します。

    1. ステップ 11 では、以下のポリシーを使用します。バケット/フォルダパスを、Amazon S3 バケットと、分析するイメージのフォルダパスに置き換えます。

      { "Version": "2012-10-17", "Statement": [ { "Sid": "S3Access", "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::bucket/folder path/*" } ] }
    2. ステップ 13 ではS3Bucket-access など、異なるポリシー名を選択します。

ステップ 2: (オプション) レイヤーを作成する (コンソール)

この例を実行するうえで、この手順は不要です。DetectCustomLabels オペレーションは、AWS SDK for Python (Boto3) の一部として、デフォルトの Lambda Python 環境に含まれています。Lambda 関数の他の部分で、デフォルトの Lambda Python 環境にはない最新の AWS サービス更新が必要な場合は、このステップを実行し、最新の Boto3 SDK リリースを関数のレイヤーとして追加してください。

まず、Boto3 SDK を含む .zip ファイルアーカイブを作成します。次にレイヤーを作成し、.zip ファイルアーカイブをそのレイヤーに追加します。詳細については、「Lambda 関数でのレイヤーの使用」を参照してください。

レイヤーを作成するには (コンソール)
  1. コマンドプロンプトを開き、次のコマンドを使用します。

    pip install boto3 --target python/. zip boto3-layer.zip -r python/
  2. zip ファイル (boto3-layer.zip) の名前を書き留めておきます。これはステップ 6 で必要になります。

  3. AWS Lambda コンソール (https://console.aws.amazon.com/lambda/) を開きます。

  4. ナビゲーションペインで [レイヤー] を選択します。

  5. [レイヤーの作成] を選択します。

  6. [名前][説明] の値を入力します。

  7. [.zip ファイルをアップロード][アップロード] の順に選択します。

  8. この手順のステップ 1 で作成した.zip ファイルアーカイブ (boto3-layer.zip) を、ダイアログボックスで選択します。

  9. 互換性のあるランタイムについては、Python 3.9 を選択してください。

  10. [作成] を選択してレイヤーを作成します。

  11. ナビゲーションペインのメニューアイコンを選択します。

  12. ナビゲーションペインで、[関数] を選択します。

  13. リソースリストの中から、ステップ 1: AWS Lambda 関数を作成する (コンソール)で作成した関数を選択します。

  14. [コード] タブを選択します。

  15. [レイヤー] セクションで、[レイヤーの追加] を選択します。

  16. [カスタムレイヤー] を選択します。

  17. [カスタムレイヤー] で、ステップ 6 で入力したレイヤー名を選択します。

  18. [バージョン] では「1」を選択します。

  19. [追加] を選択します。

ステップ 3: Python コードを追加する (コンソール)

このステップでは、Lambda コンソールのコードエディタを使用して、Lambda 関数に Python コードを追加します。このコードはDetectCustomLabels を使って、提供されたイメージを分析し、イメージ内のラベルのリストを返します。イメージは Amazon S3 バケットに置くか、または byte64 暗号化イメージのバイトとして提供することもできます。

Python コードを追加するには (コンソール)
  1. Lambda コンソールを使用していない場合は、次の手順を実行します。

    1. AWS Lambda コンソール (https://console.aws.amazon.com/lambda/) を開きます。

    2. ステップ 1: AWS Lambda 関数を作成する (コンソール)で作成した Lambda 関数を開きます。

  2. [コード] タブを選択します。

  3. [コードソース] で、lambda_function.py のコードを次のコードに置き換えます。

    # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 """ Purpose An AWS lambda function that analyzes images with an the Amazon Rekognition Custom Labels model. """ import json import base64 from os import environ import logging import boto3 from botocore.exceptions import ClientError # Set up logging. logger = logging.getLogger(__name__) # Get the model ARN and confidence. model_arn = environ['MODEL_ARN'] min_confidence = int(environ.get('CONFIDENCE', 50)) # Get the boto3 client. rek_client = boto3.client('rekognition') def lambda_handler(event, context): """ Lambda handler function param: event: The event object for the Lambda function. param: context: The context object for the lambda function. return: The labels found in the image passed in the event object. """ try: # Determine image source. if 'image' in event: # Decode the image image_bytes = event['image'].encode('utf-8') img_b64decoded = base64.b64decode(image_bytes) image = {'Bytes': img_b64decoded} elif 'S3Object' in event: image = {'S3Object': {'Bucket': event['S3Object']['Bucket'], 'Name': event['S3Object']['Name']} } else: raise ValueError( 'Invalid source. Only image base 64 encoded image bytes or S3Object are supported.') # Analyze the image. response = rek_client.detect_custom_labels(Image=image, MinConfidence=min_confidence, ProjectVersionArn=model_arn) # Get the custom labels labels = response['CustomLabels'] lambda_response = { "statusCode": 200, "body": json.dumps(labels) } except ClientError as err: error_message = f"Couldn't analyze image. " + \ err.response['Error']['Message'] lambda_response = { 'statusCode': 400, 'body': { "Error": err.response['Error']['Code'], "ErrorMessage": error_message } } logger.error("Error function %s: %s", context.invoked_function_arn, error_message) except ValueError as val_error: lambda_response = { 'statusCode': 400, 'body': { "Error": "ValueError", "ErrorMessage": format(val_error) } } logger.error("Error function %s: %s", context.invoked_function_arn, format(val_error)) return lambda_response
  4. [デプロイ] を選択して、作成した Lambda 関数をデプロイします。

ステップ 4: Lambda 関数をテストする

このステップでは、コンピュータ上の Python コードを使って、ローカルイメージまたは Amazon S3 バケット内のイメージを Lambda 関数に渡します。ローカルコンピュータが渡すイメージは 6291456 バイト未満である必要があります。イメージがそれより大きい場合は、イメージを Amazon S3 バケットにアップロードし、イメージへの Amazon S3 パスを使ってスクリプトを呼び出します。バケットへのファイルのアップロードに関する詳細については、「Amazon S3 へのオブジェクトのアップロード」を参照してください。

必ず Lambda 関数を作成したのと同じ AWS リージョンでコードを実行します。作成した Lambda 関数の AWS リージョンは、Lambda コンソールにある関数の詳細ページのナビゲーションバーで確認できます。

AWS Lambda 関数がタイムアウトエラーを返す場合は、Lambda 関数のタイムアウト期間を延長します。詳細については、「関数のタイムアウトの設定 (コンソール)」を参照してください。

お使いのコードから Lambda 関数を呼び出す方法の詳細については、「AWS Lambda 関数 の呼び出し」を参照してください。

Lambda 関数をテストするには
  1. lambda:InvokeFunction の権限があることを確認してください。以下のポリシーを使用できます。

    { "Version": "2012-10-17", "Statement": [ { "Sid": "InvokeLambda", "Effect": "Allow", "Action": "lambda:InvokeFunction", "Resource": "ARN for lambda function" } ] }

    Lambda 関数の ARN は、Lambda コンソールにある [関数の概要] から取得できます。

    アクセスを提供するには、ユーザー、グループ、またはロールにアクセス許可を追加します。

  2. Python 用 AWS SDK をインストールして設定します。詳細については「ステップ 4: AWS CLI と AWS SDKsを設定する」を参照してください。

  3. ステップ 1: AWS Lambda 関数を作成する (コンソール)のステップ 7 で指定したモデルを起動します。

  4. 次のコードを client.py という名前を付けて保存します。

    # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 """ Purpose Test code for running the Amazon Rekognition Custom Labels Lambda function example code. """ import argparse import logging import base64 import json import boto3 from botocore.exceptions import ClientError logger = logging.getLogger(__name__) def analyze_image(function_name, image): """Analyzes an image with an AWS Lambda function. :param image: The image that you want to analyze. :return The status and classification result for the image analysis. """ lambda_client = boto3.client('lambda') lambda_payload = {} if image.startswith('s3://'): logger.info("Analyzing image from S3 bucket: %s", image) bucket, key = image.replace("s3://", "").split("/", 1) s3_object = { 'Bucket': bucket, 'Name': key } lambda_payload = {"S3Object": s3_object} # Call the lambda function with the image. else: with open(image, 'rb') as image_file: logger.info("Analyzing local image image: %s ", image) image_bytes = image_file.read() data = base64.b64encode(image_bytes).decode("utf8") lambda_payload = {"image": data} response = lambda_client.invoke(FunctionName=function_name, Payload=json.dumps(lambda_payload)) return json.loads(response['Payload'].read().decode()) def add_arguments(parser): """ Adds command line arguments to the parser. :param parser: The command line parser. """ parser.add_argument( "function", help="The name of the AWS Lambda function that you want " \ "to use to analyze the image.") parser.add_argument( "image", help="The local image that you want to analyze.") def main(): """ Entrypoint for script. """ try: logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s") # Get command line arguments. parser = argparse.ArgumentParser(usage=argparse.SUPPRESS) add_arguments(parser) args = parser.parse_args() # Get analysis results. result = analyze_image(args.function, args.image) status = result['statusCode'] if status == 200: labels = result['body'] labels = json.loads(labels) print(f"There are {len(labels)} labels in the image.") for custom_label in labels: confidence = int(round(custom_label['Confidence'], 0)) print( f"Label: {custom_label['Name']}: Confidence: {confidence}%") else: print(f"Error: {result['statusCode']}") print(f"Message: {result['body']}") except ClientError as error: logging.error(error) print(error) if __name__ == "__main__": main()
  5. コードを実行します。コマンドライン引数には、Lambda 関数名と分析するイメージを指定します。ローカルイメージへのパス、または Amazon S3 バケットに保存したイメージへの S3 パスを指定できます。例:

    python client.py function_name s3://bucket/path/image.jpg

    イメージが Amazon S3 バケットにある場合は、ステップ 1: AWS Lambda 関数を作成する (コンソール)のステップ 15 で指定したバケットと同じであることを確認してください。

    成功すると、イメージ内のラベルのリストが出力されます。ラベルが返されない場合は、ステップ 1: AWS Lambda 関数を作成する (コンソール)のステップ 7 で設定した「信頼度」の値を下げてみてください。

  6. Lambda 関数を使用し終わり、そのモデルが他のアプリケーションで使用中でない場合は、モデルを停止します。次回 Lambda 関数を使用するときには、必ずモデルを起動してください。