14
6

More than 3 years have passed since last update.

OpenCVとRaspberry Piでマスクの装着状況を検知する

Last updated at Posted at 2020-11-09

概要

  • 以前、アート作品の鑑賞状況をOpenCVを使って可視化することを行った
    https://qiita.com/cami_oshimo/items/ce33491c07f9625ed121

  • これを応用して、目ではなく口の検知に変更すれば、マスクを装着の判断に使えるのではと考えた。

  • まずは単純に口が露出しているかを判定して、マスクをしているかの判断を行ってみる。

IMG_0076.JPG

IMG_0077.JPG

用意するもの

  • 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

スクリーンショット 2020-11-08 10.30.24.png

スクリーンショット 2020-11-08 10.32.13.png

課題

  • 外的要因で検出が難しい場合がある。(顔との距離、角度、光量など)逆光でノイズが入り検出不能となったためカーテンを締め切っている
  • マスクの種類・装着の仕方によっては、顔と検出されない場合がある。
  • 口検出のカスケードファイルが原因なのか、口以外の場所が口と認識される場合がある。カスケードファイルは修正できるようなので、時間をかけてチューニングすれば解決できる可能性あり。
  • 顔と認識→口の有無を認識するロジックとなっているため、そもそも顔を認識させるようにさせないといけない。口の認識のみのロジックを試したが、うまく動作しなかった。(OpenCVの問題?)
  • 描画の遅延が目立つ、RaspberryPi 4でどの程度パフォーマンスが上がるのか興味がある。
14
6
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
6