face mask detection -Pythonでマスク有無を検出-

スポンサーリンク
Python/DeepLearning

こんにちは!みやしんです。

今回は、マスク着用有無を検出するface mask detectionをご紹介します!

このブログの管理人も卒業生です。
スポンサーリンク

この記事で出来る事

マスクの着用有無をリアルタイムで確認できます。

環境構築

Githubからダウンロード

下記にアクセスしてモデルなどを一式ダウンロードできます。

GitHub - Karan-Malik/FaceMaskDetector: Real time face-mask detection using Deep Learning and OpenCV
Real time face-mask detection using Deep Learning and OpenCV - GitHub - Karan-Malik/FaceMaskDetector: Real time face-mas...

zipファイルをダウンロードできます。

解凍しましょう!

フォルダの中はこんな感じです。

Pythonのバージョン

Python 3.9.13

ライブラリのインストール

requirements.txt を使ってそのままインストールしようとしたらエラーがたくさん出ました。requirements.txtを下記の内容に修正(コピペでOK!)してからpipインストールしてください。

absl-py==0.11.0
astunparse==1.6.3
cached-property==1.5.2
cachetools==4.2.0
certifi==2020.12.5
chardet==4.0.0
DateTime==4.3
flatbuffers==1.12
gast==0.4.0
google-auth==1.24.0
google-auth-oauthlib==0.4.2
google-pasta==0.2.0
grpcio==1.34.0
h5py==3.1.0
idna==2.10
importlib-metadata==3.3.0
Keras==2.4.3
Keras-Preprocessing==1.1.2
Markdown==3.3.3
numpy==1.19.4
oauthlib==3.1.0
opencv-python==4.4.0.46
opt-einsum==3.3.0
protobuf==3.14.0
pyasn1==0.4.8
pyasn1-modules==0.2.8
pyspark==3.0.1
pytz==2020.5
PyYAML==5.4
requests==2.25.1
requests-oauthlib==1.3.0
rsa==4.7
scipy==1.5.4
six==1.15.0
tensorboard==2.5.0
tensorboard-plugin-wit==1.7.0
tensorflow==2.5.0
tensorflow-estimator==2.5.0rc0
termcolor==1.1.0
typing-extensions==3.7.4.3
urllib3==1.26.5
Werkzeug==1.0.1
wincertstore==0.2
wrapt==1.12.1
zipp==3.4.0
zope.interface==5.2.0

下記を変更しています。

gast==0.3.3 => 0.4.0
grpcio==1.32.0 => 1.34.0
tensorboard==2.4.0 => 2.5.0
h5py==2.10.0 => 3.1.0
tensorflow-estimator==2.4.0 => 2.5.0rc0

書き換えたらpipインストールします。

pip install -r requirements.txt

コード修正 facemask.py

AttributeError: module ‘keras.preprocessing.image’ has no attribute ‘load_img’

メインのスクリプト(facemask.py)をそのまま実行するとAttributeErrorになったのでコードを修正しました。具体的には「image.load_img」「keras.utils.load_img」に変更しています。

facemask.pyを下記のように修正してください。(コピペでOK!)

# -*- coding: utf-8 -*-

import numpy as np
import keras
import keras.backend as k
from keras.layers import Conv2D,MaxPooling2D,SpatialDropout2D,Flatten,Dropout,Dense
from keras.models import Sequential,load_model
from keras.optimizers import Adam
from keras.preprocessing import image
import cv2
import datetime


# UNCOMMENT THE FOLLOWING CODE TO TRAIN THE CNN FROM SCRATCH

# BUILDING MODEL TO CLASSIFY BETWEEN MASK AND NO MASK

model=Sequential()
model.add(Conv2D(32,(3,3),activation='relu',input_shape=(150,150,3)))
model.add(MaxPooling2D() )
model.add(Conv2D(32,(3,3),activation='relu'))
model.add(MaxPooling2D() )
model.add(Conv2D(32,(3,3),activation='relu'))
model.add(MaxPooling2D() )
model.add(Flatten())
model.add(Dense(100,activation='relu'))
model.add(Dense(1,activation='sigmoid'))

model.compile(optimizer='adam',loss='binary_crossentropy',metrics=['accuracy'])

from keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(
        rescale=1./255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True)

test_datagen = ImageDataGenerator(rescale=1./255)

training_set = train_datagen.flow_from_directory(
        'train',
        target_size=(150,150),
        batch_size=16 ,
        class_mode='binary')

test_set = test_datagen.flow_from_directory(
        'test',
        target_size=(150,150),
        batch_size=16,
        class_mode='binary')

model_saved=model.fit_generator(
        training_set,
        epochs=10,
        validation_data=test_set,

        )

model.save('mymodel.h5',model_saved)

#To test for individual images

mymodel=load_model('mymodel.h5')
#test_image=image.load_img('C:/Users/Karan/Desktop/ML Datasets/Face Mask Detection/Dataset/test/without_mask/30.jpg',target_size=(150,150,3))
#test_image=image.load_img(r'C:/Users/karan/Desktop/FaceMaskDetector/test/with_mask/1-with-mask.jpg',
#                          target_size=(150,150,3))
#test_image=keras.utils.load_img(r'C:/Users/karan/Desktop/FaceMaskDetector/test/with_mask/1-with-mask.jpg',
#                          target_size=(150,150,3))
test_image=keras.utils.load_img('./test/with_mask/1-with-mask.jpg', target_size=(150,150,3))
#test_image=image.img_to_array(test_image)
test_image=keras.utils.img_to_array(test_image)
test_image=np.expand_dims(test_image,axis=0)
mymodel.predict(test_image)[0][0]


# IMPLEMENTING LIVE DETECTION OF FACE MASK

mymodel=load_model('mymodel.h5')

cap=cv2.VideoCapture(0)
face_cascade=cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

while cap.isOpened():
    _,img=cap.read()
    face=face_cascade.detectMultiScale(img,scaleFactor=1.1,minNeighbors=4)
    for(x,y,w,h) in face:
        face_img = img[y:y+h, x:x+w]
        cv2.imwrite('temp.jpg',face_img)
        test_image=keras.utils.load_img('temp.jpg',target_size=(150,150,3))
        test_image=keras.utils.img_to_array(test_image)
        #test_image=image.load_img('temp.jpg',target_size=(150,150,3))
        #test_image=image.img_to_array(test_image)
        test_image=np.expand_dims(test_image,axis=0)
        pred=mymodel.predict(test_image)[0][0]
        if pred==1:
            cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255),3)
            cv2.putText(img,'NO MASK',((x+w)//2,y+h+20),cv2.FONT_HERSHEY_SIMPLEX,1,(0,0,255),3)
        else:
            cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),3)
            cv2.putText(img,'MASK',((x+w)//2,y+h+20),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),3)
        datet=str(datetime.datetime.now())
        cv2.putText(img,datet,(400,450),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,255,255),1)
          
    cv2.imshow('img',img)
    
    if cv2.waitKey(1)==ord('q'):
        break
    
cap.release()
cv2.destroyAllWindows()

マスク有無の検出を実行

facemask.pyを実行すると、最初は学習が始まり、最後にリアルタイム検出を行います。

python facemask.py

また、最初の学習が余分だな~と思う方は、学習部分をコメントアウトして使うとリアルタイム検出を最初から走らせることが出来ます。以下に学習部分をコメントアウトしたサンプルコードを載せておきます。

# -*- coding: utf-8 -*-

import numpy as np
import keras
import keras.backend as k
from keras.layers import Conv2D,MaxPooling2D,SpatialDropout2D,Flatten,Dropout,Dense
from keras.models import Sequential,load_model
from keras.optimizers import Adam
from keras.preprocessing import image
import cv2
import datetime

'''
# UNCOMMENT THE FOLLOWING CODE TO TRAIN THE CNN FROM SCRATCH

# BUILDING MODEL TO CLASSIFY BETWEEN MASK AND NO MASK

model=Sequential()
model.add(Conv2D(32,(3,3),activation='relu',input_shape=(150,150,3)))
model.add(MaxPooling2D() )
model.add(Conv2D(32,(3,3),activation='relu'))
model.add(MaxPooling2D() )
model.add(Conv2D(32,(3,3),activation='relu'))
model.add(MaxPooling2D() )
model.add(Flatten())
model.add(Dense(100,activation='relu'))
model.add(Dense(1,activation='sigmoid'))

model.compile(optimizer='adam',loss='binary_crossentropy',metrics=['accuracy'])

from keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(
        rescale=1./255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True)

test_datagen = ImageDataGenerator(rescale=1./255)

training_set = train_datagen.flow_from_directory(
        'train',
        target_size=(150,150),
        batch_size=16 ,
        class_mode='binary')

test_set = test_datagen.flow_from_directory(
        'test',
        target_size=(150,150),
        batch_size=16,
        class_mode='binary')

model_saved=model.fit_generator(
        training_set,
        epochs=10,
        validation_data=test_set,

        )

model.save('mymodel.h5',model_saved)

#To test for individual images

mymodel=load_model('mymodel.h5')
#test_image=image.load_img('C:/Users/Karan/Desktop/ML Datasets/Face Mask Detection/Dataset/test/without_mask/30.jpg',target_size=(150,150,3))
#test_image=image.load_img(r'C:/Users/karan/Desktop/FaceMaskDetector/test/with_mask/1-with-mask.jpg',
#                          target_size=(150,150,3))
#test_image=keras.utils.load_img(r'C:/Users/karan/Desktop/FaceMaskDetector/test/with_mask/1-with-mask.jpg',
#                          target_size=(150,150,3))
test_image=keras.utils.load_img('./test/with_mask/1-with-mask.jpg', target_size=(150,150,3))
#test_image=image.img_to_array(test_image)
test_image=keras.utils.img_to_array(test_image)
test_image=np.expand_dims(test_image,axis=0)
mymodel.predict(test_image)[0][0]

'''
# IMPLEMENTING LIVE DETECTION OF FACE MASK

mymodel=load_model('mymodel.h5')

cap=cv2.VideoCapture(0)
face_cascade=cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

while cap.isOpened():
    _,img=cap.read()
    face=face_cascade.detectMultiScale(img,scaleFactor=1.1,minNeighbors=4)
    for(x,y,w,h) in face:
        face_img = img[y:y+h, x:x+w]
        cv2.imwrite('temp.jpg',face_img)
        test_image=keras.utils.load_img('temp.jpg',target_size=(150,150,3))
        test_image=keras.utils.img_to_array(test_image)
        #test_image=image.load_img('temp.jpg',target_size=(150,150,3))
        #test_image=image.img_to_array(test_image)
        test_image=np.expand_dims(test_image,axis=0)
        pred=mymodel.predict(test_image)[0][0]
        if pred==1:
            cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255),3)
            cv2.putText(img,'NO MASK',((x+w)//2,y+h+20),cv2.FONT_HERSHEY_SIMPLEX,1,(0,0,255),3)
        else:
            cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),3)
            cv2.putText(img,'MASK',((x+w)//2,y+h+20),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),3)
        datet=str(datetime.datetime.now())
        cv2.putText(img,datet,(400,450),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,255,255),1)
          
    cv2.imshow('img',img)
    
    if cv2.waitKey(1)==ord('q'):
        break
    
cap.release()
cv2.destroyAllWindows()

これでリアルタイムのマスク検出が始まれば完了です!

エラー対応

いくつかエラーが出ることがあったので解決方法を記録しておきます。

AttributeError: module ‘keras.utils.generic_utils’ has no attribute ‘populate_dict_with_module_objects’

tensorflowとkerasの連携が上手くいってなさそうでした。Anacondaを使っていましたので一旦tensorflowとkerasをuninstallして入れなおしました。uninstallは念のためcondaコマンドとpipコマンドの両方で行いました。

uninstall

pip uninstall tensorflow -y 
pip uninstall tensorflow-gpu -y 
pip uninstall keras -y 
conda uninstall tensorflow -y 
conda uninstall tensorflow-gpu -y 
conda uninstall keras -y

install

pip install tensorflow-gpu
pip install keras

これで解決しました!

ImportError: Could not import PIL.Image. The use of `load_img` requires PIL.

これはPillowをinstallしたら解決しました。

pip install Pillow

Could not locate zlibwapi.dll. Please make sure it is in your library path!

zlibwapi.dllというファイルがないよ!と言ってます。下記の対応で解決しました。

まずはコマンドプロンプトを管理者権限で立ち上げます。

下記コマンドを実行します。

cd "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.7\bin"
curl -O http://www.winimage.com/zLibDll/zlib123dllx64.zip
call powershell -command "Expand-Archive zlib123dllx64.zip"
copy zlib123dllx64\dll_x64\zlibwapi.dll .

こんな感じで処理が走れば成功です。

上手くいかない方はこちらの記事を参考にされると良いかもしれません。
https://www.kkaneko.jp/tools/win/cupy.html

以上です。

このブログの管理人も卒業生です。
Python/DeepLearning
スポンサーリンク
記事が良かったらSNSでシェアを宜しくお願いします!
みやしんをフォローすると役立つ情報がいっぱいにゃ!
スポンサーリンク
みやしんのプログラミングスキル通信

コメント

タイトルとURLをコピーしました