・人の顔検出の手法を調べている方
・webアプリの作り方を調べている方
・streamlitの作り方を調べている方
など
少し前に、人の顔検出のアルゴリズムをPythonで比較するという記事をこのブログで紹介させていただきました。
その時はローカルのPCで実行してみて、比較を行うというものでした。
結果的にRetinaFaceのアルゴリズムが、かなり汎化性能が高かったですね。
なので、このアルゴリズムを使ってアップロードした画像中の人の顔を検出するwebアプリを作りたいと思い、実際作ってみましたので、
作り方について解説したいと思います。
作成したwebアプリ
実際に作成したアプリがこちらになります。

画面の左側に判定の閾値を調整するスライダーと、画像をアップロードするようのUIを設置しました。
メインの画面の方では、左にオリジナルの画像と右側に顔検出の結果を出力するようにしてます。
全部英語の方がなんとなくカッコいいと思って、文章は英語にしました。
作成手順
Streamlitのwebアプリ作成手順はおおまかに
- Pythonのコードを書く
- GitHubにPythonコードと使うライブラリのrequirements.txtをアップロードする
- SteamlitのCommunity cloudにGitHubのアカウントでサインインする
の手順で行います。
Pythonのコードを書く
今回のwebアプリで使用したコードは以下のようになっています。
import cv2
import streamlit as st
from PIL import Image
from io import BytesIO
import base64
from retinaface import RetinaFace
import numpy as np
st.set_page_config(layout="wide", page_title="人の顔検出")
st.write("## Face Detect App")
st.write(
":cat: Try uploading an image to detect the humanfaces. Full quality images can be downloaded from the sidebar"
)
st.write(
"This app using RetinaFace algorithm. Special thanks to the [retina-face] [here](https://github.com/serengil/retinaface)"
)
# Download the face dtect image
def convert_image(img):
buf = BytesIO()
img.save(buf, format="PNG")
byte_im = buf.getvalue()
return byte_im
def detect_face(upload):
image = Image.open(upload)
try:
cv2_img = cv2.imread(upload)
cv2_img = cv2.cvtColor(cv2_img, cv2.COLOR_BGR2RGB)
col1.write("Original Image :camera:")
col1.image(image)
except:
cv2_img=np.array(image)
#cv2_img = cv2.cvtColor(cv2_img, cv2.COLOR_BGR2RGB)
col1.write("Original Image :camera:")
col1.image(image)
#detect
resp = RetinaFace.detect_faces(cv2_img, threshold = value)
for key in resp:
identity = resp[key]
facial_area = identity["facial_area"]
cv2.rectangle(cv2_img, (facial_area
, facial_area
), (facial_area[0], facial_area
), (0, 255, 0), 2)
col2.write("Detect face Image :wrench:")
col2.image(cv2_img)
st.sidebar.markdown("\n")
st.sidebar.download_button("Download result", convert_image(Image.fromarray(cv2_img)), "result.png", "image/png")
col1, col2 = st.columns(2)
st.sidebar.write("""
## Threshold
""")
value= st.sidebar.slider(
'Range',
0.0, 1.0, value=0.7
)
st.sidebar.write("## Upload and download :gear:")
my_upload = st.sidebar.file_uploader("Upload an image", type=["png", "jpg", "jpeg"])
if my_upload is not None:
detect_face(upload=my_upload)
else:
detect_face("img3.jpg")
img3.jpgはデフォルトの集合写真を使っています。
少し厄介だったのが、OpenCVのBGRとNumpy配列の画像のRGBの変換だったでしょうか。。。
このあたりはかなりやっかいでした。
StreamlitのチュートリアルがPILを使っているので、合わせましたが
正直苦手でした。
GitHubへファイルのアップロード&Community cloudにGitHubアカウントでサインイン
この段階で大変だったのが、OpenCVがStreamlit community cloudで動かなかったことでした。。。
一応下記の困り事メモで解決はできたのですが、大変でした。。。
おわりに
ここまで読んでいただき、ありがとうございました。
こんかいのwebアプリは最後のopenCVの謎エラーのせいで、
トータルで5時間くらい作成に時間をかけて、なんとか公開までこじつけた感じです。。。
AI使ったwebアプリを個人で作ったのは初めてだったので嬉しかったです。
また何か作っていきます。
それでは。