Day 37 - 在 AWS Lambda 建立 OpenCV Layer

Day 37 - 在 AWS Lambda 建立 OpenCV Layer

因为 OpenCV 在影像视觉中时常需要用到,所以现在尝试在 AWS Lambda 中建立一层 OpenCV ,并将 Day 12 - 标签图片的方法与实作 这个练习,在 AWS Lambda 上完成。操作的流程如下:

  1. 打包 Python 的 OpenCV 函式库
  2. 在 AWS Lambda 建立 OpenCV 层
  3. 打包程序以及图片上传到 S3
  4. 在 AWS Lambda 执行

步骤 1.打包 Python 的 OpenCV 函式库

这个动作很重要,务必要在 Linux 环境下完成这个操作,不可以在 Windows/macOS,因为都会执行失败,推论可能是因为 AWS Lambda 上执行 OpenCV 的 Container 是 Linux-based,但是这又很奇怪的是,其他 Python 的函式不会有这个问题。

登录 Amazon Linux 2 的主机,执行下列程序,主要的操作内容是:

  • 创建一个新的 Python 虚拟环境
  • 检查 Python 版本
  • 更新 pip
  • 安装 opencv
  • 将安装好的套件压缩到 python 这个目录下
  • 检视压缩内容
python3 -m venv opencv
cd opencv
. bin/activate
python -V
pip install pip -U
pip install opencv-python
cd lib/python3.7/
ln -s site-packages/ python
zip -r opencv37-45.zip python/
unzip -l opencv37-45.zip

目前这个压缩包是针对 Python 3.7 且 opencv 的版本是 4.5.3.56,numpy 是 opencv 的相依包,所以会一并被安装进来,整个档案的大小是 72 MB左右

https://ithelp.ithome.com.tw/upload/images/20211110/20129510OL7z4hFP8b.png
图 1、Python OpenCV 压缩包的相关版本

接着直接上传压缩档到 S3,记得需要先完成 aws configure 的使用者认证。

aws s3 cp opencv37-45.zip s3://[S3存储桶的名称]

https://ithelp.ithome.com.tw/upload/images/20211110/20129510qBf7Jsu4wB.png
图 2、Python OpenCV 压缩包上传到 S3

步骤 2.在 AWS Lambda 建立 OpenCV 层

进入 AWS Lambda 管理控制台,选择建立 Layer,输入 Layer 名称,并上传先前建立的压缩档,在选择相容架构 x86_64,而相容的执行时间指的是希望可以在哪些版本的 python 中执行,只能选择 Python 3.7 ,选其他版本会出错,确定後按下 建立 键即完成建立 Layer,如下图所示。

https://ithelp.ithome.com.tw/upload/images/20211110/20129510L6uMJwZR6O.png
图 3、建立 OpenCV Layer 设定画面

步骤 3.打包程序以及图片上传到 S3

登录 EC2 ,创建一个目录,并将相关档案放入该目录中,压缩後上传到 S3 存储桶内,相关指令如下, yoloDrawLabel.py 这个程序码请参考 Day 12 - 标签图片的方法与实作

# 建立 lambda 专属目录,目录名称没有强制要求
mkdir lambda 
cd lambda 
# 产生使用 opencv 的程序码
vi yoloDrawLabel.py
mkdir labels images
# 上传标签所需要的图片与标签档
aws s3 cp s3://[S3存储桶的名称]/00-frame-608x608-0001.jpg ./images
aws s3 cp s3://[S3存储桶的名称]/00-frame-0001.txt ./labels
# 执行程序,确保可以在虚拟环境中执行
python yoloDrawLabel.py
# 将所需要档案压缩并上传到 S3
zip -r lambda.zip .
aws s3 cp lambda.zip s3://[S3存储桶的名称]

下图为 EC2 执行画面。

https://ithelp.ithome.com.tw/upload/images/20211110/20129510QmCuLb5Bmp.png
图 4、在 EC2 中建立 Lambda 压缩档

./yoloDrawLabel.py

import cv2

# 设定输入与输出
inputLabelPath = './labels/00-frame-0001.txt'
inputImgPath = './images/00-frame-608x608-0001.jpg'
outputImgPath = './labels/00-frame-608x608-0001.jpg'
# 图片大小固定为 608*608
img_w= img_h = 608
# 载入图片
cv2image = cv2.imread(inputImgPath)

with open(inputLabelPath) as f:
  for line in f:
    line = line.strip() # 删除多余的空白
    data = line.split() # 将 YOLO 一列的内容转成一维阵列
    # 将 YOLO 格式转换为边界框的左上角和右下角座标
    bbox_width = float(data[3]) * img_w
    bbox_height = float(data[4]) * img_h
    center_x = float(data[1]) * img_w
    center_y = float(data[2]) * img_h
    min_x, min_y = center_x - (bbox_width / 2), center_y - (bbox_height / 2)
    max_x, max_y = center_x + (bbox_width / 2), center_y + (bbox_height / 2)
    print(min_x,min_y,max_x,max_y)
    # 在图片上写上物件名称
    cv2.putText(cv2image, 'Altolamprologus compressiceps', (int(min_x), int(min_y-6)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 255), 1, cv2.LINE_AA)
    # 画出边界框
    cv2.rectangle(cv2image, (int(min_x),int(min_y)), (int(max_x),int(max_y)), (0,255,255), 2)
    # 将档案另存新图片档
    cv2.imwrite(r'{}'.format(outputImgPath), cv2image)
  f.close()

步骤 4.在 AWS Lambda 执行

进入 AWS Lambda 管理控制台,选择建立 Lambda 函数,设定内容如下图所示。

  • 选择下列选项之一来建立您的函式: 从头开始撰写
  • 函式名称: opencv45Func
  • 执行时间: Python 3.7 (注意:这个选项不能选其他的 Python 版本,会出现错误的)
  • 架构: x86_64
  • 执行角色: 建立具备基本 Lambda 许可的新角色

https://ithelp.ithome.com.tw/upload/images/20211110/20129510OCxuBShTVU.png
图 5、建立 Lambda 函数设定画面

建立 Lambda 函数後,选择进入 opencv45Func 函数的设定画面,在画面的最底端,为本函数新建 Layer,如下图所示。

https://ithelp.ithome.com.tw/upload/images/20211110/20129510C3XYKqa0lB.png
图 6、为 Lambda 函数新增 Layer

进入新增 Layer 画面後,选择层来源为 自订 Layer,接着选择先前建立的 opencv45 函式库层,如下图所示。

https://ithelp.ithome.com.tw/upload/images/20211110/20129510UqYLHALQ0k.png
图 7、选择 opencv45 函式库层

上传程序码
我们已经把 Lambda 函数代码上传到 S3 ,只需在函数设定主画面的右边,可以找到一个 上传於 按钮,点击後选择 Amazon S3 位置,就可以指定位置,如 https://[S3存储桶的名称].s3.ap-southeast-1.amazonaws.com/lambda.zip,画面如下所示。

https://ithelp.ithome.com.tw/upload/images/20211110/20129510mbbjoBs5vV.png
图 8、使用 S3 压缩档建立 Lambda 函数

打开 yoloDrawLabel.py 档案,插入 AWS Lambda 的呼叫函数 handler ,修改完毕後记得点击 Deploy,如下图所示。

https://ithelp.ithome.com.tw/upload/images/20211110/20129510ITzz6d92e0.png
图 9、修改 Lambda 函数

拉到画面下方,修改 执行时间设定,将 处理常式 指定为 yoloDrawLabel.handler,如下图所示。

https://ithelp.ithome.com.tw/upload/images/20211110/20129510FA2QvC53c5.png
图 10、修改执行时间设定中的处理常式

透过点击 Test 来执行 AWS Lambda 函数,第一次执行需要设定测试组态,不需任何更改,只需给定名称即可。接着再点击後,就会出现执行结果,输出结果与在 EC2 上相同,输出方块框的左上角与右下角座标,如下图所示。证明了 OpenCV 层已经正常运作。

https://ithelp.ithome.com.tw/upload/images/20211110/20129510mtKcmn8KJ8.png
图 11、执行 AWS Lambda 函数

参考资料


<<:  企业资料通讯Week7 (2) | rdt(reliable data transfer)[下]

>>:  电路级(Circuit-level)授权策略不是常见的服务网格授权策略类型

Day 13 CSS <属性书写顺序 & 网页布局-标准布局>

CSS属性书写顺序建议 建议遵循以下顺序 1. 布局定位属性 : display / positio...

画一个三角形(上)

大家好,我是西瓜,你现在看到的是 2021 iThome 铁人赛『如何在网页中绘制 3D 场景?从 ...

Transactions (4) - Concurrent Write

Preventing Lost Update 昨天讲的快照隔离优雅的解决了 read-skew 的问...

变更管理和变更控制(Change Management and Change Control)

什麽是变化,我们在变化什麽? 当涉及到更改时,至关重要的是定义什麽是更改并阐明我们正在更改的内容。...

CMoney菁英软件工程师战斗营之游戏专题发表_Week 10

阿罗哈~ 现在心情之放松 原因是游戏专题告一段落拉 排名会在下周公布 保佑我们可以在中间以上的名次就...