概要
-
以前、アート作品の鑑賞状況をOpenCVを使って可視化することを行った
https://qiita.com/cami_oshimo/items/ce33491c07f9625ed121 -
これを応用して、目ではなく口の検知に変更すれば、マスクを装着の判断に使えるのではと考えた。
-
まずは単純に口が露出しているかを判定して、マスクをしているかの判断を行ってみる。
用意するもの
- Raspberry Pi3 Model B (4でもおそらく大丈夫)
- Raspberry Pi用のケース
- Raspberry Pi用のヒートシンク
- Raspberry Pi3 Model B B+ 対応 電源セット(5V 3.0A)
- aspberry Pi用のカメラ
- HDMI入力が付いたモニター
- 100円ショップの三脚
※VNCを使ってPCからRaspberry Piをリモート操作すると開発が楽になる
準備
- RaspberryPiのセットアップを行う。
- RaspberryPiのカメラが使用できる状態にしておく。
https://www.raspberrypi.org/downloads/ - OpenCVのライブラリ、カスケードファイルが使用できるようにしておく。
haarcascade_frontalface_default.xml (顔検出)
haarcascade_mcs_mouth.xml (口検出)
プログラミング
- 顔をフレームインするよう促すメッセージ、顔・口検出のフレーム、マスク非装着時の警告をカメラ映像にオーバーレイ表示する。
- 顔と検出され、かつ口が検出された場合にマスク非装着と判定する。
import sys
sys.path.append('/home/pi/.local/lib/python2.7/site-packages')
import numpy as np
import cv2
import time
import datetime
import ambient
args = sys.argv
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
mouth_cascade = cv2.CascadeClassifier('haarcascade_mcs_mouth.xml')
cap = cv2.VideoCapture(0)
while(True):
ret, frame = cap.read()
height = frame.shape[0]
width = frame.shape[1]
import sys
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
cv2.putText(frame, 'Please face in frame.', (350, 20), cv2.FONT_HERSHEY_PLAIN, 1.5, (0,255,0), thickness=2)
for (x,y,w,h) in faces:
roi_gray = gray[y:y+h, x:x+w]
roi_color = frame[y:y+h, x:x+w]
cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
mouth = mouse_cascade.detectMultiScale(roi_gray)
for (ex,ey,ew,eh) in mouth:
cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,255),2)
cv2.putText(frame, 'Not masked!!', (10, 460), cv2.FONT_HERSHEY_DUPLEX, 1.0, (0,0,255), thickness=2)
resized_img = cv2.resize(frame,(width*2, height*2))
cv2.imshow('maskcheck', resized_img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
- RaspberryPiのデスクトップにシェルスクリプトを設置し、Pythonのプログラムが起動するようにしておく。
- アイコンのダブルクリックで起動するようにしておく。
maskcheck.sh
#! /bin/bash
cd /home/pi/opencv_programs/
sudo python3 detect_face_camera.py
課題
- 外的要因で検出が難しい場合がある。(顔との距離、角度、光量など)逆光でノイズが入り検出不能となったためカーテンを締め切っている
- マスクの種類・装着の仕方によっては、顔と検出されない場合がある。
- 口検出のカスケードファイルが原因なのか、口以外の場所が口と認識される場合がある。カスケードファイルは修正できるようなので、時間をかけてチューニングすれば解決できる可能性あり。
- 顔と認識→口の有無を認識するロジックとなっているため、そもそも顔を認識させるようにさせないといけない。口の認識のみのロジックを試したが、うまく動作しなかった。(OpenCVの問題?)
- 描画の遅延が目立つ、RaspberryPi 4でどの程度パフォーマンスが上がるのか興味がある。