-
Notifications
You must be signed in to change notification settings - Fork 0
/
Face_Mask_Model.py
338 lines (216 loc) · 9.37 KB
/
Face_Mask_Model.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
#!/usr/bin/env python
# coding: utf-8
# <a href="https://colab.research.google.com/github/aarpit1010/Real-Time-Face-Mask-Detector/blob/master/Face_Mask_Model.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a>
# In[1]:
# IMPORTING THE REQUIRED LIBRARIES
import sys
import os
import math
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
#get_ipython().run_line_magic('matplotlib', 'inline')
import seaborn as sns
# uncomment the following line if 'imutils' is not installed in your python kernel
# !{sys.executable} -m pip install imutils
import imutils
from imutils import paths
import keras
from keras.layers import Dense, Conv2D, BatchNormalization, Dropout, Activation, MaxPooling2D, Flatten
from keras.models import Sequential, load_model
from keras.losses import categorical_crossentropy, binary_crossentropy
from keras.optimizers import Adam
from keras.utils import np_utils
from keras.regularizers import l2
from keras import regularizers
from keras.callbacks import ModelCheckpoint
from keras.preprocessing.image import ImageDataGenerator
from keras.preprocessing.image import img_to_array
from keras.applications.mobilenet_v2 import preprocess_input
from keras.preprocessing.image import load_img
from keras.utils import to_categorical
from sklearn.preprocessing import LabelBinarizer
import cv2
import time
import random
import shutil
# In[2]:
from google.colab import drive
drive.mount('/content/drive')
# # Let's have a look at our Data
# In[3]:
# Path to the folders containing images
data_path = '/content/drive/My Drive/Colab Notebooks/Face Mask Detector/dataset'
mask_path = '/content/drive/My Drive/Colab Notebooks/Face Mask Detector/train/with_mask/'
nomask_path = '/content/drive/My Drive/Colab Notebooks/Face Mask Detector/train/without_mask/'
test_path = '/content/drive/My Drive/Colab Notebooks/Face Mask Detector/test/'
train_path = '/content/drive/My Drive/Colab Notebooks/Face Mask Detector/train/'
# In[4]:
# function to show images from the input path
def view(path):
images = list()
for img in random.sample(os.listdir(path),9):
images.append(img)
i = 0
fig,ax = plt.subplots(nrows=3, ncols=3, figsize=(20,10))
for row in range(3):
for col in range(3):
ax[row,col].imshow(cv2.imread(os.path.join(path,images[i])))
i+=1
# In[5]:
# sample images of people wearing masks
view(mask_path)
# In[6]:
#sample images of people NOT wearning masks
view(nomask_path)
# # Splitting of Data
#
# - TRAINING SET
# - Mask : 658
# - No Mask : 656
#
# - TEST SET
# - Mask : 97
# - No Mask : 97
# <br><br>
# Since, the dataset is pretty small, image augmentation is performed so as to increase the dataset. We perform Data Augmentation generally to get different varients of the same image without collecting more data which may not be always possible to collect.
# <br><br>
# It is another way to reduce Overfitting on our model, where we increase the amount of training data using information only in our training data and leave the test set untouched.
# # Preparation of Data Pipelining
# In[7]:
batch_size = 32 # Batch Size
epochs = 50 # Number of Epochs
img_size = 224
# In[8]:
# Data Augmentation to increase training dataset size
train_datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=20,
shear_range=0.2,
zoom_range=0.2,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1./255)
training_set = train_datagen.flow_from_directory(
'/content/drive/My Drive/Colab Notebooks/Face Mask Detector/train',
target_size=(img_size,img_size),
batch_size=batch_size,
class_mode='binary')
test_set = test_datagen.flow_from_directory(
'/content/drive/My Drive/Colab Notebooks/Face Mask Detector/test',
target_size=(img_size,img_size),
batch_size=batch_size,
class_mode='binary')
# # Building the Model
#
# - In the next step, we build our Sequential CNN model with various layers such as Conv2D, MaxPooling2D, Flatten, Dropout and Dense.
# - In the last Dense layer, we use the ‘**softmax**’ function to output a vector that gives the probability of each of the two classes.
# - Regularization is done to prevent overfitting of the data. It is neccessary since our dataset in not very large and just around 5000 images in total.
# In[9]:
model=Sequential()
model.add(Conv2D(224,(3,3), activation ='relu', input_shape=(img_size,img_size,3), kernel_regularizer=regularizers.l2(0.003)))
model.add(MaxPooling2D() )
model.add(Conv2D(100,(3,3), activation ='relu', kernel_regularizer=regularizers.l2(0.003)))
model.add(MaxPooling2D() )
model.add(Conv2D(100,(3,3), activation ='relu', kernel_regularizer=regularizers.l2(0.003)))
model.add(MaxPooling2D() )
model.add(Conv2D(50,(3,3), activation ='relu', kernel_regularizer=regularizers.l2(0.003)))
model.add(MaxPooling2D() )
model.add(Conv2D(30,(3,3), activation ='relu', kernel_regularizer=regularizers.l2(0.003)))
model.add(MaxPooling2D())
model.add(Flatten())
model.add(Dropout(0.5))
model.add(Dense(90, activation ='relu'))
model.add(Dense(30, activation = 'relu'))
model.add(Dense(1, activation ='sigmoid'))
model.summary()
# In[10]:
# Optimization of the model is done via Adam optimizer
# Loss is measures in the form of Binary Categorical Cross Entropy as our output contains 2 classes, with_mask and without_mask
model.compile(optimizer=Adam(), loss='binary_crossentropy', metrics=['accuracy'])
# In[11]:
#Model Checkpoint to save the model after training, so that it can be re-used while detecting faces
# Include the epoch in the file name (uses `str.format`)
checkpoint_path = "/content/drive/My Drive/Colab Notebooks/Face Mask Detector/cp-{epoch:04d}.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)
checkpoint = ModelCheckpoint(
filepath = checkpoint_path,
monitor='val_loss',
verbose=0,
save_best_only=True,
save_weights_only=True,
mode='auto'
)
# Save the weights using the `checkpoint_path` format
model.save_weights(checkpoint_path.format(epoch=0))
# Training of the Model is done
history=model.fit(training_set, epochs=epochs, validation_data=test_set)
# In[12]:
# Plotting the loss on validation set w.r.t the number of epochs
plt.plot(history.history['loss'],'r',label='Training Loss')
plt.plot(history.history['val_loss'],label='Validation Loss')
plt.xlabel('No. of Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()
# Plotting the accuracy on validation set w.r.t the number of epochs
plt.plot(history.history['accuracy'],'r',label='Training Accuracy')
plt.plot(history.history['val_accuracy'],label='Validation Accuracy')
plt.xlabel('No. of Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.show()
# In[13]:
# print(model.evaluate(test_data,test_target))
# In[14]:
get_ipython().system('pip install pyyaml h5py # Required to save models in HDF5 format')
# Now, look at the resulting checkpoints and choose the latest one:
# In[15]:
# Saving the Model trained above, which will be used in future while using Real time data
model.save('/content/drive/My Drive/Colab Notebooks/Face Mask Detector/trained_model.model', history)
model.save('/content/drive/My Drive/Colab Notebooks/Face Mask Detector/trained_model.h5', history)
# In[16]:
# IMPLEMENTING LIVE DETECTION OF FACE MASK
# Importing the saved model from the IPython notebook
mymodel=load_model('/content/drive/My Drive/Colab Notebooks/Face Mask Detector/trained_model.h5')
# Importing the Face Classifier XML file containing all features of the face
face_classifier=cv2.CascadeClassifier('/content/drive/My Drive/Colab Notebooks/Face Mask Detector/haarcascade_frontalface_default.xml')
# To open a video via link to be inserted in the () of VideoCapture()
# To open the web cam connected to your laptop/PC, write '0' (without quotes) in the () of VideoCapture()
src_cap=cv2.VideoCapture(0)
while src_cap.isOpened():
_,img=src_cap.read()
rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# detect MultiScale / faces
faces = face_classifier.detectMultiScale(rgb, 1.3, 5)
# Draw rectangles around each face
for (x, y, w, h) in faces:
#Save just the rectangle faces in SubRecFaces
face_img = rgb[y:y+w, x:x+w]
face_img=cv2.resize(face_img,(224,224))
face_img=face_img/255.0
face_img=np.reshape(face_img,(224,224,3))
face_img=np.expand_dims(face_img,axis=0)
pred=mymodel.predict_classes(face_img)
# print(pred)
if pred[0][0]==1:
cv2.rectangle(img, (x,y), (x+w, y+h), (0,0,255), 2)
cv2.rectangle(img, (x,y-40), (x+w,y), (0,0,255),-1)
cv2.putText(img,'NO MASK',(250,50),cv2.FONT_HERSHEY_SIMPLEX,1,(0,0,255),4)
else:
cv2.rectangle(img, (x,y), (x+w, y+h), (0,255,0), 2)
cv2.rectangle(img, (x,y-40), (x+w,y), (0,255,0),-1)
cv2.putText(img,'MASK',(250,50),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),4)
datet=str(datetime.datetime.now())
cv2.putText(img,datet,(400,450),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,255,255),1)
# Show the image
cv2.imshow('LIVE DETECTION',img)
# if key 'q' is press then break out of the loop
if cv2.waitKey(1)==ord('q'):
break
# Stop video
src_cap.release()
# Close all started windows
cv2.destroyAllWindows()
# In[16]: