「レジなし無人冷蔵庫」回転台で撮影した動画から背景が透過された商品画像を作成してみました

2020.10.30

1 はじめに

CX事業本部の平内(SIN)です。

Amazon Web Services ブログでは、「レジなし無人販売冷蔵庫を構築についての記事」が公開されています。
レジなし無人販売冷蔵庫を構築できる、This is my Smart Cooler プログラムを公開しました

こちらでは、「お客様自らがレジなし無人販売冷蔵庫を迅速に構築し学習や体験ができる This is my Smart Cooler プログラムを発表します。」ということで、そのレシピがGithubで公開されています。
レジ無し無人販売冷蔵庫 構築レシピ

「これを真似てみたい」ということで、ここまで作業を進めています。

前回作業した、合成画像でモデル作成を試していたのですが、やはり、元となるデータがある程度の大量に無いと、なかなか高い精度を出すのは難しいと感じています。

そこで、今回は、この元となるデータを回転台で撮影した動画から作成してみました。

最初に、データを生成している様子です。

動画で商品が写っている中央部分を切り取り、アルファチャンネルを追加して、円形のマスクで透過しています。

2 照明の調整

元データにバリエーションを持たせるため、冷蔵庫内の明るさを調整できるようにLED照明に電流制限抵抗(1Kの可変抵抗)を入れてみました。

3 動画撮影

冷蔵庫内に回転台を置いて、照明を変化させながら3回転ほどWebカメラで撮影しています。

4 コード

動画からデータを生成するコードです。

動画の総フレーム数と、指定した切取りフレーム数でインターバルを算出し、画像を保存しています。

また、画像は、最初に商品の写っている中央部分だけを切り出し、円形のマスクで背景を透過して保存しています。

import cv2
import os
import shutil
import numpy as np

inputPath = "./mp4" # 入力
outputPath = "./output" # 出力先
max = 200 # 切り取るフレーム数
CLASS_NAME = ["kyo_udon","koara","seafude","jagabee","chipstar","curry","butamen"]
# 切り取る範囲 left, top, size, radius
TARGET=[
    (175,80,240,120),
    (200,100,200,100),
    (175,80,240,120),
    (200,100,200,100),
    (200,100,200,100),
    (175,80,240,120),
    (200,100,200,100),
]

# 出力先の初期化
if os.path.exists(outputPath):
    shutil.rmtree(outputPath)
os.mkdir(outputPath)

for index, className in enumerate(CLASS_NAME):
    # 動画取得
    file = "{}/{}.mp4".format(inputPath, className)
    movie = cv2.VideoCapture(file) 
    # フレーム数取得
    frameCount = int(movie.get(cv2.CAP_PROP_FRAME_COUNT))
    # 読み飛ばすフレーム数の計算
    interval = int(frameCount/max)

    fileName = os.path.basename(file)
    className = os.path.splitext(fileName)[0]
    counter = 0
    for i in range(frameCount - 1):
        _, frame = movie.read()
        if(i % interval != 0):
            continue
        if(max <= counter):
            break

        # 出力名
        imageName = "{}_{}.png".format(className, str(counter).zfill(5))
        outputFileName = "{}/{}".format(outputPath, imageName)

        # 商品のみを切り取る
        (left, top, size, radius) = TARGET[index]
        frame = frame[top : top + size, left : left + size]
        h, w = frame.shape[:2]

        # マスク作成
        mask = np.zeros((h, w), dtype=np.uint8)
        cv2.circle(mask, center=(h/2, w/2), radius=radius, color=255, thickness=-1)

        # マスク部分を透過する
        rgba = cv2.cvtColor(frame, cv2.COLOR_RGB2RGBA)
        rgba[..., 3] = mask
        cv2.imwrite(outputFileName, rgba)

        print(outputFileName) 
        counter += 1

5 最後に

今回は、元データの作成を行ってみました。引き続き、モデルの精度が上がるように調整を進めます。

「レジなし無人販売冷蔵庫」は、難しいです。道のりは、遠いです。