Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…etection into master
  • Loading branch information
Aayush Garg committed Jan 20, 2021
2 parents e55754d + 3142fae commit 0dba2de
Show file tree
Hide file tree
Showing 13 changed files with 247 additions and 7 deletions.
Binary file added .DS_Store
Binary file not shown.
41 changes: 41 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#### Issue Number
ISSUE #
<!-- Please Mention the issue number as ISSUE #(Issue Number)
Example:
ISSUE #5
-->

#### Describe the changes you've made
<!--
A clear and concise description of what you have done to successfully close your assigned issue. Any new files? or anything you feel to let us know!
-->

#### Describe if there is any unusual behaviour of your code(Write `NA` if there isn't)
<!--
A clear and concise description of it.
-->

#### Additional context (OPTIONAL)
<!--
Add any other context or screenshots about the feature request here.
-->

#### Test plan (OPTIONAL)
<!--
A good test plan should give instructions that someone else can easily follow.
How someone can test your code?
-->

#### Checklist
<!--
Example how to mark a checkbox :-
- [x] My code follows the code style of this project.
-->
- [ ] My code follows the code style of this project.
- [ ] I have performed a self-review of my own code.
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [ ] I have commented my code, particularly in hard-to-understand areas.
- [ ] My changes generate no new warnings.
- [ ] I have added tests that prove my fix is effective or that my feature works.
- [ ] The title of my pull request is a short description of the requested changes.
Binary file added Alarm.wav
Binary file not shown.
34 changes: 34 additions & 0 deletions ResNet50_v2/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Mask Detection using ResNet50 v2


## 🚀&nbsp; Steps to run the ResNet50 v2

- To clone the Repository: <br>
```
git clone https://github.com/chandrikadeb7/Face-Mask-Detection.git
```
- Open terminal. Go into the cloned project directory and type the following command to train the model and create ResNet50_mask_detector.model file <br>
```
python3 ResNet50_v2/mask_with_resnet.py --dataset dataset --model "ResNet50_v2/ResNet50_mask_detector.model"
```

- To detect face masks in an image type the following command: <br>
```
python3 detect_mask_image.py --image images/pic1.jpeg --model ResNet50_v2/ResNet50_mask_detector.model
```


## :key:&nbsp; Result

![alt text](Readme_images/Matrix.png)

### Training Loss and Accuracy
![alt text](Readme_images/Graph.png)

## :star:&nbsp; Output
![alt text](Readme_images/output.png)


## :star:&nbsp; Output Video
![alt text](Readme_images/Output.gif)

Binary file added ResNet50_v2/Readme_images/Graph.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ResNet50_v2/Readme_images/Matrix.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ResNet50_v2/Readme_images/Output.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ResNet50_v2/Readme_images/output.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
128 changes: 128 additions & 0 deletions ResNet50_v2/mask_with_resnet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# -*- coding: utf-8 -*-

from tensorflow.keras.optimizers import Adam
from tensorflow.keras.utils import to_categorical
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from imutils import paths
import matplotlib.pyplot as plt
import numpy as np
import tensorflow_hub as hub
import tensorflow as tf
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.preprocessing.image import load_img
from tensorflow.keras import layers
from tensorflow.keras.layers import Input
import argparse
import os
from tensorflow.keras.applications import ResNet50V2

ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dataset", required=True,
help="path to input dataset")
ap.add_argument("-p", "--plot", type=str, default="plot.png",
help="path to output loss/accuracy plot")
ap.add_argument("-m", "--model", type=str,
default="mask_detector.model",
help="path to output face mask detector model")
args = vars(ap.parse_args())

print("[INFO] loading images...")
imagePaths = list(paths.list_images(args["dataset"]))
data = []
labels = []

IMG_SIZE = 224
CHANNELS = 3
N_LABELS=2


# loop over the image paths
for imagePath in imagePaths:
# extract the class label from the filename
label = imagePath.split(os.path.sep)[-2]
# load the input image (224x224) and preprocess it
image = load_img(imagePath, target_size=(IMG_SIZE, IMG_SIZE))
image = img_to_array(image)
image = image/255
#image = preprocess_input(image)

# update the data and labels lists, respectively
data.append(image)
labels.append(label)

data = np.array(data, dtype="float32")
labels = np.array(labels)

lb = LabelBinarizer()
labels = lb.fit_transform(labels)
labels = to_categorical(labels)

(trainX, testX, trainY, testY) = train_test_split(data, labels, test_size=0.20, stratify=labels, random_state=42)

aug = ImageDataGenerator(
rotation_range=20,
zoom_range=0.15,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.15,
horizontal_flip=True,
fill_mode="nearest")


feature_extractor_layer = ResNet50V2(weights="imagenet", include_top=False,
input_tensor=Input(shape=(IMG_SIZE,IMG_SIZE,CHANNELS)))

feature_extractor_layer.trainable = False

model = tf.keras.Sequential([
feature_extractor_layer,
layers.Flatten(name="flatten"),
layers.Dense(1024, activation='relu', name='hidden_layer'),
layers.Dropout(0.5),
layers.Dense(N_LABELS, activation='sigmoid', name='output')
])

model.summary()

LR = 1e-5 # Keep it small when transfer learning
EPOCHS = 20
BS = 256

model.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=LR),
loss="binary_crossentropy",
metrics=["accuracy"])

import time
start = time.time()
history = model.fit(aug.flow(trainX, trainY, batch_size=BS),
steps_per_epoch=len(trainX) // BS,
validation_data=(testX, testY),
epochs=EPOCHS)
print('\nTraining took {}'.format((time.time()-start)))

print("[INFO] evaluating network...")
predIdxs = model.predict(testX, batch_size=BS)

predIdxs = np.argmax(predIdxs, axis=1)

print(classification_report(testY.argmax(axis=1), predIdxs,target_names=lb.classes_))

print("[INFO] saving mask detector model...")
model.save(args["model"], save_format="h5")

N = EPOCHS
plt.style.use("ggplot")
plt.figure()
plt.plot(np.arange(0, N), history.history["loss"], label="train_loss")
plt.plot(np.arange(0, N), history.history["val_loss"], label="val_loss")
plt.plot(np.arange(0, N), history.history["accuracy"], label="accuracy")
plt.plot(np.arange(0, N), history.history["val_accuracy"], label="val_accuracy")
plt.title("Training Loss and Accuracy")
plt.xlabel("Epoch #")
plt.ylabel("Loss/Accuracy")
plt.legend(loc="lower left")
plt.savefig(args["plot"])
27 changes: 20 additions & 7 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@
from tensorflow.keras.models import load_model
import detect_mask_image

# Setting custom Page Title and Icon with changed layout and sidebar state
st.beta_set_page_config(page_title='Face Mask Detector', page_icon='😷', layout='centered', initial_sidebar_state='expanded')


def local_css(file_name):
""" Method for reading styles.css and applying necessary changes to HTML"""
with open(file_name) as f:
st.markdown(f'<style>{f.read()}</style>', unsafe_allow_html=True)


def mask_image():
global RGB_img
Expand Down Expand Up @@ -85,22 +94,26 @@ def mask_image():
mask_image()

def mask_detection():
st.title("Face mask detection")
local_css("css/styles.css")
st.markdown('<h1 align="center">😷 Face Mask Detection</h1>', unsafe_allow_html=True)
activities = ["Image", "Webcam"]
st.set_option('deprecation.showfileUploaderEncoding', False)
choice = st.sidebar.selectbox("Mask Detection on?", activities)
st.sidebar.markdown("# Mask Detection on?")
choice = st.sidebar.selectbox("Choose among the given options:", activities)

if choice == 'Image':
st.subheader("Detection on image")
image_file = st.file_uploader("Upload Image", type=['jpg']) # upload image
st.markdown('<h2 align="center">Detection on Image</h2>', unsafe_allow_html=True)
st.markdown("### Upload your image here ⬇")
image_file = st.file_uploader("", type=['jpg']) # upload image
if image_file is not None:
our_image = Image.open(image_file) # making compatible to PIL
im = our_image.save('./images/out.jpg')
saved_image = st.image(image_file, caption='image uploaded successfully', use_column_width=True)
saved_image = st.image(image_file, caption='', use_column_width=True)
st.markdown('<h3 align="center">Image uploaded successfully!</h3>', unsafe_allow_html=True)
if st.button('Process'):
st.image(RGB_img, use_column_width=True)

if choice == 'Webcam':
st.subheader("Detection on webcam")
st.text("This feature will be avilable soon")
st.markdown('<h2 align="center">Detection on Webcam</h2>', unsafe_allow_html=True)
st.markdown('<h3 align="center">This feature will be available soon!</h3>', unsafe_allow_html=True)
mask_detection()
16 changes: 16 additions & 0 deletions css/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* Changing body color to dark grey and text color to gainsboro(version of white) */
body {
color: gainsboro;
background-color: #333;
}

/* Changing sideline color to light gray and text color to black */
.sidebar .sidebar-content {
background-color: #c1c1c1;
background-image: none;
color: black;
}

/* Removing Main Menubar and Footer */
#MainMenu {visibility: hidden;}
footer {visibility: hidden;}
6 changes: 6 additions & 0 deletions detect_mask_video.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.models import load_model
from imutils.video import VideoStream
from playsound import playsound
import numpy as np
import argparse
import imutils
Expand Down Expand Up @@ -143,6 +144,11 @@ def detect_and_predict_mask(frame, faceNet, maskNet):
cv2.FONT_HERSHEY_SIMPLEX, 0.45, color, 2)
cv2.rectangle(frame, (startX, startY), (endX, endY), color, 2)

# Alarm when "No Mask" detected
if mask < withoutMask:
path = os.path.abspath("Alarm.wav")
playsound(path)

# show the output frame
cv2.imshow("Frame", frame)
key = cv2.waitKey(1) & 0xFF
Expand Down
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ scipy==1.4.1
scikit-learn==0.23.1
pillow==7.2.0
streamlit==0.65.2
playsound
pyobjc

0 comments on commit 0dba2de

Please sign in to comment.