Deep learning project – Face Mask detection using OpenCV

Face mask Detection using Deep learning - www.devpyjp.com

Hello, Guys! welcome to another interesting project project in these Covid-19 pandemic times. In this deep learning project i am going to show how i build a deep learning model that detects faces with or without mask and its deployed with OpenCV

To do this project you must know the below things.

  • How DL works
  • Basic things like layers,optimizer,
  • OpenCV basics

In these days, Govt announces wearing masks are mandatory because at least it can stop the spread of COVID-19, but people will follow this rule, may be?

So, lets build a deep learning model that detects face mask on faces or not. I hope it helps a lot.

We know, to build a machine learning or deep learning model we need data, without data we can’t build a model.

Data collection for deep learning project

A good amount of data consists faces with mask and without masks helps us a lot, But how we can get this data. Can we go outside and take people pictures , do you think people allow you to take pictures of them..?

May be they will do

So what we do now, Don’t worry guys! we have always super saviors and maybe you can also. There is a topic called augmented data creation. This helps us to create artificial data. Here we have saviour, I don’t know his/her name but the credit goes to them.

They create augmented data with human faces with masks and without masks. I give you that git repository link here, go and get that data. Link

Once you grab the data and arrange it properly like below.

data
   -- train
      - with_mask
      - without_mask
   --test
     - with_mask
     - withour mask

Ok! we got the data and now we are moving to model building lets build a deep learning model that predicts human faces with or without masks.

Building a Deep learning model

Here, I am using MobileNetV2 classifier to build this deep learning project

MobileNetV2: It’s a lightweight image classifier, and well optimized for mobile devices, and gives high accuracy. for more INFO.

Ok, I am giving code to this deep learning project. i will explain the things below.

import tensorflow as tf
import os
import datetime

from keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import GlobalAveragePooling2D,Activation,Dropout,Dense,Flatten
from tensorflow.keras.optimizers import Adam
from keras import backend as k
from keras import layers
import numpy as np
from keras.preprocessing import image
from tensorflow.keras.applications import MobileNetV2


import cv2
import matplotlib.pyplot as plt

Here we are importing all necessary libraries, and I am using Tensorflow-GPU version 2.1.0 and keras 2.2.4.

Note: Be careful with versions. most of the problems will occur based on TensorFlow and keras versions.

batch_size = 32 #32,128,256
epochs = 10

You are are free to use different batch_size and epochs.

train_data_dir = "F:/Deep learning/Mask Detection/train"
test_data_dir = "F:/Deep learning/Mask Detection/test"

lets configure your data paths, Be aware of “/” and “\”.

# Preparing data
trainGen = ImageDataGenerator(rescale=1./255,shear_range=0.2,horizontal_flip=True,zoom_range=0.2)

testGen = ImageDataGenerator(rescale=1./255)


train = trainGen.flow_from_directory(train_data_dir,target_size=(224,224),classes=['with_mask','without_mask'],class_mode = 'categorical',batch_size=batch_size,shuffle=True)

test = testGen.flow_from_directory(test_data_dir,target_size=(224,224),classes=['with_mask','without_mask'],class_mode = 'categorical',batch_size=batch_size)

ImageDataGenerator helps us to create augmented data like zooming images and resize and colors of images in the training set. It is used for making better training data.

Configure your data folders in the above lines if you change the folder names.

mob = MobileNetV2(alpha=1.3,
    input_shape = (224,224,3),
    include_top = False,
    weights = 'imagenet',
)
mob.trainable = False


model = Sequential()
model.add(mob)

model.add(GlobalAveragePooling2D())
model.add(Dense(64,activation='relu'))
model.add(Dropout(0.3))

model.add(Dense(2,activation='softmax'))

model.summary()

I already mentioned that I used MobileNetV2 and we configure it on top of Keras layers. Don’t mess with it. If you find any errors when you execute it please check versions of Keras and Tensorflow, still didn’t get then ask Google.

Here I applied GlobalAveragePooling2D pooling technique and activation function ‘relu’ and dropout 0.3 and finally configure the output layer with activation softmax.

Hint: Learn more about layers: Click

model.compile(optimizer=Adam(lr=0.00002),loss='categorical_crossentropy',metrics=['accuracy'])
model.fit(train,epochs=epochs,validation_data=test)

Here I am using Adam optimizer with a learning rate of 0.00002, you can change it to get better performance. In my case, I got 97% accuracy with these parameters.

Model Predictions:

oK, after training and testing Phase we need to cross check how it performs. sometimes even though you got 90+% accuracy, it will predict always one class. so its better to recheck

def predict_mask(path):
    im = cv2.imread(path)
    im_resized = cv2.resize(im, (224, 224), interpolation=cv2.INTER_LINEAR)

    plt.imshow(cv2.cvtColor(im_resized, cv2.COLOR_BGR2RGB))
    plt.show()
    
    img_pred = image.load_img(path,target_size=(224,224))
    img_pred = image.img_to_array(img_pred)
    img = np.expand_dims(img_pred,axis=0)
    result = model.predict_classes(img)
    prob = model.predict_proba(img)
    print(result)
    print('Probability:{}'.format(prob))
    if result[0]==0:
        prediction ="MASK"
    else:
        prediction ="No MSK"

    print(prediction)


# Function calling 

predict_mask('F:/Deep learning/Mask Detection/test/with_mask/10-with-mask.jpg')
predict_mask('F:/Deep learning/Mask Detection/test/without_mask/12.jpg')

Here is the outputs in my case, please change these paths according your file system.

Here,
1 - represents No Mask
0 - represents Mask

#There is no specific reasons to assign 0 and 1, It is just for classifying 2 classes. 

Deployment with Python OpenCV

Alright! we are at the end of the project, lets deployed this model with opencv to get realtime predictions.

# messages on screen
resMap = {
        0 : 'Mask On',
        1 : 'Kindly Wear Mask'
    }

# Colors on screen
colorMap = {
        0 : (0,255,0),
        1 : (0,0,255)
    }

def prepImg(pth):
    return cv2.resize(pth,(224,224)).reshape(1,224,224,3)/255.0

classifier = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

cap = cv2.VideoCapture(0)
while True:
    ret,img = cap.read()
    faces = classifier.detectMultiScale(cv2.cvtColor(img,cv2.COLOR_BGR2GRAY),1.1,2)

    for face in faces:
        slicedImg = img[face[1]:face[1]+face[3],face[0]:face[0]+face[2]]
        pred = model.predict(prepImg(img))
        pred = np.argmax(pred)

        cv2.rectangle(img,(face[0],face[1]),(face[0]+face[2],face[1]+face[3]),colorMap[pred],2)
        cv2.putText(img, resMap[pred],(face[0],face[1]-10),cv2.FONT_HERSHEY_SIMPLEX,0.8,(255,255,255),2)        
        
                
    cv2.imshow('FaceMask Detection',img)
    if cv2.waitKey(1) & 0xff == ord('q'):
        break
    
cap.release()
cv2.destroyAllWindows()

Note: Please maintain this haarcascade_frontalface_default.xml in the same folder of your project file.

To close this OpenCV window, press ‘q’.

Total Project Code

import tensorflow as tf
import os
import datetime

from keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import GlobalAveragePooling2D,Activation,Dropout,Dense,Flatten
from tensorflow.keras.optimizers import Adam
from keras import backend as k
from keras import layers
import numpy as np
from keras.preprocessing import image
from tensorflow.keras.applications import MobileNetV2


import cv2
import matplotlib.pyplot as plt



batch_size = 32 #32,128,256
epochs = 10


train_data_dir = "F:/Deep learning/Mask Detection/train"
test_data_dir = "F:/Deep learning/Mask Detection/test"


# Preparing data
trainGen = ImageDataGenerator(rescale=1./255,shear_range=0.2,horizontal_flip=True,zoom_range=0.2)

testGen = ImageDataGenerator(rescale=1./255)


train = trainGen.flow_from_directory(train_data_dir,target_size=(224,224),classes=['with_mask','without_mask'],class_mode = 'categorical',batch_size=batch_size,shuffle=True)

test = testGen.flow_from_directory(test_data_dir,target_size=(224,224),classes=['with_mask','without_mask'],class_mode = 'categorical',batch_size=batch_size)



mob = MobileNetV2(alpha=1.3,
    input_shape = (224,224,3),
    include_top = False,
    weights = 'imagenet',
)
mob.trainable = False


model = Sequential()
model.add(mob)

model.add(GlobalAveragePooling2D())
model.add(Dense(64,activation='relu'))
model.add(Dropout(0.3))

model.add(Dense(2,activation='softmax'))

model.summary()



model.compile(optimizer=Adam(lr=0.00002),loss='categorical_crossentropy',metrics=['accuracy'])
model.fit(train,epochs=epochs,validation_data=test)


def predict_mask(path):
    im = cv2.imread(path)
    im_resized = cv2.resize(im, (224, 224), interpolation=cv2.INTER_LINEAR)

    plt.imshow(cv2.cvtColor(im_resized, cv2.COLOR_BGR2RGB))
    plt.show()
    
    img_pred = image.load_img(path,target_size=(224,224))
    img_pred = image.img_to_array(img_pred)
    img = np.expand_dims(img_pred,axis=0)
    result = model.predict_classes(img)
    prob = model.predict_proba(img)
    print(result)
    print('Probability:{}'.format(prob))
    if result[0]==0:
        prediction ="MASK"
    else:
        prediction ="No MSK"

    print(prediction)


# Function calling 

predict_mask('F:/Deep learning/Mask Detection/test/with_mask/10-with-mask.jpg')
predict_mask('F:/Deep learning/Mask Detection/test/without_mask/12.jpg')



# messages on screen
resMap = {
        0 : 'Mask On',
        1 : 'Kindly Wear Mask'
    }

# Colors on screen
colorMap = {
        0 : (0,255,0),
        1 : (0,0,255)
    }

def prepImg(pth):
    return cv2.resize(pth,(224,224)).reshape(1,224,224,3)/255.0

classifier = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

cap = cv2.VideoCapture(0)
while True:
    ret,img = cap.read()
    faces = classifier.detectMultiScale(cv2.cvtColor(img,cv2.COLOR_BGR2GRAY),1.1,2)

    for face in faces:
        slicedImg = img[face[1]:face[1]+face[3],face[0]:face[0]+face[2]]
        pred = model.predict(prepImg(img))
        pred = np.argmax(pred)

        cv2.rectangle(img,(face[0],face[1]),(face[0]+face[2],face[1]+face[3]),colorMap[pred],2)
        cv2.putText(img, resMap[pred],(face[0],face[1]-10),cv2.FONT_HERSHEY_SIMPLEX,0.8,(255,255,255),2)        
        
                
    cv2.imshow('FaceMask Detection',img)
    if cv2.waitKey(1) & 0xff == ord('q'):
        break
    
cap.release()
cv2.destroyAllWindows()

I hope you successfully execute and learn a lot of things from this deep learning project. To get more, Please subscribe to our newsletter.

Thank you..!

1 thought on “Deep learning project – Face Mask detection using OpenCV”

Leave a Reply