顔認識でマスクを付けてくれるWebアプリを作成しStreamlit Sharingで公開する


作ったもの


みんな笑顔でとても楽しそうな良い写真ですね.
しかしこういう時期なのでマスクを付けてほしいところです.

そこで顔認識でマスクを付けてくれるWebアプリを作成しました.
https://share.streamlit.io/be4rr/put_mask/put_mask_streamlit.py

このリンクを開いて,この画像をアップロードすると...

みんなにマスクを付けてあげることができました🎉
これで安心ですね.

Webアプリ全体のプログラムをGitHubに上げています.
https://github.com/Be4rR/put_mask

使ったもの

主に次のようなPythonライブラリやサービスを利用しました.
- Streamlit
- Streamlit Sharing
- MTCNN

StreamlitはPythonを使って素早く簡単にWebアプリを作成できるライブラリです.特にデータ分析や機械学習のWebアプリを作るのに向いています.

Streamlit SharingはStreamlitを使って作成したWebアプリを簡単にデプロイできるサービスです.現状では誰でもすぐに使い始められるわけではないようですが,すごく便利です.

MTCNNはDeep Learningを使った顔認識がお手軽にできるPythonライブラリです.

プログラム

put_mask_streamlit.py
import numpy as np
import streamlit as st
from mtcnn import MTCNN
from PIL import Image, ImageDraw

st.title("Pythonで顔認識してマスクを付けさせる")

# 画像ファイルをアップロードするためのウィジェット
imgfile = st.file_uploader("Upload Image", type=["png", "jpg"], accept_multiple_files=False)

# 画像ファイルがアップロードされていなければ何もしない
if imgfile is not None:    
    img = Image.open(imgfile)

    # マスクのイラストの画像
    mask = Image.open("mask.png")

    # 元の画像を表示
    st.write("元の画像")
    st.image(img, use_column_width=True)

    # 画像に写っている顔を検出する
    detector = MTCNN()  
    # 検出された顔ごとに,顔のBounding Box,顔である確率,目や鼻などのKeypointsが得られる. 
    results = detector.detect_faces(np.asarray(img))

    for result in results:
        # 顔である確率
        confidence = result["confidence"]

        # 顔である確率が90%以下ならスルー
        if confidence < 0.9:
            continue

        # 顔のBounding Box
        x, y, w, h = result["box"]

        # マスクの画像を顔のサイズに合わせる.
        mask_resized = mask.resize((w, h//2)) 

        # マスクの画像を,検出された顔に貼り付ける.       
        img.paste(mask_resized, (x, y+h//2), mask_resized.convert("RGBA"))

    pil_img = Image.fromarray(np.uint8(img))

    st.write("マスクを付けた画像")
    st.image(pil_img, use_column_width=True)

MTCNNの使い方についてはGitHubに書かれています.
https://github.com/ipazc/mtcnn

Streamlit Sharingでデプロイするときのメモ

どちらかというとこっちが本題です.これはあくまでもメモ程度なので,実際に行う場合は公式の説明を見てください.
https://docs.streamlit.io/en/stable/deploy_streamlit_app.html

最初に述べたようにStreamlit Sharingは誰でもすぐに使えるというわけではないようです.Streamlit Sharingのページに書いてあるように,リクエストを送って招待を待つ必要があります.自分の場合はリクエストを送ってから3日後くらいに使えるようになりました.

次に必要なファイルについてです.実際のファイルはGitHubにあるので参考にしてください.
https://github.com/Be4rR/put_mask/

まず当然ですがStreamlitのプログラムが必要です.
https://github.com/Be4rR/put_mask/blob/master/put_mask_streamlit.py

2つ目にpipでインストールするライブラリが書かれているrequirements.txtです.公式の説明ではpipreqsというツールを使っていますが,日本語の処理でエラーが出たので今回は使っていません.通常通りpip freezeで作成しました.

pip freeze > requirements.txt

また,自分のPC環境はWindowsなのでデプロイした際にpywin32に関するエラーが出ましたが,pywin32をコメントアウトして回避しました.
https://discuss.streamlit.io/t/problem-with-heroku-on-windows-requirement-pywin32-227/2722

最後にapt-getでインストールするものを書いたpackages.txtです.
https://github.com/Be4rR/put_mask/blob/master/packages.txt

今回利用したMTCNNでは内部でOpenCVを使っています.そのため次のパッケージが必要になります.

packages.txt
freeglut3-dev
libgtk2.0-dev

おわりに

デプロイで少し試行錯誤しましたが,それでも簡単にWebアプリを作って簡単に公開できました.Streamlit Sharingには「1アカウントにつきアプリ3つまで公開できる」などの制限はあるようですが,それでも面白いものがたくさん作れそうです.