導入
昨今の情勢でマスクの着用の有無を気にする人々が増えた。
今回はマスクの着用の有無を簡単に判定できるプログラムを紹介する。
内容
マスクの着用の有無の判定は以下二つの手法が考えられる。
- マスク着用の有無のデータそれぞれを学習したモデルで判定
- opencvを用いて判定
今回は簡単のため2を採用する。
opencvにおいてマスクの着用のプログラムの方針は以下である。
ここで、画像内には必ず顔が一つ写っていると仮定する。
- opencvで画像内の顔を検出
- 判定された顔領域内において、opencvで口を検出
- 顔が検出できない場合または口が検出できない場合はマスクを着用、口がある場合はマスク未着用と判定
実用化を考えた場合は、顔を検出できない場合は判定不可とするべきである。
今回はマスクによって顔が隠れたため顔が検出できないと仮定した。
それぞれの検出はcascade
のdetectMultiScale()
を用いる。
また顔が検出された場合及び口が検出された場合に、それらが正しく検出されたかを確認するために画像内にバウンディングボックスの描画を行う。
バウンディングボックスはcv2.rectangle()
で簡単に描画可能である。
ここで口の検出は以下のように偽陽性が多い。
プログラム
import cv2
import numpy as np
def detection_mask(img_path):
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
mouth_cascade = cv2.CascadeClassifier('haarcascade_mcs_mouth.xml')
img = cv2.imread(img_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
mask_flag = True
if len(faces) > 0:
(x,y,w,h) = faces[0] #最初の一人
roi_gray = gray[y:y+h, x:x+w]
roi_color = img[y:y+h, x:x+w]
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
tmp_mouth = mouth_cascade.detectMultiScale(roi_gray)
if len(tmp_mouth) > 0:
#tmp_mouth_len = len(tmp_mouth)
tmp_mouth = tmp_mouth[np.argsort(tmp_mouth[:, 1])]
(mx,my,mw,mh) = tmp_mouth[-1] #口候補のうち一番下にあるもの
cv2.rectangle(roi_color,(mx,my),(mx+mw,my+mh),(0,255,255),2)
mask_flag = False
if mask_flag:
print('mask!!')
else:
print('no mask!!')
cv2.imshow("Image", img)
cv2.waitKey(5000)
cv2.destroyAllWindows()