使用 Lambda 和 Python 偵測影像中的標籤 - Amazon Rekognition

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

使用 Lambda 和 Python 偵測影像中的標籤

AWS Lambda 是一種運算服務,您可以用來執行程式碼,而無需佈建或管理伺服器。您可以從 Lambda 函數中呼叫 Rekognition API 作業。下列指示展示如何在 Python 建立 Lambda 函數,可以呼叫 DetectLabels

Lambda 函數中呼叫 DetectLabels,傳回影像中偵測到的一系列標籤,以及偵測所依據的可信度層級。

這些指示包括範例 Python 程式碼,其中示範如何呼叫 Lambda 函數,並提供來自 Amazon S3 儲存貯體或本機電腦的映像檔。

請確認您選擇的影像符合 Rekognition 的限制。如需有關影像檔案類型和大小限制的資訊,請參閱 Rekognition 中的準則和配額DetectLabels API 參考

建立 Lambda 函數 (主控台)

在此步驟中,您會建立空白的 Lambda 函數和 IAM 執行角色,讓 Lambda 函數呼叫 DetectLabels 操作。在稍後的步驟中,您可以新增原始程式碼,並選擇性地將圖層新增至 Lambda 函數。

如果您使用存放於 Amazon S3 儲存貯體中的文件,此步驟也會示範如何授與存放文件之儲存貯體的存取權。

建立 AWS Lambda 函數 (主控台)
  1. 登入 AWS Management Console ,並在 https://https://console.aws.amazon.com/lambda/ 開啟 AWS Lambda 主控台。

  2. 選擇建立函數 。如需詳細資訊,請參閱使用主控台建立 Lambda 函數

  3. 選擇下列選項:

    • 選擇從頭開始撰寫

    • 輸入函數的名稱

    • 若為執行期,請選擇最新版本的 Python。

    • 對於 Architecture (架構),選擇 x86_64

  4. 選擇建立函數來建立 AWS Lambda 函數。

  5. 在函數頁面上,選擇組態標籤。

  6. 許可窗格上,執行角色下,選擇要在 IAM 主控台中開啟角色的角色名稱。

  7. 許可標籤中,選擇新增許可 ,然後建立內嵌政策

  8. 選擇 JSON 標籤,並預設文字取代為下列內容:

    { "Version": "2012-10-17", "Statement": [ { "Action": "rekognition:DetectLabels", "Resource": "*", "Effect": "Allow", "Sid": "DetectLabels" } ] }
  9. 選擇檢閱政策

  10. 輸入原則的名稱,例如 DetectLabels 存取

  11. 選擇 建立政策

  12. 如果您要將文件存放於 Amazon S3 儲存貯體中進行分析,則必須新增 Amazon S3 存取政策。若要這麼做,請在 AWS Lambda 主控台中重複步驟 7 到 11,然後進行下列變更。

    1. 對於步驟 8,請使用下列原則。將儲存貯體/資料夾路徑取代為您要分析之文件的 Amazon S3 儲存貯體和資料夾路徑。

      { "Version": "2012-10-17", "Statement": [ { "Sid": "S3Access", "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::bucket/folder path/*" } ] }
    2. 對於步驟 10,請選擇不同的原則名稱,例如 S3Bucket-access

(可選) 建立圖層 (主控台)

您不需要執行此步驟即可使用 Lambda 函數並呼叫 DetectLabels

DetectLabels 操作包含在預設的 Lambda Python 環境中,做為適用於 Python 的 AWS SDK (Boto3) 的一部分。

如果 Lambda 函數的其他部分需要不在預設 Lambda Python 環境中的最新 AWS 服務更新,則可以執行此步驟,將最新的 Boto3 SDK 發行版本作為圖層新增至函數。

若要將 SDK 新增為圖層,您必須先建立包含 Boto3 SDK 的壓縮檔案歸檔。然後,建立一個圖層並將 zip 檔案存檔新增到圖層中。如需詳細資訊,請參閱搭配使用圖層和 Lambda 函數

建立並新增圖層(主控台)
  1. 開啟命令提示字元並輸入下列命令,以建立具有最新版本 AWS SDK 的部署套件。

    pip install boto3 --target python/. zip boto3-layer.zip -r python/
  2. 請注意您在此程序的步驟 8 中使用的壓縮檔案 (boto3-layer.zip) 的名稱。

  3. 在 https://https://console.aws.amazon.com/lambda/ 開啟 AWS Lambda 主控台。

  4. 在導覽視窗中,選擇 圖層

  5. 選擇 建立圖層

  6. 輸入 名稱描述 的值。

  7. 針對程式碼項目類型,選擇上傳 .zip 檔案並選取上傳

  8. 在對話方塊中,選擇您在此程序的步驟 1 中建立的壓縮檔案封存 (boto3-layer.zip)。

  9. 對於 相容的執行期 ,請選擇最新版本的 Python。

  10. 選擇建立,以建立資料表。

  11. 選擇導覽視窗選單圖示。

  12. 在導覽視窗中,選擇函數

  13. 在資源清單中,選擇您先前在 中建立的函數。

  14. 選取程式碼標籤。

  15. 圖層 部份,選擇 新增圖層

  16. 選擇 自訂圖層

  17. 自訂圖層中,選擇您在步驟 6 中輸入的圖層名稱。

  18. 版本中,選擇圖層版本,該版本應為 1。

  19. 選擇 新增

新增 Python 程式碼 (主控台)

在此步驟中,您可以透過 Lambda 主控台程式碼編輯器將 Python 程式碼新增至 Lambda 函數。程式碼會使用 DetectLabels 作業偵測影像中的標籤。其傳回在映像中偵測到的標籤的數組,以及偵測到的標籤的可信度水平。

您提供給 DetectLabels 作業的文件可以位於 Amazon S3 儲存貯體或本機電腦中。

若要新增 Python 程式碼 (主控台)
  1. 瀏覽至程式碼標籤。

  2. 在程式碼編輯器中,以下列程式碼取代 lambda_function.py 中的程式碼:

    import boto3 import logging from botocore.exceptions import ClientError import json import base64 # Instantiate logger logger = logging.getLogger(__name__) # connect to the Rekognition client rekognition = boto3.client('rekognition') def lambda_handler(event, context): try: image = None if 'S3Bucket' in event and 'S3Object' in event: s3 = boto3.resource('s3') s3_object = s3.Object(event['S3Bucket'], event['S3Object']) image = s3_object.get()['Body'].read() elif 'image' in event: image_bytes = event['image'].encode('utf-8') img_b64decoded = base64.b64decode(image_bytes) image = img_b64decoded elif image is None: raise ValueError('Missing image, check image or bucket path.') else: raise ValueError("Only base 64 encoded image bytes or S3Object are supported.") response = rekognition.detect_labels(Image={'Bytes': image}) lambda_response = { "statusCode": 200, "body": json.dumps(response) } labels = [label['Name'] for label in response['Labels']] print("Labels found:") print(labels) except ClientError as client_err: error_message = "Couldn't analyze image: " + client_err.response['Error']['Message'] lambda_response = { 'statusCode': 400, 'body': { "Error": client_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
  3. 若要部署您的 Lambda 函數,請選擇部署

若要新增 Python 程式碼 (主控台)

現在您已經建立 Lambda 函數,可以叫用該函數,以偵測影像中的標籤。

在此步驟中,您可以在電腦上執行 Python 程式碼,該程式碼會將本機映像或 Amazon S3 儲存貯體中的映像傳遞至 Lambda 函數。

請確定您在建立 Lambda 函數的相同 AWS 區域中執行程式碼。您可以在 AWS Lambda 主控台函數詳細資訊頁面的導覽列中檢視 Lambda 函數的區域。

如果 Lambda 函數傳回逾時錯誤,請延長 Lambda 函數的逾時期間。如需詳細資訊,請參閱設定函數逾時 (主控台)

如需從程式碼調用 Lambda 函數的更多資訊,請參閱 調用 AWS Lambda 函數

部署 Lambda 函數
  1. 如果您尚未執行以下操作,請現在執行:

    1. 請確定使用者具有 lambda:InvokeFunction 權限。您可以使用下列專案:

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

      您可以從 Lambda 主控台的函數概觀取得 Lambda 函數的 ARN。

      若要提供存取權,請新增權限至您的使用者、群組或角色:

      • 中的使用者和群組 AWS IAM Identity Center:

        建立權限合集。請按照 AWS IAM Identity Center 使用者指南 中的 建立權限合集 說明進行操作。

      • 透過身分提供者在 IAM 中管理的使用者:

        建立聯合身分的角色。遵循「IAM 使用者指南」的為第三方身分提供者 (聯合) 建立角色中的指示。

      • IAM 使用者:

    2. 安裝和設定適用於 Python 的 AWS SDK。如需詳細資訊,請參閱步驟 2:設定 AWS CLI 和 AWS SDKs

  2. 將下列程式碼複製到名為 client.py 的檔案。

    import boto3 import json import base64 import pprint # Replace with the name of your S3 bucket and image object key bucket_name = "name of bucket" object_key = "name of file in s3 bucket" # If using a local file, supply the file name as the value of image_path below image_path = "" # Create session and establish connection to client[' session = boto3.Session(profile_name='developer-role') s3 = session.client('s3', region_name="us-east-1") lambda_client = session.client('lambda', region_name="us-east-1") # Replace with the name of your Lambda function function_name = 'RekDetectLabels' def analyze_image_local(img_path): print("Analyzing local image:") with open(img_path, 'rb') as image_file: image_bytes = image_file.read() data = base64.b64encode(image_bytes).decode("utf8") lambda_payload = {"image": data} # Invoke the Lambda function with the event payload response = lambda_client.invoke( FunctionName=function_name, Payload=(json.dumps(lambda_payload)) ) decoded = json.loads(response['Payload'].read().decode()) pprint.pprint(decoded) def analyze_image_s3(bucket_name, object_key): print("Analyzing image in S3 bucket:") # Load the image data from S3 into memory response = s3.get_object(Bucket=bucket_name, Key=object_key) image_data = response['Body'].read() image_data = base64.b64encode(image_data).decode("utf8") # Create the Lambda event payload event = { 'S3Bucket': bucket_name, 'S3Object': object_key, 'ImageBytes': image_data } # Invoke the Lambda function with the event payload response = lambda_client.invoke( FunctionName=function_name, InvocationType='RequestResponse', Payload=json.dumps(event), ) decoded = json.loads(response['Payload'].read().decode()) pprint.pprint(decoded) def main(path_to_image, name_s3_bucket, obj_key): if str(path_to_image) != "": analyze_image_local(path_to_image) else: analyze_image_s3(name_s3_bucket, obj_key) if __name__ == "__main__": main(image_path, bucket_name, object_key)
  3. 執行程式碼。如果文件位於 Amazon S3 儲存貯體中,請確定该文件是與之前在 的步驟 12 中指定的相同儲存貯體。

    如果成功,您的程式碼會針對文件中偵測到的每個區塊類型傳回部分 JSON 回應。