|
| 1 | +# Python Face_Mask_Detection 1.py |
| 2 | + |
| 3 | +# Import the necessary packages |
| 4 | +from tensorflow.keras.applications.mobilenet_v2 import preprocess_input |
| 5 | +from tensorflow.keras.preprocessing.image import img_to_array |
| 6 | +from tensorflow.keras.models import load_model |
| 7 | +from imutils.video import VideoStream |
| 8 | +import numpy as np |
| 9 | +import argparse |
| 10 | +import imutils |
| 11 | +import time |
| 12 | +import cv2 |
| 13 | +import os |
| 14 | +import serial |
| 15 | +import PySimpleGUI as sg |
| 16 | + |
| 17 | +sg.theme("GreenTan") |
| 18 | + |
| 19 | +layout_b = [ |
| 20 | + [sg.Frame( |
| 21 | + layout=[ |
| 22 | + [sg.Text("Choose any one of the below actions")], |
| 23 | + ], |
| 24 | + title="", relief=sg.RELIEF_GROOVE, ) |
| 25 | + ], |
| 26 | + [sg.Button("Camera", auto_size_button=True, tooltip="Press it!!"), |
| 27 | + sg.Button("Photo", auto_size_button=True, tooltip="Hey"), |
| 28 | + sg.Graph((125, 50), (0, 0), (125, 50), k='-GRAPH-')], |
| 29 | +] |
| 30 | + |
| 31 | +layout = [ |
| 32 | + [sg.T('The Face Mask Detection', font='_ 18', justification='c', expand_x=True, tooltip="Title")], |
| 33 | + [[layout_b]] |
| 34 | +] |
| 35 | + |
| 36 | +window = sg.Window("The PySimpleGUI", layout, finalize=True, keep_on_top=True) |
| 37 | +window['-GRAPH-'].draw_image(data=sg.EMOJI_BASE64_DREAMING, location=(0, 50)) |
| 38 | + |
| 39 | +while True: |
| 40 | + event, values = window.read() |
| 41 | + |
| 42 | + if event == sg.WIN_CLOSED: |
| 43 | + ch = sg.popup_yes_no("Are you sure you want to exit?", title="YesNo") |
| 44 | + if ch == "Yes": |
| 45 | + break |
| 46 | + |
| 47 | + elif event == "Camera": |
| 48 | + try: |
| 49 | + def detect_and_predict_mask(frame, faceNet, maskNet): |
| 50 | + # Grab the dimensions of the frame and then construct a blob from it |
| 51 | + (h, w) = frame.shape[:2] |
| 52 | + blob = cv2.dnn.blobFromImage(frame, 1.0, (500, 500), (104.0, 177.0, 123.0)) |
| 53 | + |
| 54 | + # Pass the blob through the network and obtain the face detections |
| 55 | + faceNet.setInput(blob) |
| 56 | + detections = faceNet.forward() |
| 57 | + |
| 58 | + # Initialize our list of faces, their corresponding locations and the list of predictions from our |
| 59 | + # face mask network |
| 60 | + faces = [] |
| 61 | + locs = [] |
| 62 | + preds = [] |
| 63 | + |
| 64 | + # Loop over the detections |
| 65 | + for i in range(0, detections.shape[2]): |
| 66 | + # Extract the confidence (i.e., probability) associated with the detection |
| 67 | + confidence = detections[0, 0, i, 2] |
| 68 | + |
| 69 | + # Filter out weak detections by ensuring the confidence is greater than the minimum confidence |
| 70 | + if confidence > args["confidence"]: |
| 71 | + # Compute the (x, y)-coordinates of the bounding box for the object |
| 72 | + box = detections[0, 0, i, 3:7] * np.array([w, h, w, h]) |
| 73 | + (startX, startY, endX, endY) = box.astype("int") |
| 74 | + |
| 75 | + # Ensure the bounding boxes fall within the dimensions of the frame |
| 76 | + (startX, startY) = (max(0, startX), max(0, startY)) |
| 77 | + (endX, endY) = (min(w - 1, endX), min(h - 1, endY)) |
| 78 | + |
| 79 | + # Extract the face ROI(Region of Interest), convert it from BGR to RGB channel ordering, |
| 80 | + # resize it to 224x224, and preprocess it |
| 81 | + face = frame[startY:endY, startX:endX] |
| 82 | + if face.any(): |
| 83 | + face = cv2.cvtColor(face, cv2.COLOR_BGR2RGB) |
| 84 | + face = cv2.resize(face, (224, 224)) |
| 85 | + face = img_to_array(face) |
| 86 | + face = preprocess_input(face) |
| 87 | + |
| 88 | + # Add the face and bounding boxes to their respective lists |
| 89 | + faces.append(face) |
| 90 | + locs.append((startX, startY, endX, endY)) |
| 91 | + |
| 92 | + # Only make a predictions if at least one face was detected |
| 93 | + if len(faces) == 1: |
| 94 | + # For faster inference we'll make batch predictions on *all* faces at the same time |
| 95 | + # rather than one-by-one predictions in the above `for` loop |
| 96 | + faces = np.array(faces, dtype="float32") |
| 97 | + preds = maskNet.predict(faces, batch_size=32) |
| 98 | + |
| 99 | + # Return a 2-tuple(Ordered Pair, For holding two values together of any data type) of the face locations |
| 100 | + # and their corresponding locations |
| 101 | + return locs, preds |
| 102 | + |
| 103 | + |
| 104 | + # Construct the argument parser(To read the file containing the arguments) and parse the arguments |
| 105 | + ap = argparse.ArgumentParser() |
| 106 | + ap.add_argument("-f", "--face", type=str, default="face_detector", |
| 107 | + help="path to face detector model directory") |
| 108 | + ap.add_argument("-m", "--model", type=str, default="mask_detector.model", |
| 109 | + help="path to trained face mask detector model") |
| 110 | + ap.add_argument("-c", "--confidence", type=float, default=0.5, |
| 111 | + help="minimum probability to filter weak detections") |
| 112 | + args = vars(ap.parse_args()) |
| 113 | + |
| 114 | + # Load our serialized face detector model from disk os.path.sep.join is a method used to join components |
| 115 | + # of a file with the appropriate seperator for the current os |
| 116 | + print("[INFO] loading face detector model...") |
| 117 | + prototxtPath = os.path.sep.join( |
| 118 | + [args["face"], "deploy.prototxt"]) # .prototxt defines the architecture and parameters |
| 119 | + weightsPath = os.path.sep.join([args["face"], |
| 120 | + "res10_300x300_ssd_iter_140000.caffemodel"]) # .caffemodel contains the learned |
| 121 | + # weights of the model |
| 122 | + faceNet = cv2.dnn.readNet(prototxtPath, |
| 123 | + weightsPath) # cv2.dnn.readNet is a function from OpenCV's dnn module used |
| 124 | + # to read learning network models |
| 125 | + |
| 126 | + # Load the face mask detector model from disk |
| 127 | + print("[INFO] loading face mask detector model...") |
| 128 | + maskNet = load_model("model.h5") |
| 129 | + |
| 130 | + # Initialize the video stream and allow the camera sensor to warm up |
| 131 | + print("[INFO] starting video stream...") |
| 132 | + vs = VideoStream(src=0).start() |
| 133 | + time.sleep(2.0) |
| 134 | + |
| 135 | + # Loop over the frames from the video stream |
| 136 | + while True: |
| 137 | + # Grab the frame from the threaded video stream and resize it to have a maximum width of 500 pixels ( |
| 138 | + # Chose 400 pixels as a balance between reducing computational load while still maintaining enough |
| 139 | + # detail for the application's needs) |
| 140 | + frame = vs.read() |
| 141 | + frame = imutils.resize(frame, width=500) |
| 142 | + |
| 143 | + # Detect faces in the frame and determine if they are wearing a face mask or not |
| 144 | + (locs, preds) = detect_and_predict_mask(frame, faceNet, maskNet) |
| 145 | + |
| 146 | + # Loop over the detected face locations and their corresponding locations |
| 147 | + for (box, pred) in zip(locs, preds): |
| 148 | + # Unpack the bounding box and predictions |
| 149 | + (startX, startY, endX, endY) = box |
| 150 | + (mask, withoutMask) = pred |
| 151 | + |
| 152 | + # Determine the class label and color we will use to draw the bounding box and text |
| 153 | + label = "Mask" if mask > withoutMask else "No Mask" |
| 154 | + color = (0, 255, 0) if label == "Mask" else (0, 0, 255) |
| 155 | + |
| 156 | + # # Include the probability in the label |
| 157 | + # label = "{}: {:.2f}%".format(label, max(mask, withoutMask) * 100) |
| 158 | + |
| 159 | + # Display the label and bounding box rectangle on the output frame |
| 160 | + cv2.putText(frame, label, (startX, startY - 10), |
| 161 | + cv2.FONT_HERSHEY_SIMPLEX, 0.45, color, 2) |
| 162 | + cv2.rectangle(frame, (startX, startY), (endX, endY), color, 2) |
| 163 | + |
| 164 | + # Show the output frame |
| 165 | + cv2.imshow("Frame", frame) |
| 166 | + key = cv2.waitKey(1) & 0xFF |
| 167 | + |
| 168 | + # If the `q` key was pressed, break from the loop |
| 169 | + if key == ord("q"): |
| 170 | + break |
| 171 | + |
| 172 | + # Cleanup |
| 173 | + cv2.destroyAllWindows() |
| 174 | + vs.stop() |
| 175 | + except Exception as e: |
| 176 | + print(e) |
| 177 | + continue |
| 178 | + |
| 179 | +window.close() |
| 180 | + |
| 181 | +# # Observation: |
| 182 | +# 1)Import the necessary packages |
| 183 | +# 2)We are creating a blob and a screen for our face to be seen and highlighted |
| 184 | +# 3)Next based on the above part we make predictions if atleast 1 face is seen |
| 185 | +# 4)Read the file containing the arguments and parse the arguments like diving the data and running |
| 186 | +# 5)Load the pre-trained model for training and solving the problems |
| 187 | +# 6)Initialise the video screen and let it warm up for a time duration |
| 188 | +# 7)Keep looping until the user clicks the key q or stops running the program |
| 189 | +# 8)Keep a proper cleanup after running |
0 commit comments