LoginSignup
7
8

More than 3 years have passed since last update.

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

Posted at

はじめに

AWS Lambda で OpenCV を使用するにはいくつかの方法がある。

  • Lambda 関数のデプロイパッケージに OpenCV を含める
  • OpenCV 用の Lambda Layers をビルドして使用する

前者の「Lambda 関数のデプロイパッケージに OpenCV を含める」方法の場合は、Lambda のデプロイパッケージサイズの上限 50 MB のうち、そのほとんどが OpenCV のために使用されてしまう。後者の Lambda Layers を使用すると、ライブラリをデプロイパッケージに含める必要がなくなり、パッケージのサイズを小さくすることができる。また、ライブラリを外部化することで、OpenCV のバージョンアップなども行いやすくなると考えられる。

そこで本稿では、AWS Lambda (Python 3.7) 向けに OpenCV 3.4 の Lambda Layers をビルドし、実際にビルドした Layers を使用して OpenCV 3.4 を Lambda で動作させるまでの手順をまとめた。

OpenCV 3.4 Layer の作成

https://qiita.com/hajimen/items/4419ba0182fc6d008896 を参考に Docker を使用したビルドを行なったが、Python 3.7 と OpenCV 3.4.7 の組み合わせでは、先の記事の方法では上手くいかなかった。そこで、以下のような Dockerfile を作成した。

Dockerfile
FROM lambci/lambda:build-python3.7

ENV OPENCV_VERSION 3.4.7

RUN curl -fsSLO https://github.com/opencv/opencv/archive/$OPENCV_VERSION.tar.gz \
  && tar -zxf $OPENCV_VERSION.tar.gz \
  && mv opencv-$OPENCV_VERSION opencv

RUN curl -fsSLO https://github.com/opencv/opencv_contrib/archive/$OPENCV_VERSION.tar.gz \
  && tar -zxf $OPENCV_VERSION.tar.gz \
  && mv opencv_contrib-$OPENCV_VERSION opencv_contrib

RUN yum install -y cmake3

RUN pip install --upgrade pip && pip install numpy

RUN mkdir opencv/build \
  && cd opencv/build \
  && cmake3 \
    -DBUILD_SHARED_LIBS=NO \
    -DCMAKE_BUILD_TYPE=RELEASE \
    -DCMAKE_INSTALL_PREFIX=../../python \
    -DOPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules \
    -DPYTHON3_EXECUTABLE=/var/lang/bin/python .. \
  && make install

RUN find python/lib -name *.so | xargs -n 1 strip -s

RUN zip -ry9 cv2.zip python/lib

CMD cp cv2.zip /share

同じ要領で docker-compose.yml も作成。

docker-compose.yml
version: '2'
services:
  app:
    build:
      context: .
    volumes:
      - .:/share

この 2 個のファイルが存在するディレクトリで以下のコマンドを順に実行すると、カレントディレクトリに cv2.zip が生成される。

docker-compose build
docker-compose up

生成された cv2.zip を AWS Lambda マネジメントコンソールから Layers としてアップロードすれば完了。

動作確認

以下の Lambda 関数を作成し、AWS により用意されているレイヤー AWSLambda-Python37-SciPy1x(これに NumPy が含まれている)および上で作成した OpenCV 3.4 のレイヤーを使用するように設定し、実行した。

import numpy as np
import cv2

def lambda_handler(event, context):
    print(cv2.__version__)

その結果、以下のようなエラーが発生した。

[ERROR] Runtime.ImportModuleError: Unable to import module 'lambda_function': numpy.core.multiarray failed to import

どうやら NumPy のバージョンが古い場合に発生するエラーらしい。そこで NumPy の Layer も自作することに。

NumPy 1.17 Layer の作成

先ほどと同じ要領で以下の Dockerfile を作成した。

Dockerfile
FROM lambci/lambda:build-python3.7

RUN pip install --upgrade pip && pip install -t python numpy

RUN zip -ry9 numpy.zip python

CMD cp numpy.zip /share

このあとは OpenCV のときと同様の手順を実行すればカレントディレクトリに numpy.zip が生成されるので、これを AWS Lambda マネジメントコンソールから Layers としてアップロードすれば完了。

動作確認

以下の Lambda 関数を作成し、自作の 2 つのレイヤーを使用するように設定し、実行した。

import numpy as np
import cv2

def lambda_handler(event, context):
    print(cv2.__version__)

その結果、以下の出力を得た。

3.4.7

OpenCV のバージョンが出力されていることから、AWS Lambda (Python 3.7) で OpenCV 3.4 が正常に動作したことが確認できた。

7
8
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
7
8