エアガン測定

エアガンに関する色々を測定したりしなかったりしています http://www.eonet.ne.jp/~daisaku-tech/index.html

USBカメラの映像の背景差し替え

USBカメラの映像の背景を、指定した画像ファイルに置き換えてみました。

youtu.be

googleによるセマンティックセグメンテーションDeepLabV3+を使用しました。次のところの、Keras版を使用しました。

GitHub - bonlime/keras-deeplab-v3-plus: Keras implementation of Deeplab v3+ with pretrained weights

使用したPCのスペックは次の通り。

使用したライブラリなど。

このQiitaの記事を参考にさせていただきました。

keras-deeplab-v3-plusで人だけとってみる(ソース有り) - Qiita

プログラムは次の通り。

# -*- coding: utf-8 -*-
"""
背景差し替えプログラム
USBカメラの映像で、人物以外の背景を指定した画像ファイルに差し替えます。
引数に差し替えたい背景画像ファイル名をしてしてください。

$ python vwall.py 背景画像ファイル名

必要なライブラリ
python(3.6以上)
opencv(4.x)
tensorflow(1.13.1)またはtensorflor-gpu(1.13.1)
keras(2.2.4)
Keras版DeepLabV3+(2020年5月のリポジトリで、tensorflow 1.x用ブランチ)
https://github.com/bonlime/keras-deeplab-v3-plus
"""
import cv2
import numpy as np
import model
from keras.applications.mobilenetv2 import preprocess_input
import sys

if len(sys.argv) < 2:
    print("壁紙ファイル名を指定してください。")
    sys.exit(1)
    
wallfile = sys.argv[1]

def inference(model_dlv3, img):
    """
    推論実施
    :param model_dlv3: DeepLabV3のモデル
    :param img: カメラからの入力画像
    :return: 人物部分のマスク画像
    """
    img = np.array(img, dtype='float32')
    img = preprocess_input(img)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    img = cv2.resize(img, (512, 512))
    predicted = model_dlv3.predict(img[np.newaxis, ...])
    person_score = predicted[0, :, :, 15]
    back_score = predicted[0, :, :, 0]
    mask = (person_score > back_score).astype("uint8") * 255
    mask = cv2.resize(mask, (640, 480))

    return mask

def main():
    wall = cv2.imread(wallfile)
    wall = cv2.resize(wall, (640, 480))
    
    cap = cv2.VideoCapture(0)
    model_dlv3 = model.Deeplabv3()

    while(cap.isOpened()):
        img_camera = cap.read()[1]
        img_camera = cv2.resize(img_camera, (640, 480))
        mask = inference(model_dlv3, img_camera)
        mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
        n_mask = cv2.bitwise_not(mask)
        wall_mask = cv2.bitwise_and(wall, n_mask)
        person = cv2.bitwise_and(img_camera, mask)
        output = cv2.bitwise_or(person, wall_mask)

        cv2.imshow("camera input", img_camera)
        cv2.imshow("output", output)
        
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    cap.release()
    cv2.destroyAllWindows()


if __name__ == '__main__':
    main()