Face mask detection using Deep Learning.

Prathmesh Patil
Analytics Vidhya
Published in
4 min readJun 12, 2020
Photo by United Nations COVID-19 Response on Unsplash

Seeing the amid covid-19 situation through out the world it has become very important to keep our self and our family healthy and safe because as of today there is no vaccine available. The basic equipment that can keep us a step away is using a face mask. So I always wanted to do something about it.

So i decided to use Deep Learning concepts to check whether a person is wearing a face mask or not using CNN.

WHAT IS CNN?

Convolutional Neural Networks(CNN) are a special type of a neural networks which are capable processing the images and differentiate them based on their classes. They are similar to how a human eye perceives the images and that data back to our brain which is the visual cortex. To know more about it in details you can search about it online and also check this post.

Basic architecture of CNN

Assuming that you have the basic idea about let’s get started!

Lets begin with importing libraries and images.

import os
import cv2
import numpy as np
from sklearn.model_selection import train_test_split
from keras.models import Sequential
from keras.utils import to_categorical
from keras.layers import MaxPooling2D,Convolution2D,Dense,Dropout,Flatten,Input
import pickle
import pandas as pd
from keras.preprocessing.image import ImageDataGenerator
%matplotlib inline
import matplotlib.pyplot as plt

now we will import the images one by one, and set the path according to where you have downloaded the dataset.

path="dataset"
count=0
dir=os.listdir(path)
imgs=[]
count=0
classno=[]
print("with and without mask")
nosf=len(dir)
print("getting images")
for x in range(0,nosf):
mypics=os.listdir(path+"/"+str(count))
for y in mypics:
curimg = cv2.imread(path+"/"+str(count)+"/"+y)
imgs.append(curimg)
classno.append(count)
print(count,end=" ")
count+=1
print(" ")
imgnp=np.array(imgs)
clsnp=np.array(classno)

after running this part the output looks like:

Now we will split data for training testing and validation.

x_train, x_test, y_train, y_test = train_test_split(imgnp,clsnp,test_size=0.2)
x_train, x_valid, y_train, y_valid = train_test_split(x_train,y_train,test_size=0.2)

After splitting the data we will pre-process it to get into right format.

def processing(img):
img = cv2.resize(img,(28,28))
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
img = cv2.equalizeHist(img)
img = img/255
return img
x_train = np.array(list(map(processing,x_train)))
x_test = np.array(list(map(processing,x_test)))
x_valid = np.array(list(map(processing,x_valid)))

Now we will reshape the images to add a depth of 1.

x_train=x_train.reshape(880,28,28,1)
x_test=x_test.reshape(276,28,28,1)
x_valid=x_valid.reshape(220,28,28,1)

After this we will augment our data which will give better results.

datagen = ImageDataGenerator(width_shift_range=0.1,
height_shift_range=0.1,
zoom_range=0.2,
shear_range=0.1,
rotation_range=10)
datagen.fit(x_train)
batch = datagen.flow(x_train,y_train,batch_size=20)
x_batch, y_batch = next(batch)

Now we are converting the label data into categorical data.

y_train = to_categorical(y_train)
y_test = to_categorical(y_test)
y_valid = to_categorical(y_valid)

Next, lets build our model!

def mymod():

model = Sequential()

model.add(Convolution2D(60,(5,5),activation='relu',input_shape=(28,28,1)))
model.add(Convolution2D(60,(5,5),activation='relu'))
model.add(MaxPooling2D(2,2))

model.add(Convolution2D(30,(3,3),activation='relu'))
model.add(Convolution2D(30,(3,3),activation='relu'))
model.add(MaxPooling2D(2,2))
model.add(Dropout(0.5))

model.add(Flatten())
model.add(Dense(500,activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(2,activation='softmax'))

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

Note that here I have used categorical loss, even though this is a binary classification, so you can use “binary_crossentropy” as well.

this is the summary of our model

mod = mymod()
print(mod.summary())

Now, we will start training our model. Also if you are using a GPU then the training time will decrease significantly.

history = mod.fit_generator(datagen.flow(x_train,y_train,batch_size=50),
steps_per_epoch=880,
epochs=11,
validation_data=(x_valid,y_valid),
shuffle=1)

It will take some time to train, so sit back and relax!

Once training is done lets check the results.

score = mod.evaluate(x_test,y_test)
print(score[0])
print(score[1])

Seeing from the results the loss on the higher side, you can play and tune the code to get even better results also one thing to note that images in the dataset are very limited which also affects the accuracy and the model might also over fit therefore choose the parameters carefully.But still it works!.

Next we will save our model.

pik = open("ready.p","wb")
pickle.dump(mod,pik)
pik.close()
cv2.waitKey(0)

Finally lets make some predictions and crosscheck it.

y_pred=mod.predict(x_test)

We will select a random image from our testing set to compare.

plt.matshow(x_test[0].reshape(28,28))

This gives the result as 1, which is correct as non-masked index is 0 and masked is 1.

Concluding everything that we did so far.

So in this way we build our CNN model which identify if mask is worn or not, again this model is not most accurate one as I told before as the data available is less if you have more images then you can add it to the folder and train again,but still its worth a try!. Also you can use hyper parameter tuning for yielding even better accuracy and reduce the loss.I have also built a driver code which will capture video from webcam and predict whether mask is present or not which is done with the help of open-cv. You can get the source code from my GitHub. Hope this post helps you to understand about CNN for identify face masks I appreciate you for giving your time and reading it,thank you.

--

--

Prathmesh Patil
Analytics Vidhya

ML enthusiast, Data Science, Python developer, Google Cloud & Serverless. LinkedIn: https://www.linkedin.com/in/prathmesh