School of Computer Science & Engineering
BCSE306L –Artificial Intelligence– C1 Slot – WIN 2023 -24
Project Report Source Code
DA-2
Project Title : Face Mask Detection using different algorithms
Review Number : II
Date of Submission : 27th March 2024
Members
1. Diya Das (21BCE5081)
2. Armaan Saini (21BCE5115)
Faculty In-charge:
Dr. Abirami S
Professor
SCOPE
Code for the normal CNN layers Implemented manually
# %%
## Importing libraries
import pandas as pd
import numpy as np
import cv2
import os
import glob
from scipy.spatial import distance
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, confusion_matrix
import tensorflow as tf
from tensorflow.keras import Sequential, models
from tensorflow.keras.layers import Flatten, Dense, Conv2D, MaxPool2D
from keras.preprocessing.image import ImageDataGenerator
import matplotlib.pyplot as plt
import seaborn as sns
# %%
path = "kaggle/input/face-mask-12k-images-dataset/Face Mask Dataset/"
# %%
dataset = {
"image_path": [],
"mask_status": [],
"where": []
}
for where in os.listdir(path):
for status in os.listdir(path+"/"+where):
for image in glob.glob(path+where+"/"+status+"/"+"*.png"):
dataset["image_path"].append(image)
dataset["mask_status"].append(status)
dataset["where"].append(where)
dataset = pd.DataFrame(dataset)
dataset.head()
# %%
## Choosing a random image to detect the face in the image
face_model =
cv2.CascadeClassifier('../input/haarcascades/haarcascade_frontalface_default.x
ml')
## Choosing the image from the directory
img = cv2.imread("../input/face-mask-detection/images/maksssksksss244.png")
## Converting the image to grayscale to apply haarcascade algorithm
img = cv2.cvtColor(img, cv2.IMREAD_GRAYSCALE)
## Returns the x, y, w, h co-ordinates as numpy arrays for all the detected
faces
detected_face = face_model.detectMultiScale(img)
## Converting from grayscale to colored image
output_img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
## Drawing rectangle box around the faces in the image
for (x, y, w, h) in detected_face:
cv2.rectangle(output_img, (x,y), (x+w, y+h), (0, 0, 200), 2)
## Displaying the image
plt.figure(figsize = (15, 15))
plt.imshow(output_img)
# %%
## Checking for total number of images in the dataset
print(f"With Mask:", dataset.value_counts("mask_status")[0])
print(f"Without Mask:", dataset.value_counts("mask_status")[1])
## Plotting the numbers
sns.countplot(x = dataset["mask_status"])
# %%
plt.figure(figsize = (15, 10))
for i in range(9):
random = np.random.randint(1, len(dataset))
plt.subplot(3, 3, i+1)
plt.imshow(cv2.imread(dataset.loc[random,"image_path"]))
plt.title(dataset.loc[random,"mask_status"], size = 15)
plt.xticks([])
plt.yticks([])
plt.show()
# %%
## Splitting train test and Validation Dataset
train_df = dataset[dataset["where"] == "Train"]
test_df = dataset[dataset["where"] == "Test"]
valid_df = dataset[dataset["where"] == "Validation"]
print(train_df.head(10))
## Shuffling the dataset
train_df = train_df.sample(frac = 1)
test_df = test_df.sample(frac = 1)
valid_df = valid_df.sample(frac = 1)
print("\n After Shuffling \n")
print(train_df.head(10))
# %%
plt.figure(figsize = (15, 5))
plt.subplot(1, 3, 1)
sns.countplot(x = train_df["mask_status"])
plt.title("Training Dataset", size = 10)
plt.subplot(1, 3, 2)
sns.countplot(x = test_df["mask_status"])
plt.title("Test Dataset", size = 10)
plt.subplot(1, 3, 3)
sns.countplot(x = valid_df["mask_status"])
plt.title("Validation Dataset", size = 10)
plt.show()
# %%
train_df = train_df.reset_index().drop("index", axis = 1)
train_df.head()
# %%
## Reading all the image into a list and changing the size of the image to
(150,150)
data = []
image_size = 150
for i in range(len(train_df)):
## Converting the image into grayscale
img_array = cv2.imread(train_df["image_path"][i], cv2.IMREAD_GRAYSCALE)
## Resizing the array
new_image_array = cv2.resize(img_array, (image_size, image_size))
##Encoding the image with the label
if train_df["mask_status"][i] == "WithMask":
data.append([new_image_array, 1])
else:
data.append([new_image_array, 0])
# %%
data = np.array(data,dtype=object)
# %%
data[0][0].shape
# %%
## Shuffling the data to make sure everything is not in order
np.random.shuffle(data)
# %%
## Looking at the training samples
fig, ax = plt.subplots(2, 3, figsize=(10, 10))
for row in range(2):
for col in range(3):
image_index = row*100+col
ax[row, col].axis("off")
ax[row,col].imshow(data[image_index][0], cmap = "gray")
if data[image_index][1] == 0:
ax[row, col].set_title("Without Mask")
else:
ax[row, col].set_title("With Mask")
plt.show()
# %%
X = []
y = []
## Seperating X and y
for image in data:
X.append(image[0])
y.append(image[1])
## Converting X and y to numpy array as Tensorflow accepts only numpy arrays
X = np.array(X)
y = np.array(y)
# %%
### Normalizing the data
X = X/255
### Train Test Split
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size = 0.2,
random_state = 42)
# %%
model = Sequential()
model.add(Conv2D(64, (3, 3), activation = "relu"))
model.add(Conv2D(64, (3, 3), activation = "relu"))
model.add(MaxPool2D(pool_size=(3, 3)))
model.add(Flatten())
model.add(Dense(128, activation = "relu"))
model.add(Dense(1, activation = "sigmoid"))
# model.summary()
# %%
model.compile(optimizer='adam',
loss=tf.keras.losses.BinaryCrossentropy(),
metrics=['accuracy'])
# %%
# X_train = X_train.reshape(-1, 32, 150, 150)
## Reshaping training set to match Conc2D
X_train = X_train.reshape(len(X_train), X_train.shape[1], X_train.shape[2], 1)
X_val = X_val.reshape(len(X_val), X_val.shape[1], X_val.shape[2], 1)
history = model.fit(X_train, y_train, epochs=5, batch_size = 32)
# %%
model.summary()
# %%
def visualize_data(history):
# Plotting accuracy
plt.plot(history.history['accuracy'])
plt.title('Model Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend(['Train', 'Validation'], loc='upper left')
plt.show()
# Plotting loss
plt.plot(history.history['loss'])
plt.title('Model Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend(['Train', 'Validation'], loc='upper left')
plt.show()
visualize_data(history)
# %%
prediction = (model.predict(X_val) > 0.5).astype("int32")
# %%
print(classification_report(y_val, prediction))
print(confusion_matrix(y_val, prediction))
Code for the VGG algorithm implemented.
# %%
# %%
## Importing libraries
import pandas as pd
import numpy as np
import cv2
import os
import glob
from scipy.spatial import distance
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, confusion_matrix
from keras.applications.vgg19 import VGG19
import tensorflow as tf
from tensorflow.keras import Sequential, models
from tensorflow.keras.layers import Flatten, Dense, Conv2D, MaxPool2D
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import matplotlib.pyplot as plt
import seaborn as sns
# %%
# %%
path = "/kaggle/input/face-mask-12k-images-dataset/Face Mask Dataset/"
# %%
# %%
dataset = {
"image_path": [],
"mask_status": [],
"where": []
}
for where in os.listdir(path):
for status in os.listdir(path+"/"+where):
for image in glob.glob(path+where+"/"+status+"/"+"*.png"):
dataset["image_path"].append(image)
dataset["mask_status"].append(status)
dataset["where"].append(where)
dataset = pd.DataFrame(dataset)
dataset.head()
# %%
# %%
## Choosing a random image to detect the face in the image
face_model =
cv2.CascadeClassifier('/kaggle/input/haarcascade/haarcascade_frontalface_defau
lt.xml')
## Choosing the image from the directory
img = cv2.imread("/kaggle/input/face-mask-
detection/images/maksssksksss352.png")
## Converting the image to grayscale to apply haarcascade algorithm
img = cv2.cvtColor(img, cv2.IMREAD_GRAYSCALE)
## Returns the x, y, w, h co-ordinates as numpy arrays for all the detected
faces
detected_face = face_model.detectMultiScale(img)
## Converting from grayscale to colored image
output_img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
## Drawing rectangle box around the faces in the image
for (x, y, w, h) in detected_face:
cv2.rectangle(output_img, (x,y), (x+w, y+h), (0, 0, 200), 2)
## Displaying the image
plt.figure(figsize = (15, 15))
plt.imshow(output_img)
# %%
# %%
## Checking for total number of images in the dataset
print(f"With Mask:", dataset.value_counts("mask_status")[0])
print(f"Without Mask:", dataset.value_counts("mask_status")[1])
## Plotting the numbers
sns.countplot(x = dataset["mask_status"])
# %%
# %%
plt.figure(figsize = (15, 10))
for i in range(9):
random = np.random.randint(1, len(dataset))
plt.subplot(3, 3, i+1)
plt.imshow(cv2.imread(dataset.loc[random,"image_path"]))
plt.title(dataset.loc[random,"mask_status"], size = 15)
plt.xticks([])
plt.yticks([])
plt.show()
# %%
# %%
## Splitting train test and Validation Dataset
train_df = dataset[dataset["where"] == "Train"]
test_df = dataset[dataset["where"] == "Test"]
valid_df = dataset[dataset["where"] == "Validation"]
print(train_df.head(10))
## Shuffling the dataset
train_df = train_df.sample(frac = 1)
test_df = test_df.sample(frac = 1)
valid_df = valid_df.sample(frac = 1)
print("\n After Shuffling \n")
print(train_df.head(10))
# %%
# %%
plt.figure(figsize = (15, 5))
plt.subplot(1, 3, 1)
sns.countplot(x = train_df["mask_status"])
plt.title("Training Dataset", size = 10)
plt.subplot(1, 3, 2)
sns.countplot(x = test_df["mask_status"])
plt.title("Test Dataset", size = 10)
plt.subplot(1, 3, 3)
sns.countplot(x = valid_df["mask_status"])
plt.title("Validation Dataset", size = 10)
plt.show()
# %%
# %%
train_df = train_df.reset_index().drop("index", axis = 1)
train_df.head()
# %%
# %%
## Reading all the image into a list and changing the size of the image to
(150,150)
data = []
image_size = 150
for i in range(len(train_df)):
## Converting the image into grayscale
img_array = cv2.imread(train_df["image_path"][i], cv2.IMREAD_GRAYSCALE)
## Resizing the array
new_image_array = cv2.resize(img_array, (image_size, image_size))
##Encoding the image with the label
if train_df["mask_status"][i] == "WithMask":
data.append([new_image_array, 1])
else:
data.append([new_image_array, 0])
# %%
# %%
data = np.array(data,dtype="object")
# %%
# %%
data[0][0].shape
# %%
# %%
## Shuffling the data to make sure everything is not in order
np.random.shuffle(data)
# %%
# %%
## Looking at the training samples
fig, ax = plt.subplots(2, 3, figsize=(10, 10))
for row in range(2):
for col in range(3):
image_index = row*100+col
ax[row, col].axis("off")
ax[row,col].imshow(data[image_index][0], cmap = "gray")
if data[image_index][1] == 0:
ax[row, col].set_title("Without Mask")
else:
ax[row, col].set_title("With Mask")
plt.show()
# %%
# %%
# datagen = ImageDataGenerator(rescale = 1./255)
# train_generator=datagen.flow_from_dataframe(
# dataframe=train_df,
# directory="../input",
# x_col="image_path",
# y_col="mask_status",
# batch_size=80,
# seed=42,
# shuffle=False,
# class_mode="binary",
# target_size=(150,150))
# %%
# %%
X = []
y = []
## Seperating X and y
for image in data:
X.append(image[0])
y.append(image[1])
## Converting X and y to numpy array as Tensorflow accepts only numpy arrays
X = np.array(X)
y = np.array(y)
# %%
# %%
### Normalizing the data
X = X/255
### Train Test Split
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size = 0.2,
random_state = 42)
# %%
# %%
vgg19 = VGG19(weights='imagenet',include_top=False,input_shape=(128, 128, 3))
for layer in vgg19.layers:
layer.trainable = False
model = Sequential()
model.add(vgg19)
model.add(Flatten(name="layer1"))
model.add(Dense(128, activation='relu',name="layer2"))
model.add(Dense(2,activation='sigmoid',name="layer3"))
model.summary()
# %%
# %%
model.compile(optimizer='adam',
loss=tf.keras.losses.BinaryCrossentropy(),
metrics=['accuracy'])
# %%
# %%
train_dir = '../input/face-mask-12k-images-dataset/Face Mask Dataset/Train'
test_dir = '../input/face-mask-12k-images-dataset/Face Mask Dataset/Test'
val_dir = '../input/face-mask-12k-images-dataset/Face Mask Dataset/Validation'
# %%
train_datagen = ImageDataGenerator(rescale=1.0/255, horizontal_flip=True,
zoom_range=0.2,shear_range=0.2)
train_generator =
train_datagen.flow_from_directory(directory=train_dir,target_size=(128,128),cl
ass_mode='categorical',batch_size=32)
val_datagen = ImageDataGenerator(rescale=1.0/255)
val_generator =
train_datagen.flow_from_directory(directory=val_dir,target_size=(128,128),clas
s_mode='categorical',batch_size=32)
test_datagen = ImageDataGenerator(rescale=1.0/255)
test_generator =
train_datagen.flow_from_directory(directory=val_dir,target_size=(128,128),clas
s_mode='categorical',batch_size=32)
history = model.fit(train_generator,
epochs=5,
validation_data=val_generator)
# %%
# %%
def visualize_data(history):
# Plotting accuracy
plt.plot(history.history['accuracy'])
plt.title('Model Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend(['Train', 'Validation'], loc='upper left')
plt.show()
# Plotting loss
plt.plot(history.history['loss'])
plt.title('Model Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend(['Train', 'Validation'], loc='upper left')
plt.show()
visualize_data(history)
# %%
model.summary()
# %%
# %%
# Evaluate the model on the test data
evaluation = model.evaluate(test_generator)
# Print the evaluation results
print("Test Loss:", evaluation[0])
print("Test Accuracy:", evaluation[1])