Lambda+API Gatewayで複数画像を連携する

API Gatewayを用いて複数画像を連携したい場合の処理方法について備忘録として記しておく。 クライアントから1つの画像を受け取り、3種類の色変え処理をした画像を返すといった処理をサンプルコードとして記述する。

サンプルコード

この画像を
f:id:fourthgrd:20200808170729j:plain:w200
次の3パターンに色変えする。
f:id:fourthgrd:20200808171901j:plain:w200 f:id:fourthgrd:20200808172035j:plain:w200 f:id:fourthgrd:20200808172109j:plain:w200

APIとして複数画像を連携する場合は、クライアント、サーバ間でbase64エンコードした形でbodyに埋め込めばいい。lambdaのコードがこちら

import base64
import json

import cv2
import numpy as np

def handler(event, context):
    #パラメータを受け取る
    body = json.loads(event['body'])
    file_type = body['file_type']
    image_base64 = body['image_base64']

    #base64のデータをcv2のBGRデータに変換
    nparr = np.fromstring(base64.b64decode(body['image_base64']), np.uint8)
    bgr = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
    
    #BGRからHSVに変換
    hsv = cv2.cvtColor(bgr, cv2.COLOR_BGR2HSV)
    
    #色変え処理を実行
    chg_hue_ptns = [30,130,160]
    chged_col_imgs = []
    for chg_hue_ptn in chg_hue_ptns:
        hsv_chg = np.copy(hsv)
        hsv_chg[:, :, 0] = np.where((hsv[:, :, 0] >= 90)&(hsv[:, :, 0] < 100),
                                    chg_hue_ptn,
                                    hsv_chg[:, :, 0])
        chged_col_imgs.append(cv2.cvtColor(hsv_chg, cv2.COLOR_HSV2BGR))
    
    #BGRをbase64に変更
    base64_imgs = []
    for chged_col_img in chged_col_imgs:
        result, dst_data = cv2.imencode('.'+file_type, chged_col_img)
        base64_imgs.append(base64.b64encode(dst_data).decode('utf-8'))
    
    return {
        'statusCode': 200,
        'body': json.dumps({'imgs':base64_imgs}),
        'headers': {'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*'}
    }

API Gatewayペイロードサイズは最大10Mなのでその点は注意が必要。 docs.aws.amazon.com

参考

[Python3] 画像をBase64にエンコード、Base64をNumPy配列へ読み込みOpenCVで処理、画像データをBase64に変換 - Qiita

AWS Lambda (Python 3.7) 向けに OpenCV 3.4 & NumPy の Lambda Layers をビルドする - Qiita