diff --git a/.gitattributes b/.gitattributes index a6344aac8c09253b3b630fb776ae94478aa0275b..5fcb453c6e2eb8310b0da96505d649963ce1f979 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,35 +1,38 @@ -*.7z filter=lfs diff=lfs merge=lfs -text -*.arrow filter=lfs diff=lfs merge=lfs -text -*.bin filter=lfs diff=lfs merge=lfs -text -*.bz2 filter=lfs diff=lfs merge=lfs -text -*.ckpt filter=lfs diff=lfs merge=lfs -text -*.ftz filter=lfs diff=lfs merge=lfs -text -*.gz filter=lfs diff=lfs merge=lfs -text -*.h5 filter=lfs diff=lfs merge=lfs -text -*.joblib filter=lfs diff=lfs merge=lfs -text -*.lfs.* filter=lfs diff=lfs merge=lfs -text -*.mlmodel filter=lfs diff=lfs merge=lfs -text -*.model filter=lfs diff=lfs merge=lfs -text -*.msgpack filter=lfs diff=lfs merge=lfs -text -*.npy filter=lfs diff=lfs merge=lfs -text -*.npz filter=lfs diff=lfs merge=lfs -text -*.onnx filter=lfs diff=lfs merge=lfs -text -*.ot filter=lfs diff=lfs merge=lfs -text -*.parquet filter=lfs diff=lfs merge=lfs -text -*.pb filter=lfs diff=lfs merge=lfs -text -*.pickle filter=lfs diff=lfs merge=lfs -text -*.pkl filter=lfs diff=lfs merge=lfs -text -*.pt filter=lfs diff=lfs merge=lfs -text -*.pth filter=lfs diff=lfs merge=lfs -text -*.rar filter=lfs diff=lfs merge=lfs -text -*.safetensors filter=lfs diff=lfs merge=lfs -text -saved_model/**/* filter=lfs diff=lfs merge=lfs -text -*.tar.* filter=lfs diff=lfs merge=lfs -text -*.tar filter=lfs diff=lfs merge=lfs -text -*.tflite filter=lfs diff=lfs merge=lfs -text -*.tgz filter=lfs diff=lfs merge=lfs -text -*.wasm filter=lfs diff=lfs merge=lfs -text -*.xz filter=lfs diff=lfs merge=lfs -text -*.zip filter=lfs diff=lfs merge=lfs -text -*.zst filter=lfs diff=lfs merge=lfs -text -*tfevents* filter=lfs diff=lfs merge=lfs -text +*.7z filter=lfs diff=lfs merge=lfs -text +*.arrow filter=lfs diff=lfs merge=lfs -text +*.bin filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.ckpt filter=lfs diff=lfs merge=lfs -text +*.ftz filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.h5 filter=lfs diff=lfs merge=lfs -text +*.joblib filter=lfs diff=lfs merge=lfs -text +*.lfs.* filter=lfs diff=lfs merge=lfs -text +*.mlmodel filter=lfs diff=lfs merge=lfs -text +*.model filter=lfs diff=lfs merge=lfs -text +*.msgpack filter=lfs diff=lfs merge=lfs -text +*.npy filter=lfs diff=lfs merge=lfs -text +*.npz filter=lfs diff=lfs merge=lfs -text +*.onnx filter=lfs diff=lfs merge=lfs -text +*.ot filter=lfs diff=lfs merge=lfs -text +*.parquet filter=lfs diff=lfs merge=lfs -text +*.pb filter=lfs diff=lfs merge=lfs -text +*.pickle filter=lfs diff=lfs merge=lfs -text +*.pkl filter=lfs diff=lfs merge=lfs -text +*.pt filter=lfs diff=lfs merge=lfs -text +*.pth filter=lfs diff=lfs merge=lfs -text +*.rar filter=lfs diff=lfs merge=lfs -text +*.safetensors filter=lfs diff=lfs merge=lfs -text +saved_model/**/* filter=lfs diff=lfs merge=lfs -text +*.tar.* filter=lfs diff=lfs merge=lfs -text +*.tar filter=lfs diff=lfs merge=lfs -text +*.tflite filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.wasm filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text +*tfevents* filter=lfs diff=lfs merge=lfs -text +res10_300x300_ssd_iter_140000.caffemodel filter=lfs diff=lfs merge=lfs -text +assets/model/mask_detector.keras filter=lfs diff=lfs merge=lfs -text +assets/Mask_detector.mp4 filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..b6e8f56ebc60e33b04aa161f74372071361b3009 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +maskVenv +# /assets/dataset \ No newline at end of file diff --git a/README.md b/README.md index 577f4c2f2897d8959699a5f132f14ca2cfbce69d..5d8f004604b9da7221a3d5d2f60e343d49270d9e 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,13 @@ ---- -title: Real Time Face Mask Detector -emoji: 🦀 -colorFrom: indigo -colorTo: blue -sdk: gradio -sdk_version: 4.36.1 -app_file: app.py -pinned: false ---- - -Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference +--- +title: Mask Detector +emoji: ⚡ +colorFrom: pink +colorTo: green +sdk: gradio +sdk_version: 4.36.1 +app_file: app.py +pinned: false +--- + +Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference + diff --git a/app.py b/app.py new file mode 100644 index 0000000000000000000000000000000000000000..209cba6f3e6e24be9edba36cb6f8a988a925b52f --- /dev/null +++ b/app.py @@ -0,0 +1,128 @@ +# import the necessary packages +from tensorflow.keras.applications.mobilenet_v2 import preprocess_input +from tensorflow.keras.preprocessing.image import img_to_array +from tensorflow.keras.models import load_model +from imutils.video import VideoStream +import numpy as np +import imutils +import time +import cv2 +import os + +import gradio as gr + +# load our serialized face detector model from disk +prototxtPath = r"assets/model/deploy.prototxt.txt" +weightsPath = r"assets/model/res10_300x300_ssd_iter_140000.caffemodel" +faceNet = cv2.dnn.readNet(prototxtPath,weightsPath) + +# load the face mask detector model from disk +maskNet = load_model("assets/model/mask_detector.keras") + + +def detect_and_predict_mask(frame, faceNet, maskNet): + try: + # grab the dimensions of the frame and then construct a blob from it + (h, w) = frame.shape[:2] + blob = cv2.dnn.blobFromImage(frame, 1.0, (224,224),(104.0,177.0,123.0) ) + + # pass the blob through the network and obtain the face detections + faceNet.setInput(blob) + detections = faceNet.forward() + print(detections.shape) + + # initialize our list of faces, their corresponding locations, and the list of predictions from our face mask network + faces = [] + locs = [] + preds = [] + # loop over the detections + for i in range(0,detections.shape[2]): + # extract the confidence (i.e., probability) associated with the detection + confidence = detections[0,0,i,2] + + # filter out weak detections by ensuring the confidence is greater than minimum confidence + if confidence > 0.5: + # compute the (x, y)-cordinates of the bounding box for the object + box = detections[0, 0, i, 3:7] * np.array([w, h, w, h]) + (startX, startY, endX, endY) = box.astype("int") + + # ensure the bounding boxes fall within the dimensions of the frame + (startX , startY) = (max(0,startX) , max(0,startY)) + (endX, endY) = (min(w-1,endX) , min(h-1,endY)) + + # extract the face ROI, convert it from BGR to RGB channel ordering, resize it to 224x224, and preprocess it face=frame[startY:endY, startX:endX] + # bounding mask only for face detected + face = frame[startY:endY , startX:endX] + face = cv2.cvtColor(face, cv2.COLOR_BGR2RGB) + face = cv2.resize(face, (224,224)) + face = img_to_array(face) + face = preprocess_input(face) + + # add the face and bounding boxes to their respective lists + faces.append(face) + locs.append((startX, startY, endX, endY)) + + # only make a predictions if at least one face was detected + if len(faces) > 0: + # far faster inference we'll make batch predictions on *all* faces at the same time rather than one-by-one predictions in the above 'for' loop + faces = np.array(faces,dtype="float32") + preds = maskNet.predict(faces, batch_size=32) + + # return a 2-tuple of the face locations and their corresponding locations + return (locs, preds) + except Exception as e: + print(e) + +def webcam_stream(frame): + if type(frame)==type(None): + return + while True: + try: + # grab the frame from the threaded video stream and resize it to have a max width of 400 pixels + frame = imutils.resize(frame,width=400) + + # detect faces in the frame and determine if they are wearing a face mask or not + (locs, preds) = detect_and_predict_mask(frame, faceNet, maskNet) + + # loop over the detected face locations and their correspondings locations + for (box, pred) in zip(locs, preds): + # unpack the bounding box and predictions + (startX, startY, endX, endY) = box + (mask, withoutMask) = pred + + # determine the class label and color we'll use to draw the bounding box and text + label = "Mask" if mask> withoutMask else "No Mask" + color = (0,255,0) if label=="Mask" else (0,0,255) + + # include the probability in the label + label = "{}: {:.2f}%".format(label,max(mask, withoutMask) *100) + + # display the label and bounding box rectangle on the output frame + cv2.putText(frame,label,(startX,startY-10), cv2.FONT_HERSHEY_SIMPLEX, 0.45, color, 2) + cv2.rectangle(frame, (startX,startY), (endX,endY),color,2) + + + # show the output frame + # cv2.imshow("Frame",frame) + # key = cv2.waitKey(1) & 0xFF + + # if the 'q' key was pressed, break from the loop + # if key == ord("q"): + # break + except Exception as e: + print(e) + + return frame +# do a bit of cleanup +# cv2.destroyAllWindows() + + + +webcam = gr.Image(sources=["webcam"],streaming=True,every="float",mirror_webcam=True) +output = gr.Image(sources=["webcam"]) +# Create a Gradio interface with the webcam_stream function +app = gr.Interface(webcam_stream,inputs=webcam,outputs=output,live=True) + +# Start the app +app.launch() +gr.close_all() \ No newline at end of file diff --git a/assets/Mask_detector.mp4 b/assets/Mask_detector.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..177c8cd1279074ce849cc8b2b9dfee925dd686e9 --- /dev/null +++ b/assets/Mask_detector.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:77737bbeac67b9a50df847b4b4fbc9ad9e14b561469f657466369b0b45452a39 +size 2302102 diff --git a/assets/dataset/with_mask/with_mask_1.jpg b/assets/dataset/with_mask/with_mask_1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2728d8c01a52bc6e1dba34c4833a423a17a650af Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1.jpg differ diff --git a/assets/dataset/with_mask/with_mask_10.jpg b/assets/dataset/with_mask/with_mask_10.jpg new file mode 100644 index 0000000000000000000000000000000000000000..05e39e61e6090baa8ea368068e6100fb2d46795b Binary files /dev/null and b/assets/dataset/with_mask/with_mask_10.jpg differ diff --git a/assets/dataset/with_mask/with_mask_100.jpg b/assets/dataset/with_mask/with_mask_100.jpg new file mode 100644 index 0000000000000000000000000000000000000000..48ffd6e67d9e02d8ef3c61c18ef34573059536a0 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_100.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1000.jpg b/assets/dataset/with_mask/with_mask_1000.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e889f5851441e7e14e5faceec7327cc9a9583912 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1000.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1001.jpg b/assets/dataset/with_mask/with_mask_1001.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6c55ce008f4fe40a92145a4707889a21beab28d7 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1001.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1002.jpg b/assets/dataset/with_mask/with_mask_1002.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6175d9347abf173fe9db86a1b8ad8afcad051e62 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1002.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1003.jpg b/assets/dataset/with_mask/with_mask_1003.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b28559221b3f499197ae01c5d70c54c9012e4680 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1003.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1004.jpg b/assets/dataset/with_mask/with_mask_1004.jpg new file mode 100644 index 0000000000000000000000000000000000000000..413b5a88663238525e4a04f29d8fa57f108f4c8f Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1004.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1005.jpg b/assets/dataset/with_mask/with_mask_1005.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b47cd6c22922a4501d660c28b21c3ed238880b99 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1005.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1006.jpg b/assets/dataset/with_mask/with_mask_1006.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6b44a2dcbfa0b373c05331b6896ccb1799d1497c Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1006.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1007.jpg b/assets/dataset/with_mask/with_mask_1007.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2a79d1e5fc0d3e10dff799834e00d9302c8d7ddb Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1007.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1008.jpg b/assets/dataset/with_mask/with_mask_1008.jpg new file mode 100644 index 0000000000000000000000000000000000000000..118cc1b17ab93ba07dae08139cd7d3f1ea8aeba4 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1008.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1009.jpg b/assets/dataset/with_mask/with_mask_1009.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5f5e8aa4e2ceccc9fbb6205d45ff1fd460740931 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1009.jpg differ diff --git a/assets/dataset/with_mask/with_mask_101.jpg b/assets/dataset/with_mask/with_mask_101.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b5b817828b3cffed150e3566c77ec6a0ea248dfd Binary files /dev/null and b/assets/dataset/with_mask/with_mask_101.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1010.jpg b/assets/dataset/with_mask/with_mask_1010.jpg new file mode 100644 index 0000000000000000000000000000000000000000..539274e1e0cb10134f7a95c6781dd0056615a295 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1010.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1011.jpg b/assets/dataset/with_mask/with_mask_1011.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e434d84f029d48b5c0385f8c66ac46e6c60d426d Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1011.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1012.jpg b/assets/dataset/with_mask/with_mask_1012.jpg new file mode 100644 index 0000000000000000000000000000000000000000..54808aca6f26eb1a3fe82f814c4c829cefa4e647 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1012.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1013.jpg b/assets/dataset/with_mask/with_mask_1013.jpg new file mode 100644 index 0000000000000000000000000000000000000000..335ccb2fc5374b303cbb17cbb31f4a03a31b2734 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1013.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1014.jpg b/assets/dataset/with_mask/with_mask_1014.jpg new file mode 100644 index 0000000000000000000000000000000000000000..03d4cee908031ed195f95313d2f3b689c1e21b39 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1014.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1015.jpg b/assets/dataset/with_mask/with_mask_1015.jpg new file mode 100644 index 0000000000000000000000000000000000000000..779e643e0b8ac48e9ba8838100f7caae0085f638 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1015.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1016.jpg b/assets/dataset/with_mask/with_mask_1016.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2dbea66d721ecfb980e0b9fb460ccbc1c651d881 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1016.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1017.jpg b/assets/dataset/with_mask/with_mask_1017.jpg new file mode 100644 index 0000000000000000000000000000000000000000..59cb6ee6f68847b933ae505c964e78551811b679 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1017.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1018.jpg b/assets/dataset/with_mask/with_mask_1018.jpg new file mode 100644 index 0000000000000000000000000000000000000000..48dd73c8c4e8cbc785dbdc20887c0fb53e411d3a Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1018.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1019.jpg b/assets/dataset/with_mask/with_mask_1019.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bec909cacdeaad29c347863b18d014d4eeb6753a Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1019.jpg differ diff --git a/assets/dataset/with_mask/with_mask_102.jpg b/assets/dataset/with_mask/with_mask_102.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d84491f74103351c342ee70430fe6f2b6b861b2f Binary files /dev/null and b/assets/dataset/with_mask/with_mask_102.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1020.jpg b/assets/dataset/with_mask/with_mask_1020.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2262466749763c016ed6440313d91d20ead4de02 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1020.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1021.jpg b/assets/dataset/with_mask/with_mask_1021.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f357c2d24fe0de0688d8faefbf05ace65fb639da Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1021.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1022.jpg b/assets/dataset/with_mask/with_mask_1022.jpg new file mode 100644 index 0000000000000000000000000000000000000000..499d90d46661203ad7a5ea76c93d1264f9422db4 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1022.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1023.jpg b/assets/dataset/with_mask/with_mask_1023.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6d1f754443690fd7bac91408bc65dd8054d92052 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1023.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1024.jpg b/assets/dataset/with_mask/with_mask_1024.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0b4a3635f6a8e8cd15b7df71400ac2ae10c1d53d Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1024.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1025.jpg b/assets/dataset/with_mask/with_mask_1025.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ef3a1b116080168f27acf5620b9d330432417596 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1025.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1026.jpg b/assets/dataset/with_mask/with_mask_1026.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b069a4a1310f35d9b17dc9f99a4e77e0150fb66c Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1026.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1027.jpg b/assets/dataset/with_mask/with_mask_1027.jpg new file mode 100644 index 0000000000000000000000000000000000000000..146ab9fee3d4d00bb4c06426b534fcb6b7adb3d1 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1027.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1028.jpg b/assets/dataset/with_mask/with_mask_1028.jpg new file mode 100644 index 0000000000000000000000000000000000000000..30e1b8c780cb335e5866be9c51f334fcd5c8750d Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1028.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1029.jpg b/assets/dataset/with_mask/with_mask_1029.jpg new file mode 100644 index 0000000000000000000000000000000000000000..22e6e1e9fcef1f9f2b797859b035d1624cdc79e7 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1029.jpg differ diff --git a/assets/dataset/with_mask/with_mask_103.jpg b/assets/dataset/with_mask/with_mask_103.jpg new file mode 100644 index 0000000000000000000000000000000000000000..065d03aaead6464c557be992d1931c3ad8d1e4f5 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_103.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1030.jpg b/assets/dataset/with_mask/with_mask_1030.jpg new file mode 100644 index 0000000000000000000000000000000000000000..31e53ade0ed16dfbd5a0890f8d5c7bbd5508e5c8 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1030.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1031.jpg b/assets/dataset/with_mask/with_mask_1031.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9c1a111330bd397a847a3d3ded0bb75311fe202c Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1031.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1032.jpg b/assets/dataset/with_mask/with_mask_1032.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b4a8d67065e2052f51033ace0b192f986d596588 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1032.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1033.jpg b/assets/dataset/with_mask/with_mask_1033.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7494e71ad26791eba6abc6534677f75c0e33427a Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1033.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1034.jpg b/assets/dataset/with_mask/with_mask_1034.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b666c56a83e82d0670c1bca9e36dc202b518fe16 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1034.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1035.jpg b/assets/dataset/with_mask/with_mask_1035.jpg new file mode 100644 index 0000000000000000000000000000000000000000..728873396f8efdb0d893d6270884203c3d4e2846 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1035.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1036.jpg b/assets/dataset/with_mask/with_mask_1036.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ce177be9f862561e4396103a4088f7085f587b5f Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1036.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1037.jpg b/assets/dataset/with_mask/with_mask_1037.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f8ad3c3f7986a4e0c449db5664eb1933f9aed916 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1037.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1038.jpg b/assets/dataset/with_mask/with_mask_1038.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c15cf66712a4910211baf8302f256c91525b6db5 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1038.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1039.jpg b/assets/dataset/with_mask/with_mask_1039.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d30b0bfc94d1bcf0f656e0eac2a6eeb19dc5b451 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1039.jpg differ diff --git a/assets/dataset/with_mask/with_mask_104.jpg b/assets/dataset/with_mask/with_mask_104.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e0989d97b6f544b39c7d31f426119e6fdafbda42 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_104.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1040.jpg b/assets/dataset/with_mask/with_mask_1040.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9c8ebf29de9dd02d4a35ad4ffe66e9b9c8a1415a Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1040.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1041.jpg b/assets/dataset/with_mask/with_mask_1041.jpg new file mode 100644 index 0000000000000000000000000000000000000000..86336de8e0f018fbc2b1a5d82acf5cd7985fc420 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1041.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1042.jpg b/assets/dataset/with_mask/with_mask_1042.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e9447c9a508c5062811a913f587bab46ac5a5efd Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1042.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1043.jpg b/assets/dataset/with_mask/with_mask_1043.jpg new file mode 100644 index 0000000000000000000000000000000000000000..aef2501ed0f8e44bb1e6be89d088b062ceb89254 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1043.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1044.jpg b/assets/dataset/with_mask/with_mask_1044.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cc15aac90739167d19df43cc0b83b39b7c500c36 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1044.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1045.jpg b/assets/dataset/with_mask/with_mask_1045.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f9de21d929183c56627b05d1ce3bd74a2b1aaa83 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1045.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1046.jpg b/assets/dataset/with_mask/with_mask_1046.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e5bec4f7a9a34c80531d380d9941ac8f0f8c4561 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1046.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1047.jpg b/assets/dataset/with_mask/with_mask_1047.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a8a7fca9b4e82669c6db22fd7f7324141d319889 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1047.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1048.jpg b/assets/dataset/with_mask/with_mask_1048.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e27ba1bee2606ca245689ba18ceaeb566d79a718 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1048.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1049.jpg b/assets/dataset/with_mask/with_mask_1049.jpg new file mode 100644 index 0000000000000000000000000000000000000000..741ecd4fce7bfa92dea5634316259ad7eab5bb4b Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1049.jpg differ diff --git a/assets/dataset/with_mask/with_mask_105.jpg b/assets/dataset/with_mask/with_mask_105.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1a5fc45eacc1e06e0d9bf374700a82eb7b227165 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_105.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1050.jpg b/assets/dataset/with_mask/with_mask_1050.jpg new file mode 100644 index 0000000000000000000000000000000000000000..55aeb41aca4347bfdbc1ea18c8154bfb203b0b52 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1050.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1051.jpg b/assets/dataset/with_mask/with_mask_1051.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3f34d2ffafb268ea5d95488aee4e3f06c15a5f22 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1051.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1052.jpg b/assets/dataset/with_mask/with_mask_1052.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e13e6f05d092e086a24dbf8b8a2600df1d922998 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1052.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1053.jpg b/assets/dataset/with_mask/with_mask_1053.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0742dad0664c69b28f56aaaebf3b396e94256892 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1053.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1054.jpg b/assets/dataset/with_mask/with_mask_1054.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cc585e566bf0bc762abef5094a381cd37b068e67 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1054.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1055.jpg b/assets/dataset/with_mask/with_mask_1055.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ea8d05965ff927e879326fcafa1168a7307272f9 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1055.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1056.jpg b/assets/dataset/with_mask/with_mask_1056.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fb6f16fc2faf32adfb8560cede5df19aad0dc8f6 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1056.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1057.jpg b/assets/dataset/with_mask/with_mask_1057.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6070b16f58777400aeb7dab80893769948c5a0e3 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1057.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1058.jpg b/assets/dataset/with_mask/with_mask_1058.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f15312a3fbd4f8dc155d89b17fd4c61300096077 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1058.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1059.jpg b/assets/dataset/with_mask/with_mask_1059.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8343a5a917bfde369ec328d5b1a9b112b3dba2a8 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1059.jpg differ diff --git a/assets/dataset/with_mask/with_mask_106.jpg b/assets/dataset/with_mask/with_mask_106.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b285a04ca18f9127a458c4172c47fb445698e94e Binary files /dev/null and b/assets/dataset/with_mask/with_mask_106.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1060.jpg b/assets/dataset/with_mask/with_mask_1060.jpg new file mode 100644 index 0000000000000000000000000000000000000000..857f788b1f42530fd3073e3ef6c279ba889fca54 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1060.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1061.jpg b/assets/dataset/with_mask/with_mask_1061.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4a8f60be46691978507af02f21bc4a7d7b2a7381 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1061.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1062.jpg b/assets/dataset/with_mask/with_mask_1062.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0df16f576233f819e81b3ff5b178d47490a4a3ba Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1062.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1063.jpg b/assets/dataset/with_mask/with_mask_1063.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7e31a8562daf4c30c5079316922fee36f4a4fe98 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1063.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1064.jpg b/assets/dataset/with_mask/with_mask_1064.jpg new file mode 100644 index 0000000000000000000000000000000000000000..84e2cc19e39fb8c9ff4476465b4487aa52721b04 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1064.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1065.jpg b/assets/dataset/with_mask/with_mask_1065.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bbea16d3d8bbb152c8730a59ce23836757e42484 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1065.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1066.jpg b/assets/dataset/with_mask/with_mask_1066.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4a5072ae6a745ce51aab03e566a4849458fb038f Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1066.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1067.jpg b/assets/dataset/with_mask/with_mask_1067.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e8b0af9aee6fbdc08c85b7cb20194e9b0140657d Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1067.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1068.jpg b/assets/dataset/with_mask/with_mask_1068.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2126a1c0b4c9cc6463f792c56b1fc794dd5125a1 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1068.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1069.jpg b/assets/dataset/with_mask/with_mask_1069.jpg new file mode 100644 index 0000000000000000000000000000000000000000..da659ad0fe155feba6ef3e1cc5d7e69549c59cfd Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1069.jpg differ diff --git a/assets/dataset/with_mask/with_mask_107.jpg b/assets/dataset/with_mask/with_mask_107.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5a0de1cae95e5c3b0efa661aa8e2cd8eeb8d1266 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_107.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1070.jpg b/assets/dataset/with_mask/with_mask_1070.jpg new file mode 100644 index 0000000000000000000000000000000000000000..41bbd840c6e3f9e69e652a4b0fa59a5d0ba8100c Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1070.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1071.jpg b/assets/dataset/with_mask/with_mask_1071.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ec748d1f88b92ea5dccea38bb76980ec9214a8aa Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1071.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1072.jpg b/assets/dataset/with_mask/with_mask_1072.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3560d1c2a54315d9e6997040e2e3ac5be028cae6 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1072.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1073.jpg b/assets/dataset/with_mask/with_mask_1073.jpg new file mode 100644 index 0000000000000000000000000000000000000000..85de43ff27efbcef21161e953055d21ce7e43aba Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1073.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1074.jpg b/assets/dataset/with_mask/with_mask_1074.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2d1ef1e62198c68f7f34013d9242a25a892cf23a Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1074.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1075.jpg b/assets/dataset/with_mask/with_mask_1075.jpg new file mode 100644 index 0000000000000000000000000000000000000000..70c13828ab3a48fdd6e3be297418bd47102827e4 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1075.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1076.jpg b/assets/dataset/with_mask/with_mask_1076.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7d4dea5804a42edc490daf9b59f79e3866f3fd96 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1076.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1077.jpg b/assets/dataset/with_mask/with_mask_1077.jpg new file mode 100644 index 0000000000000000000000000000000000000000..755e282f144cd855c042edf4c89f43f3baeec7dc Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1077.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1078.jpg b/assets/dataset/with_mask/with_mask_1078.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fd57f98990497bd496bbcad34d80f5d28686a23a Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1078.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1079.jpg b/assets/dataset/with_mask/with_mask_1079.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d541543bafa2ba24a8cf72de11488b083c679cfa Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1079.jpg differ diff --git a/assets/dataset/with_mask/with_mask_108.jpg b/assets/dataset/with_mask/with_mask_108.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9edda6302f87e5167c1e6490fb6b4f9733f07bbb Binary files /dev/null and b/assets/dataset/with_mask/with_mask_108.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1080.jpg b/assets/dataset/with_mask/with_mask_1080.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6ff62b1bf1462630739c856a36bd2f8398fd8236 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1080.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1081.jpg b/assets/dataset/with_mask/with_mask_1081.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7d189f9f7a21ed63164a17a054ae48e7462a2056 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1081.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1082.jpg b/assets/dataset/with_mask/with_mask_1082.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a53291fc8a9c9480badb633893b309ac80283dd2 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1082.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1083.jpg b/assets/dataset/with_mask/with_mask_1083.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b2174742fc5c5a2c14f7a5125e7e1007a2ea6aa7 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1083.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1084.jpg b/assets/dataset/with_mask/with_mask_1084.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e5dfa3fe864224adfcfd2d402e0b3384ccfbd1a4 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1084.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1085.jpg b/assets/dataset/with_mask/with_mask_1085.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e5ddb5b803c562e1e4a20dd87dc24cadb279e893 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1085.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1086.jpg b/assets/dataset/with_mask/with_mask_1086.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e320751b4d30d6e40f4d41f6d1fba8b22fa59955 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1086.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1087.jpg b/assets/dataset/with_mask/with_mask_1087.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bb2bdffc292ecac0eb16cc6d0c2a31ed362935b1 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1087.jpg differ diff --git a/assets/dataset/with_mask/with_mask_1088.jpg b/assets/dataset/with_mask/with_mask_1088.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f66f9fae9816208100a21fede6a0ba3faa8f7311 Binary files /dev/null and b/assets/dataset/with_mask/with_mask_1088.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1.jpg b/assets/dataset/without_mask/without_mask_1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..883d0ab50ab0a668b4d24bec47ab8c79347e1dc1 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1.jpg differ diff --git a/assets/dataset/without_mask/without_mask_10.jpg b/assets/dataset/without_mask/without_mask_10.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2414b456b9bd5ec7166928c4e2340374442da4ac Binary files /dev/null and b/assets/dataset/without_mask/without_mask_10.jpg differ diff --git a/assets/dataset/without_mask/without_mask_100.jpg b/assets/dataset/without_mask/without_mask_100.jpg new file mode 100644 index 0000000000000000000000000000000000000000..36a4f1a21d8f7aef0971c882cbb495e22608fc3b Binary files /dev/null and b/assets/dataset/without_mask/without_mask_100.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1000.jpg b/assets/dataset/without_mask/without_mask_1000.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ab956265449d43309d8ec5ff726509e8e65da4ed Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1000.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1001.jpg b/assets/dataset/without_mask/without_mask_1001.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0f344f75c3f4d6049fc0a7f7094518b311a41914 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1001.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1002.jpg b/assets/dataset/without_mask/without_mask_1002.jpg new file mode 100644 index 0000000000000000000000000000000000000000..69ff6d1ab6a734adfe734c4b923e02a707c7235e Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1002.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1003.jpg b/assets/dataset/without_mask/without_mask_1003.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e3ddbabc44374ba3b7c6fd3382a5a36ee78d79cd Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1003.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1004.jpg b/assets/dataset/without_mask/without_mask_1004.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7019a556cb4941a2f69e7af3beed1d9e3cfb53ef Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1004.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1005.jpg b/assets/dataset/without_mask/without_mask_1005.jpg new file mode 100644 index 0000000000000000000000000000000000000000..360b3412fc674e5174e27fbaa629b65e086ab60e Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1005.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1006.jpg b/assets/dataset/without_mask/without_mask_1006.jpg new file mode 100644 index 0000000000000000000000000000000000000000..01edda3e6a9a9dcc00a621e513202f5c559392b5 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1006.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1007.jpg b/assets/dataset/without_mask/without_mask_1007.jpg new file mode 100644 index 0000000000000000000000000000000000000000..893cb79d4731889f35b218cf6d3f3f9e9ffff18c Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1007.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1008.jpg b/assets/dataset/without_mask/without_mask_1008.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7db0761ee686f567b75ab6dadf002ab35aad6a6c Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1008.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1009.jpg b/assets/dataset/without_mask/without_mask_1009.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bf6a0b5d145da53b415ba86f57ef3187a8a163f5 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1009.jpg differ diff --git a/assets/dataset/without_mask/without_mask_101.jpg b/assets/dataset/without_mask/without_mask_101.jpg new file mode 100644 index 0000000000000000000000000000000000000000..eca52feb3f3f31aadc99f7b26ae7865372288e1e Binary files /dev/null and b/assets/dataset/without_mask/without_mask_101.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1010.jpg b/assets/dataset/without_mask/without_mask_1010.jpg new file mode 100644 index 0000000000000000000000000000000000000000..03f31ed1981466dcc03ba71cf36fd5ebc98cd3c9 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1010.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1011.jpg b/assets/dataset/without_mask/without_mask_1011.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4abaa530547033fab998490f3b8d14120b467043 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1011.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1012.jpg b/assets/dataset/without_mask/without_mask_1012.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0ac58e57e3ef37240ae3afa7644c801331b0b4d5 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1012.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1013.jpg b/assets/dataset/without_mask/without_mask_1013.jpg new file mode 100644 index 0000000000000000000000000000000000000000..535c64084410891a03fe7282a4ef16084df5af88 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1013.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1014.jpg b/assets/dataset/without_mask/without_mask_1014.jpg new file mode 100644 index 0000000000000000000000000000000000000000..61b940e7881ead2b9420a409a2825e1a7d390851 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1014.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1015.jpg b/assets/dataset/without_mask/without_mask_1015.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c913481414445042e4e3b29c6bedf90bcbe2561a Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1015.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1016.jpg b/assets/dataset/without_mask/without_mask_1016.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cb978c08a0e4191e5c58bb6ae2baf90db3524224 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1016.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1017.jpg b/assets/dataset/without_mask/without_mask_1017.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f7e2090d077edd37f93dcecd5785fcac9b84e619 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1017.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1018.jpg b/assets/dataset/without_mask/without_mask_1018.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6bf72396e3d5282cc7d601e545e141e4712d161b Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1018.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1019.jpg b/assets/dataset/without_mask/without_mask_1019.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7bafcf7ae63732901b88d8230a945b1bd85a2241 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1019.jpg differ diff --git a/assets/dataset/without_mask/without_mask_102.jpg b/assets/dataset/without_mask/without_mask_102.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ed73c09771eff6ef31eae6347d754787d7d4dd99 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_102.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1020.jpg b/assets/dataset/without_mask/without_mask_1020.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bb1c9505e13d9b9b8d31bed76cf6cac9835ce4f7 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1020.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1021.jpg b/assets/dataset/without_mask/without_mask_1021.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5532fdd0387fdf6a0173aa54be2b5124a266a0af Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1021.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1022.jpg b/assets/dataset/without_mask/without_mask_1022.jpg new file mode 100644 index 0000000000000000000000000000000000000000..44edbf2576672b0fdb221b7e5d0bfc005bc788cd Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1022.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1023.jpg b/assets/dataset/without_mask/without_mask_1023.jpg new file mode 100644 index 0000000000000000000000000000000000000000..41e5202874321d951977687e3ebf6152287ad6c6 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1023.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1024.jpg b/assets/dataset/without_mask/without_mask_1024.jpg new file mode 100644 index 0000000000000000000000000000000000000000..de95071daa5210f97d89b146a3a81a7724f8c828 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1024.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1025.jpg b/assets/dataset/without_mask/without_mask_1025.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f2aa591987bdb3b7252c80ff4dded11624f77356 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1025.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1026.jpg b/assets/dataset/without_mask/without_mask_1026.jpg new file mode 100644 index 0000000000000000000000000000000000000000..832ba8ef5c07e72ad0b002d9e5aee86b80e0cf10 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1026.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1027.jpg b/assets/dataset/without_mask/without_mask_1027.jpg new file mode 100644 index 0000000000000000000000000000000000000000..858bc1e36785af1488cbe1a66c0eec4d3c2c3245 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1027.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1028.jpg b/assets/dataset/without_mask/without_mask_1028.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5eda4141303b7c7aeaaa8eb92020f220e7aa0ba1 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1028.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1029.jpg b/assets/dataset/without_mask/without_mask_1029.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bf8c028490c694714a7ab61f4ab20e95db1818e4 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1029.jpg differ diff --git a/assets/dataset/without_mask/without_mask_103.jpg b/assets/dataset/without_mask/without_mask_103.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e667a336a45f814fb9aa90219b653e606cf37095 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_103.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1030.jpg b/assets/dataset/without_mask/without_mask_1030.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b9bf2871b375bed3ea4f91092bae163fb8f067e3 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1030.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1031.jpg b/assets/dataset/without_mask/without_mask_1031.jpg new file mode 100644 index 0000000000000000000000000000000000000000..502df14afeeda7fa65404f32b4ee034c0c5ae2bd Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1031.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1032.jpg b/assets/dataset/without_mask/without_mask_1032.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d3a332b199818bb2705a81577b4ce19d629ce86e Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1032.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1033.jpg b/assets/dataset/without_mask/without_mask_1033.jpg new file mode 100644 index 0000000000000000000000000000000000000000..deb8e04791c39100ae87c936df1641e2d616a32f Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1033.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1034.jpg b/assets/dataset/without_mask/without_mask_1034.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e05d4c7b2efbf0888333bfb8d98e9f938541776c Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1034.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1035.jpg b/assets/dataset/without_mask/without_mask_1035.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1eaeec17eca49be7700879428da65599a7dd10eb Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1035.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1036.jpg b/assets/dataset/without_mask/without_mask_1036.jpg new file mode 100644 index 0000000000000000000000000000000000000000..010c3bc33b82f9181c5c97e0c5f846db2ce8f373 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1036.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1037.jpg b/assets/dataset/without_mask/without_mask_1037.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a51122dcddce5a575260947612ae19c9fb53a0aa Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1037.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1038.jpg b/assets/dataset/without_mask/without_mask_1038.jpg new file mode 100644 index 0000000000000000000000000000000000000000..05886274354accb9905ca569ac69c72cedc21f9c Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1038.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1039.jpg b/assets/dataset/without_mask/without_mask_1039.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7e96ce5ec4edbbef816ac614e0001c4a23a168c3 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1039.jpg differ diff --git a/assets/dataset/without_mask/without_mask_104.jpg b/assets/dataset/without_mask/without_mask_104.jpg new file mode 100644 index 0000000000000000000000000000000000000000..dea98ca8a90ffebd22916b9818e9197e8608c4ea Binary files /dev/null and b/assets/dataset/without_mask/without_mask_104.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1040.jpg b/assets/dataset/without_mask/without_mask_1040.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7b31807811869ba774eee2ea6b11fd3fa16b30a6 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1040.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1041.jpg b/assets/dataset/without_mask/without_mask_1041.jpg new file mode 100644 index 0000000000000000000000000000000000000000..850f32269cf4a7dbae6e008884eb9153d29bea2a Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1041.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1042.jpg b/assets/dataset/without_mask/without_mask_1042.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1b363fe0d8155947a3733d1f6bdaa27f8ebce6ff Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1042.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1043.jpg b/assets/dataset/without_mask/without_mask_1043.jpg new file mode 100644 index 0000000000000000000000000000000000000000..431deebc5a77e193af99c264191e0d49127a867a Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1043.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1044.jpg b/assets/dataset/without_mask/without_mask_1044.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9e20614e1652bf908777fe171f0bbb4c0fe1afff Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1044.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1045.jpg b/assets/dataset/without_mask/without_mask_1045.jpg new file mode 100644 index 0000000000000000000000000000000000000000..750e71ba9e43fa825b23b72aef52967917b92127 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1045.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1046.jpg b/assets/dataset/without_mask/without_mask_1046.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9e1f4ec0c0118aac751eda62e407b0e5238e784f Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1046.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1047.jpg b/assets/dataset/without_mask/without_mask_1047.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a344873cf15368c29de80168428c6e2937abbfe3 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1047.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1048.jpg b/assets/dataset/without_mask/without_mask_1048.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c9e3cf7a7365a5ff86ee8d88bc7dfdb6c62cb2ec Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1048.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1049.jpg b/assets/dataset/without_mask/without_mask_1049.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fd4c0d1b7b5057cbd3902743b3b4ed41c4353673 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1049.jpg differ diff --git a/assets/dataset/without_mask/without_mask_105.jpg b/assets/dataset/without_mask/without_mask_105.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cad27994f1fa179aaea449806ac9cac3c3619d71 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_105.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1050.jpg b/assets/dataset/without_mask/without_mask_1050.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2aeedce46f18b9f9285e1cdae78f4a5c2415eb4c Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1050.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1051.jpg b/assets/dataset/without_mask/without_mask_1051.jpg new file mode 100644 index 0000000000000000000000000000000000000000..97f85276a320a2b006d8ec7bb8244aa9e6176514 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1051.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1052.jpg b/assets/dataset/without_mask/without_mask_1052.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f97991eb913b1799658f6ca77093994bb5a97678 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1052.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1053.jpg b/assets/dataset/without_mask/without_mask_1053.jpg new file mode 100644 index 0000000000000000000000000000000000000000..69952817614c1da6daab6daa5b630b7d0e48ac7f Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1053.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1054.jpg b/assets/dataset/without_mask/without_mask_1054.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a1b90ecc74f33800c4045bc4852852fd85a70476 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1054.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1055.jpg b/assets/dataset/without_mask/without_mask_1055.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6ccae8d99966d37ce2146ca7f991a4eefff9f9ff Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1055.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1056.jpg b/assets/dataset/without_mask/without_mask_1056.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0782e40957efd3dc5724a6042056223b68d7cf46 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1056.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1057.jpg b/assets/dataset/without_mask/without_mask_1057.jpg new file mode 100644 index 0000000000000000000000000000000000000000..210577425496666919cbc3997c078f27ee2374e1 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1057.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1058.jpg b/assets/dataset/without_mask/without_mask_1058.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f155c95082319e86b5252d19ec2b8cedafac8753 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1058.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1059.jpg b/assets/dataset/without_mask/without_mask_1059.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1cc552c5dfe703880d203f63af801c167b949f04 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1059.jpg differ diff --git a/assets/dataset/without_mask/without_mask_106.jpg b/assets/dataset/without_mask/without_mask_106.jpg new file mode 100644 index 0000000000000000000000000000000000000000..91f5a1c3c936b51cf0a26581a54823ee45152562 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_106.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1060.jpg b/assets/dataset/without_mask/without_mask_1060.jpg new file mode 100644 index 0000000000000000000000000000000000000000..333d3124afe8d3355fa5e140610895c4c957b943 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1060.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1061.jpg b/assets/dataset/without_mask/without_mask_1061.jpg new file mode 100644 index 0000000000000000000000000000000000000000..da809163bdecda272cc2f98ac502549d298bdc92 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1061.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1062.jpg b/assets/dataset/without_mask/without_mask_1062.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f8c13d46642dda9c6c63b3c7cd9c57995ac6fc5d Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1062.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1063.jpg b/assets/dataset/without_mask/without_mask_1063.jpg new file mode 100644 index 0000000000000000000000000000000000000000..aaaabfef011290d154345307de09fc7c3536bad5 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1063.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1064.jpg b/assets/dataset/without_mask/without_mask_1064.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4a5ac68a0a14db8020e971583c03cf0c9a6b386a Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1064.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1065.jpg b/assets/dataset/without_mask/without_mask_1065.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9aa32ed84ac17ca9e770b3067a6b43cc94fe6d53 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1065.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1066.jpg b/assets/dataset/without_mask/without_mask_1066.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bb1bf27d5b09a10d3882ebe4254785ed4ff5257e Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1066.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1067.jpg b/assets/dataset/without_mask/without_mask_1067.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3faf41e60e55d3311cac9cf56136fe16e2e09f6c Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1067.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1068.jpg b/assets/dataset/without_mask/without_mask_1068.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fa055e58c4828d74d10bcf3d39634c8f82153d09 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1068.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1069.jpg b/assets/dataset/without_mask/without_mask_1069.jpg new file mode 100644 index 0000000000000000000000000000000000000000..746865229a548993ccae2fbaeec9ec9fb9b77745 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1069.jpg differ diff --git a/assets/dataset/without_mask/without_mask_107.jpg b/assets/dataset/without_mask/without_mask_107.jpg new file mode 100644 index 0000000000000000000000000000000000000000..930380b262915be315b342d5c70585fe9168aa44 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_107.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1070.jpg b/assets/dataset/without_mask/without_mask_1070.jpg new file mode 100644 index 0000000000000000000000000000000000000000..45934db40fddac4ac19a587075c7a94b1db9cedc Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1070.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1071.jpg b/assets/dataset/without_mask/without_mask_1071.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1f5ef6c33bdcb8b5cb32f8c81c9d7cd84f614b26 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1071.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1072.jpg b/assets/dataset/without_mask/without_mask_1072.jpg new file mode 100644 index 0000000000000000000000000000000000000000..56242b50cd151be390ead9b4effec08ff5c078c7 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1072.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1073.jpg b/assets/dataset/without_mask/without_mask_1073.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0d2c24eb1914617b5dfca0751731f55b5440a5ba Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1073.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1074.jpg b/assets/dataset/without_mask/without_mask_1074.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5892a6b774b9557c2c1c3e40e79108f19dc6cff9 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1074.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1075.jpg b/assets/dataset/without_mask/without_mask_1075.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4e15099b4e74ddfe5b400bc522552d64a9d36065 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1075.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1076.jpg b/assets/dataset/without_mask/without_mask_1076.jpg new file mode 100644 index 0000000000000000000000000000000000000000..98199dd375ee5adc35915db38daf6fb8adc52d10 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1076.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1077.jpg b/assets/dataset/without_mask/without_mask_1077.jpg new file mode 100644 index 0000000000000000000000000000000000000000..831c3a0f2a20acf427952264cd93dbd2bf55fe9b Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1077.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1078.jpg b/assets/dataset/without_mask/without_mask_1078.jpg new file mode 100644 index 0000000000000000000000000000000000000000..62b6164f1cbefa63ee8a410bfb9262bc977f4964 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1078.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1079.jpg b/assets/dataset/without_mask/without_mask_1079.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ce832ef3c0cde6bef4dc37783f55de2fdc1b8ba9 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1079.jpg differ diff --git a/assets/dataset/without_mask/without_mask_108.jpg b/assets/dataset/without_mask/without_mask_108.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d9c5533f6c1f45937043f6c4d4359cb0d9b76cae Binary files /dev/null and b/assets/dataset/without_mask/without_mask_108.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1080.jpg b/assets/dataset/without_mask/without_mask_1080.jpg new file mode 100644 index 0000000000000000000000000000000000000000..54490843a78101dbd5cb31cc1721e1fe2c08796c Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1080.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1081.jpg b/assets/dataset/without_mask/without_mask_1081.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9464b3344ea59295c1daec8ffad012fa1e20171a Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1081.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1082.jpg b/assets/dataset/without_mask/without_mask_1082.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bf898179ef1e9ed1794531bda4e278f90d5d32bd Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1082.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1083.jpg b/assets/dataset/without_mask/without_mask_1083.jpg new file mode 100644 index 0000000000000000000000000000000000000000..132b51e44e2d0470580db7917c75a1773945a2da Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1083.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1084.jpg b/assets/dataset/without_mask/without_mask_1084.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bc51642c585acb14c2dba1663828e4917ea1ca07 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1084.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1085.jpg b/assets/dataset/without_mask/without_mask_1085.jpg new file mode 100644 index 0000000000000000000000000000000000000000..48d89b48f4b201b9184da6e48d3cb3509b8a7fe2 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1085.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1086.jpg b/assets/dataset/without_mask/without_mask_1086.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d9a167b039a5656c7fc5de71ca8aa54a649374e8 Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1086.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1087.jpg b/assets/dataset/without_mask/without_mask_1087.jpg new file mode 100644 index 0000000000000000000000000000000000000000..df80ac1b21141e995bc9bd503f76e41064e0c72b Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1087.jpg differ diff --git a/assets/dataset/without_mask/without_mask_1088.jpg b/assets/dataset/without_mask/without_mask_1088.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6efa1640a72aacbb4a630e233b08a5056b26a95b Binary files /dev/null and b/assets/dataset/without_mask/without_mask_1088.jpg differ diff --git a/assets/model/deploy.prototxt.txt b/assets/model/deploy.prototxt.txt new file mode 100644 index 0000000000000000000000000000000000000000..b4ca0a0830aa9116946dfbf8ecf39d70cde611d1 --- /dev/null +++ b/assets/model/deploy.prototxt.txt @@ -0,0 +1,1789 @@ +input: "data" +input_shape { + dim: 1 + dim: 3 + dim: 300 + dim: 300 +} + +layer { + name: "data_bn" + type: "BatchNorm" + bottom: "data" + top: "data_bn" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "data_scale" + type: "Scale" + bottom: "data_bn" + top: "data_bn" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "conv1_h" + type: "Convolution" + bottom: "data_bn" + top: "conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 32 + pad: 3 + kernel_size: 7 + stride: 2 + weight_filler { + type: "msra" + variance_norm: FAN_OUT + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv1_bn_h" + type: "BatchNorm" + bottom: "conv1_h" + top: "conv1_h" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "conv1_scale_h" + type: "Scale" + bottom: "conv1_h" + top: "conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "conv1_relu" + type: "ReLU" + bottom: "conv1_h" + top: "conv1_h" +} +layer { + name: "conv1_pool" + type: "Pooling" + bottom: "conv1_h" + top: "conv1_pool" + pooling_param { + kernel_size: 3 + stride: 2 + } +} +layer { + name: "layer_64_1_conv1_h" + type: "Convolution" + bottom: "conv1_pool" + top: "layer_64_1_conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 32 + bias_term: false + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_64_1_bn2_h" + type: "BatchNorm" + bottom: "layer_64_1_conv1_h" + top: "layer_64_1_conv1_h" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "layer_64_1_scale2_h" + type: "Scale" + bottom: "layer_64_1_conv1_h" + top: "layer_64_1_conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "layer_64_1_relu2" + type: "ReLU" + bottom: "layer_64_1_conv1_h" + top: "layer_64_1_conv1_h" +} +layer { + name: "layer_64_1_conv2_h" + type: "Convolution" + bottom: "layer_64_1_conv1_h" + top: "layer_64_1_conv2_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 32 + bias_term: false + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_64_1_sum" + type: "Eltwise" + bottom: "layer_64_1_conv2_h" + bottom: "conv1_pool" + top: "layer_64_1_sum" +} +layer { + name: "layer_128_1_bn1_h" + type: "BatchNorm" + bottom: "layer_64_1_sum" + top: "layer_128_1_bn1_h" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "layer_128_1_scale1_h" + type: "Scale" + bottom: "layer_128_1_bn1_h" + top: "layer_128_1_bn1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "layer_128_1_relu1" + type: "ReLU" + bottom: "layer_128_1_bn1_h" + top: "layer_128_1_bn1_h" +} +layer { + name: "layer_128_1_conv1_h" + type: "Convolution" + bottom: "layer_128_1_bn1_h" + top: "layer_128_1_conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 128 + bias_term: false + pad: 1 + kernel_size: 3 + stride: 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_128_1_bn2" + type: "BatchNorm" + bottom: "layer_128_1_conv1_h" + top: "layer_128_1_conv1_h" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "layer_128_1_scale2" + type: "Scale" + bottom: "layer_128_1_conv1_h" + top: "layer_128_1_conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "layer_128_1_relu2" + type: "ReLU" + bottom: "layer_128_1_conv1_h" + top: "layer_128_1_conv1_h" +} +layer { + name: "layer_128_1_conv2" + type: "Convolution" + bottom: "layer_128_1_conv1_h" + top: "layer_128_1_conv2" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 128 + bias_term: false + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_128_1_conv_expand_h" + type: "Convolution" + bottom: "layer_128_1_bn1_h" + top: "layer_128_1_conv_expand_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 128 + bias_term: false + pad: 0 + kernel_size: 1 + stride: 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_128_1_sum" + type: "Eltwise" + bottom: "layer_128_1_conv2" + bottom: "layer_128_1_conv_expand_h" + top: "layer_128_1_sum" +} +layer { + name: "layer_256_1_bn1" + type: "BatchNorm" + bottom: "layer_128_1_sum" + top: "layer_256_1_bn1" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "layer_256_1_scale1" + type: "Scale" + bottom: "layer_256_1_bn1" + top: "layer_256_1_bn1" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "layer_256_1_relu1" + type: "ReLU" + bottom: "layer_256_1_bn1" + top: "layer_256_1_bn1" +} +layer { + name: "layer_256_1_conv1" + type: "Convolution" + bottom: "layer_256_1_bn1" + top: "layer_256_1_conv1" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 256 + bias_term: false + pad: 1 + kernel_size: 3 + stride: 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_256_1_bn2" + type: "BatchNorm" + bottom: "layer_256_1_conv1" + top: "layer_256_1_conv1" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "layer_256_1_scale2" + type: "Scale" + bottom: "layer_256_1_conv1" + top: "layer_256_1_conv1" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "layer_256_1_relu2" + type: "ReLU" + bottom: "layer_256_1_conv1" + top: "layer_256_1_conv1" +} +layer { + name: "layer_256_1_conv2" + type: "Convolution" + bottom: "layer_256_1_conv1" + top: "layer_256_1_conv2" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 256 + bias_term: false + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_256_1_conv_expand" + type: "Convolution" + bottom: "layer_256_1_bn1" + top: "layer_256_1_conv_expand" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 256 + bias_term: false + pad: 0 + kernel_size: 1 + stride: 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_256_1_sum" + type: "Eltwise" + bottom: "layer_256_1_conv2" + bottom: "layer_256_1_conv_expand" + top: "layer_256_1_sum" +} +layer { + name: "layer_512_1_bn1" + type: "BatchNorm" + bottom: "layer_256_1_sum" + top: "layer_512_1_bn1" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "layer_512_1_scale1" + type: "Scale" + bottom: "layer_512_1_bn1" + top: "layer_512_1_bn1" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "layer_512_1_relu1" + type: "ReLU" + bottom: "layer_512_1_bn1" + top: "layer_512_1_bn1" +} +layer { + name: "layer_512_1_conv1_h" + type: "Convolution" + bottom: "layer_512_1_bn1" + top: "layer_512_1_conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 128 + bias_term: false + pad: 1 + kernel_size: 3 + stride: 1 # 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_512_1_bn2_h" + type: "BatchNorm" + bottom: "layer_512_1_conv1_h" + top: "layer_512_1_conv1_h" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "layer_512_1_scale2_h" + type: "Scale" + bottom: "layer_512_1_conv1_h" + top: "layer_512_1_conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "layer_512_1_relu2" + type: "ReLU" + bottom: "layer_512_1_conv1_h" + top: "layer_512_1_conv1_h" +} +layer { + name: "layer_512_1_conv2_h" + type: "Convolution" + bottom: "layer_512_1_conv1_h" + top: "layer_512_1_conv2_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 256 + bias_term: false + pad: 2 # 1 + kernel_size: 3 + stride: 1 + dilation: 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_512_1_conv_expand_h" + type: "Convolution" + bottom: "layer_512_1_bn1" + top: "layer_512_1_conv_expand_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 256 + bias_term: false + pad: 0 + kernel_size: 1 + stride: 1 # 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_512_1_sum" + type: "Eltwise" + bottom: "layer_512_1_conv2_h" + bottom: "layer_512_1_conv_expand_h" + top: "layer_512_1_sum" +} +layer { + name: "last_bn_h" + type: "BatchNorm" + bottom: "layer_512_1_sum" + top: "layer_512_1_sum" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "last_scale_h" + type: "Scale" + bottom: "layer_512_1_sum" + top: "layer_512_1_sum" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "last_relu" + type: "ReLU" + bottom: "layer_512_1_sum" + top: "fc7" +} + +layer { + name: "conv6_1_h" + type: "Convolution" + bottom: "fc7" + top: "conv6_1_h" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 0 + kernel_size: 1 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv6_1_relu" + type: "ReLU" + bottom: "conv6_1_h" + top: "conv6_1_h" +} +layer { + name: "conv6_2_h" + type: "Convolution" + bottom: "conv6_1_h" + top: "conv6_2_h" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 256 + pad: 1 + kernel_size: 3 + stride: 2 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv6_2_relu" + type: "ReLU" + bottom: "conv6_2_h" + top: "conv6_2_h" +} +layer { + name: "conv7_1_h" + type: "Convolution" + bottom: "conv6_2_h" + top: "conv7_1_h" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 64 + pad: 0 + kernel_size: 1 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv7_1_relu" + type: "ReLU" + bottom: "conv7_1_h" + top: "conv7_1_h" +} +layer { + name: "conv7_2_h" + type: "Convolution" + bottom: "conv7_1_h" + top: "conv7_2_h" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 1 + kernel_size: 3 + stride: 2 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv7_2_relu" + type: "ReLU" + bottom: "conv7_2_h" + top: "conv7_2_h" +} +layer { + name: "conv8_1_h" + type: "Convolution" + bottom: "conv7_2_h" + top: "conv8_1_h" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 64 + pad: 0 + kernel_size: 1 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv8_1_relu" + type: "ReLU" + bottom: "conv8_1_h" + top: "conv8_1_h" +} +layer { + name: "conv8_2_h" + type: "Convolution" + bottom: "conv8_1_h" + top: "conv8_2_h" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv8_2_relu" + type: "ReLU" + bottom: "conv8_2_h" + top: "conv8_2_h" +} +layer { + name: "conv9_1_h" + type: "Convolution" + bottom: "conv8_2_h" + top: "conv9_1_h" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 64 + pad: 0 + kernel_size: 1 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv9_1_relu" + type: "ReLU" + bottom: "conv9_1_h" + top: "conv9_1_h" +} +layer { + name: "conv9_2_h" + type: "Convolution" + bottom: "conv9_1_h" + top: "conv9_2_h" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv9_2_relu" + type: "ReLU" + bottom: "conv9_2_h" + top: "conv9_2_h" +} +layer { + name: "conv4_3_norm" + type: "Normalize" + bottom: "layer_256_1_bn1" + top: "conv4_3_norm" + norm_param { + across_spatial: false + scale_filler { + type: "constant" + value: 20 + } + channel_shared: false + } +} +layer { + name: "conv4_3_norm_mbox_loc" + type: "Convolution" + bottom: "conv4_3_norm" + top: "conv4_3_norm_mbox_loc" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 16 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv4_3_norm_mbox_loc_perm" + type: "Permute" + bottom: "conv4_3_norm_mbox_loc" + top: "conv4_3_norm_mbox_loc_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv4_3_norm_mbox_loc_flat" + type: "Flatten" + bottom: "conv4_3_norm_mbox_loc_perm" + top: "conv4_3_norm_mbox_loc_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv4_3_norm_mbox_conf" + type: "Convolution" + bottom: "conv4_3_norm" + top: "conv4_3_norm_mbox_conf" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 8 # 84 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv4_3_norm_mbox_conf_perm" + type: "Permute" + bottom: "conv4_3_norm_mbox_conf" + top: "conv4_3_norm_mbox_conf_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv4_3_norm_mbox_conf_flat" + type: "Flatten" + bottom: "conv4_3_norm_mbox_conf_perm" + top: "conv4_3_norm_mbox_conf_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv4_3_norm_mbox_priorbox" + type: "PriorBox" + bottom: "conv4_3_norm" + bottom: "data" + top: "conv4_3_norm_mbox_priorbox" + prior_box_param { + min_size: 30.0 + max_size: 60.0 + aspect_ratio: 2 + flip: true + clip: false + variance: 0.1 + variance: 0.1 + variance: 0.2 + variance: 0.2 + step: 8 + offset: 0.5 + } +} +layer { + name: "fc7_mbox_loc" + type: "Convolution" + bottom: "fc7" + top: "fc7_mbox_loc" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 24 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "fc7_mbox_loc_perm" + type: "Permute" + bottom: "fc7_mbox_loc" + top: "fc7_mbox_loc_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "fc7_mbox_loc_flat" + type: "Flatten" + bottom: "fc7_mbox_loc_perm" + top: "fc7_mbox_loc_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "fc7_mbox_conf" + type: "Convolution" + bottom: "fc7" + top: "fc7_mbox_conf" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 12 # 126 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "fc7_mbox_conf_perm" + type: "Permute" + bottom: "fc7_mbox_conf" + top: "fc7_mbox_conf_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "fc7_mbox_conf_flat" + type: "Flatten" + bottom: "fc7_mbox_conf_perm" + top: "fc7_mbox_conf_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "fc7_mbox_priorbox" + type: "PriorBox" + bottom: "fc7" + bottom: "data" + top: "fc7_mbox_priorbox" + prior_box_param { + min_size: 60.0 + max_size: 111.0 + aspect_ratio: 2 + aspect_ratio: 3 + flip: true + clip: false + variance: 0.1 + variance: 0.1 + variance: 0.2 + variance: 0.2 + step: 16 + offset: 0.5 + } +} +layer { + name: "conv6_2_mbox_loc" + type: "Convolution" + bottom: "conv6_2_h" + top: "conv6_2_mbox_loc" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 24 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv6_2_mbox_loc_perm" + type: "Permute" + bottom: "conv6_2_mbox_loc" + top: "conv6_2_mbox_loc_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv6_2_mbox_loc_flat" + type: "Flatten" + bottom: "conv6_2_mbox_loc_perm" + top: "conv6_2_mbox_loc_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv6_2_mbox_conf" + type: "Convolution" + bottom: "conv6_2_h" + top: "conv6_2_mbox_conf" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 12 # 126 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv6_2_mbox_conf_perm" + type: "Permute" + bottom: "conv6_2_mbox_conf" + top: "conv6_2_mbox_conf_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv6_2_mbox_conf_flat" + type: "Flatten" + bottom: "conv6_2_mbox_conf_perm" + top: "conv6_2_mbox_conf_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv6_2_mbox_priorbox" + type: "PriorBox" + bottom: "conv6_2_h" + bottom: "data" + top: "conv6_2_mbox_priorbox" + prior_box_param { + min_size: 111.0 + max_size: 162.0 + aspect_ratio: 2 + aspect_ratio: 3 + flip: true + clip: false + variance: 0.1 + variance: 0.1 + variance: 0.2 + variance: 0.2 + step: 32 + offset: 0.5 + } +} +layer { + name: "conv7_2_mbox_loc" + type: "Convolution" + bottom: "conv7_2_h" + top: "conv7_2_mbox_loc" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 24 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv7_2_mbox_loc_perm" + type: "Permute" + bottom: "conv7_2_mbox_loc" + top: "conv7_2_mbox_loc_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv7_2_mbox_loc_flat" + type: "Flatten" + bottom: "conv7_2_mbox_loc_perm" + top: "conv7_2_mbox_loc_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv7_2_mbox_conf" + type: "Convolution" + bottom: "conv7_2_h" + top: "conv7_2_mbox_conf" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 12 # 126 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv7_2_mbox_conf_perm" + type: "Permute" + bottom: "conv7_2_mbox_conf" + top: "conv7_2_mbox_conf_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv7_2_mbox_conf_flat" + type: "Flatten" + bottom: "conv7_2_mbox_conf_perm" + top: "conv7_2_mbox_conf_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv7_2_mbox_priorbox" + type: "PriorBox" + bottom: "conv7_2_h" + bottom: "data" + top: "conv7_2_mbox_priorbox" + prior_box_param { + min_size: 162.0 + max_size: 213.0 + aspect_ratio: 2 + aspect_ratio: 3 + flip: true + clip: false + variance: 0.1 + variance: 0.1 + variance: 0.2 + variance: 0.2 + step: 64 + offset: 0.5 + } +} +layer { + name: "conv8_2_mbox_loc" + type: "Convolution" + bottom: "conv8_2_h" + top: "conv8_2_mbox_loc" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 16 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv8_2_mbox_loc_perm" + type: "Permute" + bottom: "conv8_2_mbox_loc" + top: "conv8_2_mbox_loc_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv8_2_mbox_loc_flat" + type: "Flatten" + bottom: "conv8_2_mbox_loc_perm" + top: "conv8_2_mbox_loc_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv8_2_mbox_conf" + type: "Convolution" + bottom: "conv8_2_h" + top: "conv8_2_mbox_conf" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 8 # 84 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv8_2_mbox_conf_perm" + type: "Permute" + bottom: "conv8_2_mbox_conf" + top: "conv8_2_mbox_conf_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv8_2_mbox_conf_flat" + type: "Flatten" + bottom: "conv8_2_mbox_conf_perm" + top: "conv8_2_mbox_conf_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv8_2_mbox_priorbox" + type: "PriorBox" + bottom: "conv8_2_h" + bottom: "data" + top: "conv8_2_mbox_priorbox" + prior_box_param { + min_size: 213.0 + max_size: 264.0 + aspect_ratio: 2 + flip: true + clip: false + variance: 0.1 + variance: 0.1 + variance: 0.2 + variance: 0.2 + step: 100 + offset: 0.5 + } +} +layer { + name: "conv9_2_mbox_loc" + type: "Convolution" + bottom: "conv9_2_h" + top: "conv9_2_mbox_loc" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 16 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv9_2_mbox_loc_perm" + type: "Permute" + bottom: "conv9_2_mbox_loc" + top: "conv9_2_mbox_loc_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv9_2_mbox_loc_flat" + type: "Flatten" + bottom: "conv9_2_mbox_loc_perm" + top: "conv9_2_mbox_loc_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv9_2_mbox_conf" + type: "Convolution" + bottom: "conv9_2_h" + top: "conv9_2_mbox_conf" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 8 # 84 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv9_2_mbox_conf_perm" + type: "Permute" + bottom: "conv9_2_mbox_conf" + top: "conv9_2_mbox_conf_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv9_2_mbox_conf_flat" + type: "Flatten" + bottom: "conv9_2_mbox_conf_perm" + top: "conv9_2_mbox_conf_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv9_2_mbox_priorbox" + type: "PriorBox" + bottom: "conv9_2_h" + bottom: "data" + top: "conv9_2_mbox_priorbox" + prior_box_param { + min_size: 264.0 + max_size: 315.0 + aspect_ratio: 2 + flip: true + clip: false + variance: 0.1 + variance: 0.1 + variance: 0.2 + variance: 0.2 + step: 300 + offset: 0.5 + } +} +layer { + name: "mbox_loc" + type: "Concat" + bottom: "conv4_3_norm_mbox_loc_flat" + bottom: "fc7_mbox_loc_flat" + bottom: "conv6_2_mbox_loc_flat" + bottom: "conv7_2_mbox_loc_flat" + bottom: "conv8_2_mbox_loc_flat" + bottom: "conv9_2_mbox_loc_flat" + top: "mbox_loc" + concat_param { + axis: 1 + } +} +layer { + name: "mbox_conf" + type: "Concat" + bottom: "conv4_3_norm_mbox_conf_flat" + bottom: "fc7_mbox_conf_flat" + bottom: "conv6_2_mbox_conf_flat" + bottom: "conv7_2_mbox_conf_flat" + bottom: "conv8_2_mbox_conf_flat" + bottom: "conv9_2_mbox_conf_flat" + top: "mbox_conf" + concat_param { + axis: 1 + } +} +layer { + name: "mbox_priorbox" + type: "Concat" + bottom: "conv4_3_norm_mbox_priorbox" + bottom: "fc7_mbox_priorbox" + bottom: "conv6_2_mbox_priorbox" + bottom: "conv7_2_mbox_priorbox" + bottom: "conv8_2_mbox_priorbox" + bottom: "conv9_2_mbox_priorbox" + top: "mbox_priorbox" + concat_param { + axis: 2 + } +} + +layer { + name: "mbox_conf_reshape" + type: "Reshape" + bottom: "mbox_conf" + top: "mbox_conf_reshape" + reshape_param { + shape { + dim: 0 + dim: -1 + dim: 2 + } + } +} +layer { + name: "mbox_conf_softmax" + type: "Softmax" + bottom: "mbox_conf_reshape" + top: "mbox_conf_softmax" + softmax_param { + axis: 2 + } +} +layer { + name: "mbox_conf_flatten" + type: "Flatten" + bottom: "mbox_conf_softmax" + top: "mbox_conf_flatten" + flatten_param { + axis: 1 + } +} + +layer { + name: "detection_out" + type: "DetectionOutput" + bottom: "mbox_loc" + bottom: "mbox_conf_flatten" + bottom: "mbox_priorbox" + top: "detection_out" + include { + phase: TEST + } + detection_output_param { + num_classes: 2 + share_location: true + background_label_id: 0 + nms_param { + nms_threshold: 0.45 + top_k: 400 + } + code_type: CENTER_SIZE + keep_top_k: 200 + confidence_threshold: 0.01 + } +} diff --git a/assets/model/mask_detector.h5 b/assets/model/mask_detector.h5 new file mode 100644 index 0000000000000000000000000000000000000000..702bce76ca251e01246477392114250c18f3bec0 --- /dev/null +++ b/assets/model/mask_detector.h5 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2844fe9a89fc4fd4e8a540ae8b3922a9b10dc46d284fbe553f0c2c0f7b1d70e2 +size 11532200 diff --git a/assets/model/mask_detector.keras b/assets/model/mask_detector.keras new file mode 100644 index 0000000000000000000000000000000000000000..2b555d86b3ac2392bfb0316f5a6bc6fef5d68874 --- /dev/null +++ b/assets/model/mask_detector.keras @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97bde8c2cc9829c51a98ce2fefbcfb23c342340a1677ecfae1378e2052178958 +size 11550361 diff --git a/assets/model/res10_300x300_ssd_iter_140000.caffemodel b/assets/model/res10_300x300_ssd_iter_140000.caffemodel new file mode 100644 index 0000000000000000000000000000000000000000..b7deb28672653fabd0c77f9ced8f0b3711ab7d92 --- /dev/null +++ b/assets/model/res10_300x300_ssd_iter_140000.caffemodel @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a56a11a57a4a295956b0660b4a3d76bbdca2206c4961cea8efe7d95c7cb2f2d +size 10666211 diff --git a/assets/model_files/mask_detector.model b/assets/model_files/mask_detector.model new file mode 100644 index 0000000000000000000000000000000000000000..6a4ec8ed36f6f7f044af5983df088a866e1407bb --- /dev/null +++ b/assets/model_files/mask_detector.model @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c528c89c690273e43235dde2d750a49264ee2cd36c536b96f8bf5146b0b06cdc +size 11495912 diff --git a/assets/plot.png b/assets/plot.png new file mode 100644 index 0000000000000000000000000000000000000000..1a312de3bab9075032d78aa41d753cc02c8db2a0 Binary files /dev/null and b/assets/plot.png differ diff --git a/notebooks/Train_Mask_Detection.ipynb b/notebooks/Train_Mask_Detection.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..e6b7b68742d0ce417c310fb94a4d409b18a209a2 --- /dev/null +++ b/notebooks/Train_Mask_Detection.ipynb @@ -0,0 +1,762 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "b1d8379f", + "metadata": {}, + "outputs": [], + "source": [ + "!pip install tf_keras" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "64b101f5", + "metadata": {}, + "outputs": [], + "source": [ + "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n", + "from tensorflow.keras.applications import MobileNetV2\n", + "from tensorflow.keras.layers import AveragePooling2D\n", + "from tensorflow.keras.layers import Dropout\n", + "from tensorflow.keras.layers import Flatten\n", + "from tensorflow.keras.layers import Dense\n", + "from tensorflow.keras.layers import Input\n", + "from tensorflow.keras.models import Model\n", + "from tensorflow.keras.optimizers import Adam\n", + "from tensorflow.keras.applications.mobilenet_v2 import preprocess_input\n", + "from tensorflow.keras.preprocessing.image import img_to_array\n", + "from tensorflow.keras.preprocessing.image import load_img\n", + "from tensorflow.keras.utils import to_categorical\n", + "from sklearn.preprocessing import LabelBinarizer\n", + "from sklearn.model_selection import train_test_split\n", + "from sklearn.metrics import classification_report\n", + "from imutils import paths\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import os" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "b4822912", + "metadata": {}, + "outputs": [], + "source": [ + "# Initialize the initial learning rate, number of epochs to train for,\n", + "# and batch size\n", + "INIT_LR = 1e-4\n", + "EPOCHS = 2\n", + "BS = 32\n", + "DIRECTORY = '../assets/dataset'" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "4f22baac", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "without_mask\n", + "with_mask\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "d:\\Programming\\Projects\\Mask_detector\\maskVenv\\Lib\\site-packages\\PIL\\Image.py:1000: UserWarning: Palette images with Transparency expressed in bytes should be converted to RGBA images\n", + " warnings.warn(\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['without_mask', 'without_mask', 'without_mask', 'without_mask', 'without_mask', 'without_mask', 'without_mask', 'without_mask', 'without_mask', 'without_mask']\n" + ] + } + ], + "source": [ + "data = []\n", + "labels = []\n", + "\n", + "for category in os.listdir(DIRECTORY):\n", + " print(category)\n", + " path = os.path.join(DIRECTORY, category)\n", + " for img in os.listdir(path):\n", + " img_path = os.path.join(path, img)\n", + " image = load_img(img_path, target_size=(224, 224))\n", + " image = img_to_array(image)\n", + " image = preprocess_input(image)\n", + " \n", + " data.append(image)\n", + " labels.append(category)\n", + " \n", + "print(labels[:10])" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "71e7f1b6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Before: [[1]\n", + " [1]] ,type: \n", + "After: [[0. 1.]\n", + " [0. 1.]] ,type: \n", + "Before-data: [array([[[ 0.94509804, 0.94509804, 0.94509804],\n", + " [ 0.94509804, 0.94509804, 0.94509804],\n", + " [ 0.94509804, 0.94509804, 0.94509804],\n", + " ...,\n", + " [ 0.92941177, 0.92941177, 0.92941177],\n", + " [ 0.92941177, 0.92941177, 0.92941177],\n", + " [ 0.92941177, 0.92941177, 0.92941177]],\n", + "\n", + " [[ 0.94509804, 0.94509804, 0.94509804],\n", + " [ 0.94509804, 0.94509804, 0.94509804],\n", + " [ 0.94509804, 0.94509804, 0.94509804],\n", + " ...,\n", + " [ 0.92941177, 0.92941177, 0.92941177],\n", + " [ 0.92941177, 0.92941177, 0.92941177],\n", + " [ 0.92941177, 0.92941177, 0.92941177]],\n", + "\n", + " [[ 0.94509804, 0.94509804, 0.94509804],\n", + " [ 0.94509804, 0.94509804, 0.94509804],\n", + " [ 0.94509804, 0.94509804, 0.94509804],\n", + " ...,\n", + " [ 0.92941177, 0.92941177, 0.92941177],\n", + " [ 0.92941177, 0.92941177, 0.92941177],\n", + " [ 0.92941177, 0.92941177, 0.92941177]],\n", + "\n", + " ...,\n", + "\n", + " [[-0.7176471 , -0.7176471 , -0.7176471 ],\n", + " [-0.7176471 , -0.7176471 , -0.7176471 ],\n", + " [-0.64705884, -0.64705884, -0.64705884],\n", + " ...,\n", + " [-0.7882353 , -0.7882353 , -0.7882353 ],\n", + " [-0.7882353 , -0.7882353 , -0.7882353 ],\n", + " [-0.7882353 , -0.7882353 , -0.7882353 ]],\n", + "\n", + " [[-0.70980394, -0.70980394, -0.70980394],\n", + " [-0.70980394, -0.70980394, -0.70980394],\n", + " [-0.64705884, -0.64705884, -0.64705884],\n", + " ...,\n", + " [-0.79607844, -0.79607844, -0.79607844],\n", + " [-0.79607844, -0.79607844, -0.79607844],\n", + " [-0.79607844, -0.79607844, -0.79607844]],\n", + "\n", + " [[-0.70980394, -0.70980394, -0.70980394],\n", + " [-0.70980394, -0.70980394, -0.70980394],\n", + " [-0.64705884, -0.64705884, -0.64705884],\n", + " ...,\n", + " [-0.79607844, -0.79607844, -0.79607844],\n", + " [-0.79607844, -0.79607844, -0.79607844],\n", + " [-0.79607844, -0.79607844, -0.79607844]]], dtype=float32), array([[[ 0.58431375, 0.52156866, 0.62352943],\n", + " [ 0.5529412 , 0.4901961 , 0.5921569 ],\n", + " [ 0.5529412 , 0.4901961 , 0.5921569 ],\n", + " ...,\n", + " [ 0.5372549 , 0.52156866, 0.54509807],\n", + " [ 0.5372549 , 0.52156866, 0.54509807],\n", + " [ 0.5529412 , 0.5372549 , 0.56078434]],\n", + "\n", + " [[ 0.58431375, 0.52156866, 0.62352943],\n", + " [ 0.5529412 , 0.4901961 , 0.5921569 ],\n", + " [ 0.5529412 , 0.4901961 , 0.5921569 ],\n", + " ...,\n", + " [ 0.5372549 , 0.52156866, 0.54509807],\n", + " [ 0.5372549 , 0.52156866, 0.54509807],\n", + " [ 0.5529412 , 0.5372549 , 0.56078434]],\n", + "\n", + " [[ 0.58431375, 0.52156866, 0.62352943],\n", + " [ 0.58431375, 0.52156866, 0.62352943],\n", + " [ 0.58431375, 0.52156866, 0.62352943],\n", + " ...,\n", + " [ 0.5529412 , 0.5372549 , 0.56078434],\n", + " [ 0.5529412 , 0.5372549 , 0.56078434],\n", + " [ 0.58431375, 0.5686275 , 0.5921569 ]],\n", + "\n", + " ...,\n", + "\n", + " [[-0.1372549 , -0.18431371, 0.03529418],\n", + " [ 0.17647064, 0.12941182, 0.34901965],\n", + " [ 0.17647064, 0.12941182, 0.34901965],\n", + " ...,\n", + " [ 0.12941182, 0.05098045, 0.24705887],\n", + " [ 0.12941182, 0.05098045, 0.24705887],\n", + " [ 0.33333337, 0.254902 , 0.4431373 ]],\n", + "\n", + " [[ 0.04313731, 0.01176476, 0.20784318],\n", + " [ 0.3411765 , 0.30980396, 0.5058824 ],\n", + " [ 0.3411765 , 0.30980396, 0.5058824 ],\n", + " ...,\n", + " [-0.27058822, -0.34117645, -0.12941176],\n", + " [-0.27058822, -0.34117645, -0.12941176],\n", + " [-0.05098039, -0.11372548, 0.07450986]],\n", + "\n", + " [[ 0.04313731, 0.01176476, 0.20784318],\n", + " [ 0.3411765 , 0.30980396, 0.5058824 ],\n", + " [ 0.3411765 , 0.30980396, 0.5058824 ],\n", + " ...,\n", + " [-0.27058822, -0.34117645, -0.12941176],\n", + " [-0.27058822, -0.34117645, -0.12941176],\n", + " [-0.05098039, -0.11372548, 0.07450986]]], dtype=float32)] ,type: \n", + "After-After: [[0. 1.]\n", + " [0. 1.]] ,type: \n" + ] + } + ], + "source": [ + "# perform one-hot encoding on the labels\n", + "lb = LabelBinarizer()\n", + "labels = lb.fit_transform(labels)\n", + "print(\"Before: \", labels[:2],\" ,type: \",type(labels))\n", + "labels = to_categorical(labels)\n", + "print(\"After: \", labels[:2],\" ,type: \",type(labels))\n", + "\n", + "print(\"Before-data: \", data[:2],\" ,type: \",type(data))\n", + "data = np.array(data, dtype=\"float32\")\n", + "labels = np.array(labels)\n", + "print(\"After-After: \", labels[:2],\" ,type: \",type(labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "c608337a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[0., 1.],\n", + " [0., 1.],\n", + " [0., 1.],\n", + " [0., 1.],\n", + " [0., 1.],\n", + " [0., 1.],\n", + " [0., 1.],\n", + " [0., 1.],\n", + " [0., 1.],\n", + " [0., 1.]])" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "labels[:10]" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "b4a1c892", + "metadata": {}, + "outputs": [], + "source": [ + "(trainX, testX, trainY, testY) = train_test_split(data, labels, test_size=0.20, stratify=labels, random_state=42)" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "716b83e5", + "metadata": {}, + "outputs": [], + "source": [ + "aug = ImageDataGenerator(\n", + " rotation_range=20,\n", + " zoom_range=0.15,\n", + " width_shift_range=0.2,\n", + " height_shift_range=0.2,\n", + " shear_range=0.15,\n", + " horizontal_flip=True,\n", + " fill_mode=\"nearest\")" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "0772282d", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\VickyWadh\\AppData\\Local\\Temp\\ipykernel_25156\\3680935412.py:2: UserWarning: `input_shape` is undefined or non-square, or `rows` is not in [96, 128, 160, 192, 224]. Weights for input shape (224, 224) will be loaded as the default.\n", + " baseModel = MobileNetV2(weights=\"imagenet\", include_top=False,\n" + ] + } + ], + "source": [ + "# load the MobileNetV2 network, ensuring the head FC Layer sets are left off\n", + "baseModel = MobileNetV2(weights=\"imagenet\", include_top=False,\n", + " input_tensor=Input(shape=(224,224,3)))" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "185ef084", + "metadata": {}, + "outputs": [], + "source": [ + "# construct the head of the model that will be placed on the top of the base model\n", + "headModel = baseModel.output\n", + "headModel = AveragePooling2D(pool_size=(7,7))(headModel)\n", + "headModel = Flatten(name=\"flatten\")(headModel)\n", + "headModel = Dense(128, activation=\"relu\")(headModel)\n", + "headModel = Dropout(0.5)(headModel)\n", + "headModel = Dense(2, activation=\"softmax\")(headModel)" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "204919cd", + "metadata": {}, + "outputs": [], + "source": [ + "# place the head FC model on top of the base model (this will become the actual model we will train)\n", + "model = Model(inputs=baseModel.input, outputs=headModel)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "27601586", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ] + } + ], + "source": [ + "# loop over all the layers in the base model and freeze them so they will \n", + "# *not* be updated during the first training process\n", + "for layer in baseModel.layers:\n", + " print(layer)\n", + " layer.trainable = False" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "3be244cf", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[INFO] compiling model...\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "d:\\Programming\\Projects\\Mask_detector\\maskVenv\\Lib\\site-packages\\keras\\src\\optimizers\\base_optimizer.py:33: UserWarning: Argument `decay` is no longer supported and will be ignored.\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "import tensorflow as tf\n", + "# compile our model\n", + "print(\"[INFO] compiling model...\")\n", + "opt = Adam(learning_rate=INIT_LR, decay=INIT_LR / EPOCHS)\n", + "model.compile(loss=\"binary_crossentropy\", optimizer=opt,metrics=[\"accuracy\"])" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "id": "18a9b4e5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[INFO] training head...\n", + "Epoch 1/2\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "d:\\Programming\\Projects\\Mask_detector\\maskVenv\\Lib\\site-packages\\keras\\src\\trainers\\data_adapters\\py_dataset_adapter.py:121: UserWarning: Your `PyDataset` class should call `super().__init__(**kwargs)` in its constructor. `**kwargs` can include `workers`, `use_multiprocessing`, `max_queue_size`. Do not pass these arguments to `fit()`, as they will be ignored.\n", + " self._warn_if_super_not_called()\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1m188/188\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m219s\u001b[0m 1s/step - accuracy: 0.8356 - loss: 0.4183 - val_accuracy: 0.9742 - val_loss: 0.0843\n", + "Epoch 2/2\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\VickyWadh\\anaconda3\\Lib\\contextlib.py:155: UserWarning: Your input ran out of data; interrupting training. Make sure that your dataset or generator can generate at least `steps_per_epoch * epochs` batches. You may need to use the `.repeat()` function when building your dataset.\n", + " self.gen.throw(typ, value, traceback)\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1m188/188\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m32s\u001b[0m 168ms/step - accuracy: 0.9688 - loss: 0.0960 - val_accuracy: 0.9735 - val_loss: 0.0840\n" + ] + } + ], + "source": [ + "# train the head of the network\n", + "print(\"[INFO] training head...\")\n", + "H = model.fit(\n", + " aug.flow(trainX, trainY, batch_size=BS),\n", + " steps_per_epoch=len(trainX) // BS,\n", + " validation_data=(testX, testY),\n", + " validation_steps=len(testX) // BS,\n", + " epochs=EPOCHS)" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "634f0d23", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[INFO] evaluating network...\n", + "\u001b[1m48/48\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m35s\u001b[0m 688ms/step\n" + ] + } + ], + "source": [ + "# make predictions on the testing set\n", + "print(\"[INFO] evaluating network...\")\n", + "predIdxs = model.predict(testX, batch_size=BS)" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "id": "1a891386", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " with_mask 0.97 0.97 0.97 745\n", + "without_mask 0.98 0.97 0.97 766\n", + "\n", + " accuracy 0.97 1511\n", + " macro avg 0.97 0.97 0.97 1511\n", + "weighted avg 0.97 0.97 0.97 1511\n", + "\n" + ] + } + ], + "source": [ + "# for each image in the testing set we need to find the index of the label\n", + "# with corresponding largest predicted probability\n", + "predIdxs = np.argmax(predIdxs, axis=1)\n", + "\n", + "# show a nicely formatted classification report\n", + "print(classification_report(testY.argmax(axis=1), predIdxs, target_names=lb.classes_))" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "id": "500c8e0a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[INFO] saving mask detector model...\n" + ] + } + ], + "source": [ + "# serialize the model to disk\n", + "print(\"[INFO] saving mask detector model...\")\n", + "model.save(\"../assets/model/mask_detector.keras\")" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "id": "4fa65710", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjsAAAHMCAYAAAAzqWlnAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAABoWklEQVR4nO3dd1zU9eMH8NfnuDv2FBAEARESt4aj3OLIlTs1m1qOsqk50syR2ldLs7K+tn6OypXmnt8cucmBOcotDoaAcCCb4z6/P447OO5AjhvA+Xo+Hjy8+8z3vQF9+V4fQRRFEUREREQ2SlLVBSAiIiKyJIYdIiIismkMO0RERGTTGHaIiIjIpjHsEBERkU1j2CEiIiKbxrBDRERENo1hh4iIiGwaww4RERHZNIYdIhMJgoAuXbqYfJ0uXbpAEATTC0TVUkhICEJCQqq6GESPJYYdqvEEQTDqa+XKlVVd5Brj0KFDZgtzVHm//vqr9ud33759VV0cohpHWtUFIDLVrFmz9LYtXboU6enpePfdd+Hh4aGzr0WLFma9/7///gsnJyeTr7N69WpkZ2eboURka77//nsIggBRFPH999+jZ8+eVV0kohpF4INAyRaFhITg9u3buHXrFrsOTHDo0CF07doVnTt3xqFDh6q6ODWa5ucwNjbWqPOuXLmCiIgIdO/eHWlpaTh//jzu3r2L2rVrm7+QRDaK3Vj0WNGMi8nPz8fcuXPRoEED2Nvb49VXXwUApKen47PPPkNUVBQCAwMhl8vh4+OD/v3748SJEwavaaibZ/bs2RAEAYcOHcLGjRvRpk0bODk5wcvLCyNGjEBcXFyZZStJ0400e/ZsnDt3Dn379oWHhwecnJzQuXNnHD9+3GCZEhISMGrUKPj6+sLR0REtWrTAqlWrdK5nCQkJCZgwYQJCQkK0dTd48GCcOXNG79j8/Hx89dVXePLJJ+Hp6QknJyeEhIRgwIAB+OOPP3SOPXLkCJ599lkEBgbC3t4efn5+eOqppzBnzpwKlSs/Px/Lli1Dnz59EBwcDHt7e3h5eaF79+7YvXu3wXM0Y2yysrIwefJkBAUFwd7eHmFhYVi4cCEM/T9RFEUsW7YMjRs3hoODAwICAvDWW28hPT29QuU05IcffgAAjBo1Cq+++ioKCgrK7YpNTU3FjBkz0KRJEzg5OcHd3R3NmzfHtGnTkJWVValjyxtvVPJnvSTN70ViYiJef/11BAQEwM7OTlv2q1evYtq0aWjVqhV8fHxgb2+P4OBgjB07Fvfu3Svz8+3btw/PPvssfH19YW9vj7p16+r8zOzduxeCIGDUqFEGz8/Ly4O3tze8vb2Rl5dX5n3ItrAbix5LQ4YMwalTp9C7d28MHDgQvr6+ANRdUjNmzECnTp3Qt29feHp64s6dO9i2bRt2796N7du3o1evXhW+z7fffott27ahf//+6Ny5M6Kjo7F+/Xr8/fffOHfuHOzt7St0ndOnT2PRokV4+umn8frrr+POnTvYtGkTunXrhnPnzqFBgwbaY5OSkvD000/j9u3b6NSpE9q1a4fExES8+eabFu3+uHXrFjp06ID4+HhERUXh+eefx927d/Hbb79h586d2LRpE/r166c9/tVXX8XatWvRpEkTvPzyy3B0dER8fDyOHj2KPXv2oHv37gCAPXv2oG/fvnBzc0P//v0REBCA1NRU/Pvvv/j2228NdmOWlpqainfffRft2rVDjx494OPjg4SEBGzfvh19+vTBDz/8gNdff13vvIKCAjzzzDOIj49H7969IZVKsWXLFkybNg25ubl6937vvffw1Vdfwd/fH2PHjoVMJsPWrVsRHR2N/Px8yOVyo+o0Pz8fq1atgru7OwYNGoScnBxMmjQJP/74I6ZMmaIXjm/duoWuXbvi9u3biIyMxBtvvAGVSoWrV6/iiy++wPjx4+Hs7Gz0sZWVmpqKp556Ci4uLhg8eDAkEom2Rer333/H8uXL0bVrV7Rr1w5yuRyXLl3Cjz/+iO3bt+P06dMICAjQud6sWbMwd+5cuLi4YODAgahbty7i4+Nx/Phx/PLLL+jevTt69uyJ+vXrY8OGDVi6dCnc3d11rrFp0yY8ePAAkyZNqvDvH9kAkcgGBQcHiwDEW7du6Wzv3LmzCEBs2rSpmJycrHeeQqEwuP3u3buiv7+/GBERobcPgNi5c2edbbNmzRIBiK6uruL58+d19j3//PMiAHH9+vUGy1bSwYMHRQAiAHHFihU6+5YvXy4CEN944w2d7aNHjxYBiFOmTNHZfu7cOVEul4sAxFmzZul9DkM09y/9+Qzp2bOnCECcN2+ezvZjx46JdnZ2opeXl/jw4UNRFNX1LAiCGBkZKSqVSr1rpaSkaF8PHjxYBCCeO3dO7zhD3ytDcnNzxbt37+ptVygUYuPGjUVPT08xOztbZ5/mZ6h37946++7fvy+6u7uL7u7uYn5+vs7nBCDWr19ffPDggXZ7Tk6O+NRTT4kAxODg4AqVV2Pt2rUiAHHs2LHabUOGDBEBiH/88Yfe8U8//bQIQFywYIHevuTkZDEnJ6dSxwYHB5dZds3P+sGDB3W2a35uX3rpJbGgoEDvvHv37om5ubl62/fu3StKJBJx/PjxetsBiPXq1RPv3bund17J7+9nn30mAhC//vprveM0v2dXrlwx+HnINjHskE16VNjZsmWL0dd8++23RQDi7du3dbaXF3ZmzJihd50DBw6IAMRJkyYZLFtJmrDRvn17vevk5+eLUqlUjIyM1G7Ly8sTHR0dRXd3dzEjI0PvnNdff90iYefu3bsiADEoKEgnAGi8+OKLIgBx1apVoiiKYnp6ughAbNeunahSqcq9tibsWOofp8WLF4sAxD///FNnu+Zn6Nq1a3rnvPzyyyIA8cKFC9ptmrr9v//7P73jNfVobNiJiooSAYjHjx/Xbtu+fbsIQBw2bJjOsadPnxYBiC1atBALCwvLva4xx4pi5cOOXC4X79+//8jrl9a0aVOxXr16Otv69esnAhB///33R56fkpIiOjg4iE2aNNHZfvnyZRGA2LVrV6PLRDUbx+zQY6lNmzZl7jt27BiGDRuGunXrwt7eXjvl9+uvvwYAg+NtytKqVSu9bXXr1gUApKWlmXQdmUyG2rVr61znypUryMnJQbNmzeDq6qp3TocOHSp8T2PExMQAADp27AiZTKa3PyoqSuc4Nzc3PPvsszh+/DhatGiBuXPn4uDBgwZno73wwgsAgLZt22L8+PFYv359uWM6ynLp0iW8+uqrCA0NhaOjo/b7OmnSJACGv6/u7u4ICwvT227oe3j27FkAQOfOnfWO79ChA+zs7Iwq7/Xr13Hw4EE0aNAATz/9tHZ7r1694Ofnhy1btiAlJUW7/eTJkwCAZ555BhJJ+X+1G3OsKUJCQrRdxKWJoqjtevLx8YFUKtV+Ty5cuKD3/Th58iQEQahQN3KtWrUwbNgwXLx4UWdc2/fffw8AGD9+vAmfimoijtmhx5Kfn5/B7Zs3b8bQoUPh4OCAHj16oH79+nB2doZEIsGhQ4fw559/GjWosfS0dwCQStW/doWFhSZdR3OtktfRDIQta6aOpWbwaO7r7+9vcL9mu0Kh0G5bv349Fi5ciDVr1mjHvjg4OGDo0KH4/PPPtWUdPHgwduzYgcWLF+P//u//8N133wEAIiMj8emnn6JHjx6PLN/JkycRFRUFpVKJbt26oX///nBzc4NEIsG5c+ewdetWg9/X8uodQIXrXiqVwtvb+5HlLOmHH36AKIrawfMlr/XCCy9g8eLFWLlyJT744AMAxXVbepyLIcYca4qyfs8AYOLEiVi6dCn8/f3xzDPPICAgAI6OjgCAlStX4vbt2zrHKxQKeHp6ao95lDfffBOrV6/Gd999h3bt2iEvLw+rVq2Cr68vBg0aVPkPRTUSww49lspaqXjmzJmQy+U4ffo0GjZsqLNv3Lhx+PPPP61RvEpzc3MDANy/f9/g/rK2m0ozCDQxMdHg/oSEBJ3jAMDR0RGzZ8/G7NmzcffuXRw+fBgrV67EL7/8gtjYWBw5ckR7bN++fdG3b19kZWUhOjoaO3bswH//+1/069cPMTExaNSoUbnlmzdvHnJycnDw4EG9mXOffvoptm7dWpmPrUPz2e7fv4/Q0FCdfUqlEikpKQgMDKzQtUrOuPrwww/x4YcfGjzuhx9+0IYdTTCrSMujMccCgEQiQX5+vsF9JQNsaWX9niUlJeGrr75CkyZNcPz4cb1WyLVr1xos84MHD5CTk1OhwNO2bVu0bNlSO1B59+7dePDgAaZOnWqw9ZFsG7uxiEq4fv06GjVqpBd0VCoVjh49WkWlqriIiAg4Ojri/PnzePjwod5+S32Gli1baq+vVCr19h88eBAA8OSTTxo8v27dunjhhRewd+9ehIWF4ejRo3jw4IHecc7OzoiKisKSJUswffp05Ofnlzl1vKTr16/Dy8vL4ErQ5gqwms9m6HpHjx41qiVv69atSEpKQoMGDfDaa68Z/AoNDcXVq1e193vqqacAqKdeq1Sqcq9vzLEA4Onpifv376OgoEBv3+nTpyv8uTRu3rwJlUqFnj176gWde/fu4ebNmwbLLIoi9uzZU+H7vPnmm8jNzcXq1au1CzOOHTvW6PJSzcewQ1RCSEgIrl27hvj4eO02URQxe/Zs/PPPP1VYsoqRy+UYPnw40tPTMW/ePJ19f//9N1avXm2R+wYGBqJHjx6IjY3F0qVLdfZFR0djzZo18PT01HYfJCcn48KFC3rXycrKQmZmJqRSqXaa9uHDhw0GKE0rVUVWrw4JCUFqairOnz+vs/2nn37C3r17K/QZH0XT3TR//nykpqZqt+fm5pbZMlMWzdiSuXPn4scffzT4NX36dJ1jIyMj0a5dO5w7dw4LFy7Uu+aDBw+Qm5tr9LGAeoybUqnEihUrdI5buXIljh07ZtRnA4oXWCwdAjMzMzFmzBiD3++3334bADBp0iSDLVKGto0cORLu7u5YtGgR/vzzT/To0UOv1Y0eD+zGIirh/fffx/jx49GyZUsMGTIEMpkMx44dwz///INnn30W27dvr+oiPtJ//vMfHDhwAIsWLUJ0dDTatWuHhIQEbNiwAX369MGWLVuMHpR6+fJlvbEjGkFBQZg7dy6WL1+O9u3bY/Lkydi3bx9atWqlXWdHIpFgxYoV2v/Fx8XFoWXLlmjatCmaNWuGunXrIiMjAzt27EBiYiLeeecd7bHvvPMO4uLi0L59e+1ihWfOnMGBAwcQHByMESNGPLL87733Hvbu3YsOHTpg2LBhcHd3x+nTp3H06FEMHToUGzduNKo+DGnfvj3efvttfP3112jSpAmGDh2qXWfH09OzzPFMpd26dQt//PEHvL29MXDgwDKPGz58ON577z1s2rQJX3/9Nby8vPDLL7+gS5cumD59OjZt2oQuXbpAFEVcu3YN+/btw+XLl7VBw5hj3377baxYsQJvvPEG9u/fj7p16+LcuXM4ceIE+vXrhx07dhhVV35+fhgxYgTWrVuHFi1aoGfPnkhPT8f//vc/ODg4oEWLFjh37pzOOT179sRHH32EefPmoWHDhtp1du7fv4+jR4/iqaee0lts0cnJCa+88gq++uorAOquaHpMVeVUMCJLedTU8/KsWLFCbN68uejk5CTWqlVLHDhwoHj+/Plyp9iWNfW89LGiKIq3bt0SAYivvPLKI8ummbJc1lTxsqYE37t3T3z55ZdFb29v0cHBQWzevLm4cuVK8bfffhMBiF988UW5dVD6/uV9NW/eXOe+48ePF4OCgkSZTCbWqlVLHDBggPjXX3/pXDctLU2cM2eO2LVrV7FOnTqiXC4X/fz8xM6dO4tr1qzRmY6+fv16ccSIEWJYWJjo7Owsurq6io0bNxanT58uJiUlVehziKJ6ynbbtm1FFxcX0d3dXezRo4f4559/iitWrDC4jlFlplurVCrx66+/FiMiIkS5XC76+/uLb775pqhQKMq9XknTp08XAYjvv//+I48dM2aMCEBcsmSJdltKSoo4ZcoU8YknnhDt7e1Fd3d3sXnz5uL06dPFrKwsnfONOfbIkSNix44dRUdHR9HV1VXs06eP+Pfffxv1e1FSVlaWOH36dLF+/fqivb29GBgYKL755ptiSkpKub+nO3fuFJ955hnR09NTlMvlYmBgoDhw4EBx//79Bo8/d+6cCED09/c3uN4PPR74bCyix8iMGTOwYMEC7NmzB88880xVF4fI4lauXIlRo0bho48+wieffFLVxaEqwrBDZIPi4+NRp04dnW0XLlzQLssfFxcHBweHKiodkXUolUo8+eST+Pfff3Hr1q0Kz4Yj28MxO0Q2qFWrVggLC0OTJk3g7OyMa9euYefOnVCpVPjuu+8YdMimHT16FH/++ScOHTqECxcu4K233mLQecyxZYfIBs2ZMwdbtmxBbGwsHj58CA8PDzz11FP44IMPDE6/JrIls2fPxpw5c+Dl5YUhQ4bgyy+/rPBihGSbGHaIiIjIpnGdHSIiIrJpDDtERERk0xh2iIiIyKYx7BAREZFN49TzImlpaQafx2IqHx8fJCcnm/26pIv1bB2sZ+tgPVsP69o6LFHPUqkUnp6eFTvWrHeuwZRKpcEn+ppCEATttTnpzXJYz9bBerYO1rP1sK6tozrUc7UKO//88w+2bduGW7duIS0tDR988AHatGlT7jmXLl3C6tWrcffuXdSqVQtDhgzhOiJERESkVa3G7OTl5SEkJASvvfZahY5PSkrCf/7zHzRu3BiLFi1C3759sXz5cr2n5RIREdHjq1q17LRs2RItW7as8PH79u2Dr68vXn75ZQBAYGAgLl++jJ07d6JFixYWKiURERHVJNUq7Bjr2rVraNq0qc625s2bY+XKlWWeU1BQoDM2RxAE7TLimn5Fc9Fcz9zXJV2sZ+tgPVsH69l6WNfWUR3quUaHHYVCAXd3d51t7u7uyMnJQX5+PuRyud45mzdvxsaNG7Xv69Wrh4ULF8LHx8di5fTz87PYtakY69k6WM/WwXq2Hta1dVRlPdfosFMZgwYNQr9+/bTvNUkzOTnZ7FPPBUGAn58fEhMTOdLfgljP1sF6tg7Ws/Wwrq3DUvUslUor3FBRo8OOh4cH0tPTdbalp6fD0dHRYKsOAMhkMshkMoP7LPXDLooif5GsgPVsHaxn62A9Ww/r2jqqsp6r1WwsY4WHh+PChQs6286fP48nnniiikpERERE1U21Cju5ubmIjY1FbGwsAPXU8tjYWKSkpAAA1qxZg2XLlmmP79mzJ5KSkvDLL78gLi4Oe/fuxYkTJ9C3b9+qKD4RERFVQ9WqG+vGjRuYM2eO9v3q1asBAJ07d8aECROQlpamDT4A4Ovri2nTpmHVqlXYtWsXatWqhfHjx3PaOREREWkJIjsqAagHKFvicRH+/v5ISEhgf7AFsZ6tg/VsHaxn62FdW4el6lkmk1V4gHK16sYiIiIiMrdq1Y1lS5RKJXJycuDg4ICMjAy9NGuJxZUqe01rn2fuawqCgOzsbOTm5hr9v4bq8hmq4jxjrykIAgoLC1FYWGiwnm3hcxORbWLYsZDk5GT89ttvVV0MIjJCdQhepl6rOnwGU69pzfMkEkm5U6JrwmeoTuUo67y6deuie/fulbqmOTDsWIggCLCzs4MgCEa1NlhyrR9rnkdUE/H3hMgy0tMzqvT+HKBchAOUrcfc/6A8anVOU+reEt83a/+Daq7PIAgCateujfv370OlUlm9LI/L90IQBPj6+iIpKalCx1dFndrK90IQBPj4+CA5Odksn6mmfi9EUURhIaAqFKEqFKFUql8rVSJUhUChUr2/sGh/YdE2lUq9rbBQhEopQll0jUKViEIloCoENMXzre2Czj39q2yAMlt2yOrM3TyqaUXTNEeTZWgemmtvb896tiBBEODh4YGcnBzWs4VpArxKpaoRda1SiShUqsNIYaEIZYE6eCiV6u2FyhKvC0UoC4qOK72v5DWK9pmTAEAqQCdhyGUO5r2JkRh2iIiIzETTSlJWqDAUOLSvlaJ2v/Z9ofo8TUuKpUnsAKlUgJ1UgNQO6j+lAuykxdvV2wA7u+J9Bo+zUx8nlUkQEOCPxMREy3+AMjDsEBHRY0dV1EWTlVmAzIxCFBSotCFFL5g8qpWk1HmWJggwGCoMBQ6pVIBdqdBSvF2AVFYitNgBgsQyA9WrevYkww4REVVLOq0kBgKHXktIpVpJFBYrf4VaSewAqUwou5XEToCdTDfQSCRcesFYDDtERGQSlapEa4fBwFHidaH+vqpvJSnultG+LqdbpsxWEp33lmklocph2CEiegyIorrbRlmqlcRgS0jpMScGWlBKhpiqHktSMmBoWkkMhpZSrSQlx5LUhAHKVHkMO0RE1YhKJSIvrxC5OSr1OJIa10oCbUuHocChHiei2xKic5yh82x4LAlZB8MOEZGRSreSlAwZFW4lKUTR1GFDrSQKi5Zf20piZ2CGjcFBrWW0kpTax7EkVF0x7BCRzdKMJSkOFGW0kpQxzkRnNk6poAIL93qU10qiM/W3mrSSEFVnDDtEVKW0rSSF+gujVaaVpOQ+q44lKauVxK70DJvyW0lkMgEBgf5ISqq6NUmIbA3DDhFVSIXHkpQ1G0e74mvxPk2AsVYrSfH03jJaScraVyK0lF6/xNytJIIgQCqVGP1cPSIqG8MOkQ2pcCtJoYGVXEvsM7RGibXHkhhsCXlUK0kZrSscS0L0eGPYIaoCoqr0TJmKtZLoPxenVKCxQisJBOi1hOi0eJQRVAwtMa8TTDiWhIgshGGHqAy6rSRlrDVSUHZLiP60YOuPJdFfBM24VpKS+ziWhIhqKoYdqvFElYj8R40lKTEbR69rp6x91a6VpKIP4rNMKwnHkhBRTcWwQ1ZR2VaSkkvQl99KorBo+cttJSkrcJTTSqIJLhxLQkRkeQw7pKO8sST6D+LTbwkxGFSs2UpSRqgo/0F8pZ78a4VWEiIish6GnRpIFNWtGcY++feRrSSF6tYXSzOllcTgeTIBgRxLQkREZWDYsSBDY0l0AofOg/jKayXRX1jN+q0k5Tzdt/Q+WVlPD1Z350g4loSIiKyIYcdCHiQrcfxAJiw+lkQCg6FC00pSVuAovcS8TrePnQCJHceSEBGRbWDYsRA7uxJvKthKoj+otfSKrZZvJSEiIrI1DDsW4uZhh2cGuXMsCRERURWTVHUBbJVEIsDeXqIdS0JERERVg2GHiIiIbBrDDhEREdk0hh0iIiKyaQw7REREZNMYdoiIiMimMewQERGRTWPYISIiIpvGsENEREQ2jWGHiIiIbBrDDhEREdk0hh0iIiKyaQw7REREZNMYdoiIiMimMewQERGRTWPYISIiIpvGsENEREQ2jWGHiIiIbBrDDhEREdk0hh0iIiKyaQw7REREZNMYdoiIiMimMewQERGRTWPYISIiIpvGsENEREQ2jWGHiIiIbBrDDhEREdk0hh0iIiKyaQw7REREZNMYdoiIiMimMewQERGRTWPYISIiIpvGsENEREQ2jWGHiIiIbBrDDhEREdk0hh0iIiKyaQw7REREZNOkVV2A0vbs2YPt27dDoVAgODgYo0ePRlhYWJnH79y5E/v27UNKSgrc3NzQtm1bjBw5EnK53IqlJiIiouqqWrXsHD9+HKtXr8bQoUOxcOFCBAcHY/78+UhPTzd4/NGjR7FmzRo899xz+OKLLzB+/HicOHECa9eutXLJiYiIqLqqVmFnx44d6NatG7p27YrAwECMGTMGcrkcBw8eNHj8lStX0KBBA3To0AG+vr5o3rw52rdvj+vXr1u55ERERFRdVZuwo1QqcfPmTTRt2lS7TSKRoGnTprh69arBcxo0aICbN29qw839+/cRExODli1bWqXMREREVP1VmzE7GRkZUKlU8PDw0Nnu4eGB+Ph4g+d06NABGRkZmDlzJgCgsLAQPXr0wODBg8u8T0FBAQoKCrTvBUGAo6Oj9rU5aa5n7uuSLtazdbCerYP1bD2sa+uoDvVcbcJOZVy6dAmbN2/G66+/jvDwcCQmJmLFihXYuHEjhg4davCczZs3Y+PGjdr39erVw8KFC+Hj42Oxcvr5+Vns2lSM9WwdrGfrYD1bD+vaOqqynqtN2HFzc4NEIoFCodDZrlAo9Fp7NNavX49OnTqhW7duAICgoCDk5ubi+++/x+DBgyGR6PfSDRo0CP369dO+1yTN5ORkKJVK83yYEtf28/NDYmIiRFE067WpGOvZOljP1sF6th7WtXVYqp6lUmmFGyqqTdiRSqUIDQ3FxYsX0aZNGwCASqXCxYsX0atXL4Pn5OXl6TWLGQo4JclkMshkMoP7LPXDLooif5GsgPVsHaxn62A9Ww/r2jqqsp6rTdgBgH79+uGbb75BaGgowsLCsGvXLuTl5aFLly4AgGXLlsHLywsjR44EAERGRmLnzp2oV6+ethtr/fr1iIyMfGToISIiosdDtQo77dq1Q0ZGBjZs2ACFQoGQkBBMnz5d242VkpKi05IzZMgQCIKAdevWITU1FW5uboiMjMTzzz9fRZ+AiIiIqhtBZNsdAPWYnZKztMxBEAT4+/sjISGBTaQWxHq2DtazdbCerYd1bR2WqmeZTFbhMTvs6yEiIiKbxrBDRERENo1hh4iIiGwaww4RERHZNIYdIiIismkMO0RERGTTGHaIiIjIpjHsEBERkU1j2CEiIiKbxrBDRERENo1hh4iIiGwaww4RERHZNIYdIiIismkMO0RERGTTGHaIiIjIpjHsEBERkU1j2CEiIiKbxrBDRERENo1hh4iIiGwaww4RERHZNIYdIiIismkMO0RERGTTGHaIiIjIpjHsEBERkU1j2CEiIiKbxrBDRERENo1hh4iIiGwaww4RERHZNIYdIiIismkMO0RERGTTGHaIiIjIpjHsEBERkU1j2CEiIiKbxrBDRERENo1hh4iIiGwaww4RERHZNIYdIiIismkMO0RERGTTGHaIiIjIpjHsEBERkU0zKexs2bIFqamp5ioLERERkdlJTTl53bp1WLduHRo2bIhOnTrhqaeegqOjo7nKRkRERGQyk1p2vv32W4wcORKZmZlYvnw5xo4di6VLl+Ls2bNQqVTmKiMRERFRpZnUsuPl5YX+/fujf//+uHPnDo4ePYpjx47hxIkTcHV1Rbt27dCxY0eEh4ebq7xERERERjEp7JQUFBSEkSNHYuTIkfj333+xc+dO7N27F3v37oWfnx86deqE7t27w93d3Vy3JCIiInoks87Gys/Px7Fjx7B161acOXMGEokELVu2RN26dbFp0ya8/fbb+Ouvv8x5SyIiIqJymdyyI4oizp8/jyNHjuDUqVPIzc1FSEgIXnzxRXTo0EHbkpOWloYvv/wSq1evRps2bUwuOBEREVFFmBR2Vq5ciRMnTkChUMDT0xM9evRA586dUbduXb1jPT09ERUVhW+++caUWxIREREZxaSws3//frRp0wadO3dG06ZNIQhCucdHRETgjTfeMOWWREREREYxKez88MMPcHBwqPDxvr6+8PX1NeWWREREREYxaYCyUqnE7du3y9x/584dZGZmmnILIiIiIpOYFHZWrlyJ77//vsz933//PX7++WdTbkFERERkEpPCzqVLlxAZGVnm/sjISFy4cMGUWxARERGZxKSwk5GRATc3tzL3u7q6Ij093ZRbEBEREZnEpLDj4eGBW7dulbn/5s2b5YYhIiIiIkszKey0bt0aBw4cwOnTp/X2nTp1CgcPHuQCgkRERFSlTJp6PmzYMFy4cAGfffYZQkJCtIsJ3r17F7GxsQgMDMSwYcPMUlAiIiKiyjAp7Dg5OWH+/PnYtm0boqOjcfLkSQBA7dq1MWTIEPTv39+odXiIiIiIzM3kZ2M5ODhg2LBhbMEhIiKiasmsTz0nIiIiqm5MbtnJz89HdHQ0bt26hezsbKhUKp39giDweVhERERUZUwKO8nJyZgzZw6Sk5Ph5OSE7OxsuLi4aEOPq6srx+wQERFRlTKpG+vnn39GdnY25s+fjy+//BIA8P7772P16tV44YUXIJfLMWPGDLMUlIiIiKgyTH5cRM+ePREWFgaJRH0pURQhk8nQv39/NGnSBCtXrjRHOYmIiIgqxaSwk5eXB19fXwCAo6MjACA7O1u7/4knnsDly5dNuQURERGRSUwas+Pt7Y0HDx4AAOzs7ODl5YVr166hbdu2AIB79+5BLpcbdc09e/Zg+/btUCgUCA4OxujRoxEWFlbm8VlZWVi7di3++usvZGZmwsfHB6+88gqefPLJyn8wIiIishkmhZ0mTZrg9OnTeO655wAAXbp0wZYtW5CZmQlRFHH48GF07ty5wtc7fvw4Vq9ejTFjxiA8PBw7d+7E/PnzsXTpUri7u+sdr1QqMW/ePLi5uWHixInw8vJCSkoKnJycTPlYREREZENMCjsDBw7E9evXUVBQAJlMhkGDBiEtLQ3R0dGQSCTo0KEDXn755Qpfb8eOHejWrRu6du0KABgzZgzOnj2LgwcPYuDAgXrHHzhwAJmZmfjkk08glao/iqZbjYiIiAgwQzeWt7e39r1cLsf48eMxfvx4o6+lVCpx8+ZNnVAjkUjQtGlTXL161eA5Z86cQXh4OH766SecPn0abm5uaN++PQYOHKgdMF1aQUEBCgoKtO8FQdCONxIEwehyl0dzPXNfl3Sxnq2D9WwdrGfrYV1bR3Wo50qHnby8PLzxxhsYOHAg+vfvb3JBMjIyoFKp4OHhobPdw8MD8fHxBs+5f/8+kpOT0aFDB3z44YdITEzEjz/+iMLCQm3XWmmbN2/Gxo0bte/r1auHhQsXwsfHx+TPUBY/Pz+LXZuKsZ6tg/VsHaxn62FdW0dV1nOlw469vT3s7Oxgb29vzvIYRRRFuLm5Ydy4cZBIJAgNDUVqaiq2bdtWZtgZNGgQ+vXrp32vSZrJyclQKpVmLZ8gCPDz80NiYiJEUTTrtakY69k6WM/WwXq2Hta1dViqnqVSaYUbKkzqxmrbti1OnjyJnj17mtw85ebmBolEAoVCobNdoVDotfZoeHh4QCqV6nRZBQQEQKFQQKlUasfxlCSTySCTyQxez1I/7KIo8hfJCljP1sF6tg7Ws/Wwrq2jKuvZpHV22rVrh4yMDMyZMwdHjhzB5cuXcfPmTb2vipBKpQgNDcXFixe121QqFS5evIgnnnjC4DkNGjRAYmKizvO4EhIS4OnpaTDoEBER0ePHpEQwZ84c7et///23zOPWr19foev169cP33zzDUJDQxEWFoZdu3YhLy8PXbp0AQAsW7YMXl5eGDlyJACgZ8+e2Lt3L1auXIlevXohMTERmzdvRu/evSv/oYiIiMimmBR2zP00c01L0YYNG6BQKBASEoLp06dru7FSUlJ0usu8vb0xY8YMrFq1CpMnT4aXlxd69+5tcJo6ERERPZ4EkR2VANQDlEtOSTcHQRDg7++PhIQE9gdbEOvZOljP1sF6th7WtXVYqp5lMlmFByibNGaHiIiIqLozqRvr22+/feQxgiCYvbuLiIiIqKJMCjuXLl3S26ZSqaBQKKBSqeDm5lal6/AQERERmRR2vvnmG4PblUol/vjjD+zcuRMzZ8405RZEREREJrHImB2pVIpevXqhefPm+OmnnyxxCyIiIqIKsegA5eDg4HLX3yEiIiKyNIuGnfPnz3PMDhEREVUpk8bslHx6eElZWVn4999/cevWLQwYMMCUWxARERGZxKSw89tvvxnc7uzsjNq1a2PMmDHo1q2bKbcgIiIiMolJYaeiz7wiIiIiqipcQZmIiIhsmklh5/z581izZk2Z+9euXYuLFy+acgsiIiIik5gUdjZt2oQHDx6UuT81NRWbNm0y5RZEREREJjEp7Ny5cwfh4eFl7q9fvz7u3Lljyi2IiIiITGJS2FEqlVAqleXuz8vLM+UWRERERCYxKezUrVsXf/31l8F9oigiOjoagYGBptyCiIiIyCQmhZ1evXrhypUrWLJkCe7cuYPCwkIUFhbi9u3bWLJkCa5evYpevXqZq6xERERERjNpnZ1OnTrh/v372LRpE6KjoyGRqLOTSqWCIAgYMmQIunTpYo5yEhEREVWKSWEHAJ577jl07NgRf/31F5KSkgAAtWvXRuvWreHn52dyAYmIiIhMYXLYAQA/Pz/079/fHJciIiIiMiuTxuzcvHkTe/fuLXP/3r17ERsba8otiIiIiExiUthZt24dLly4UOb+ixcvYt26dabcgoiIiMgkJrfsRERElLm/YcOGuHHjhim3ICIiIjKJSWEnJycHdnZ2Ze4XBAHZ2dmm3IKIiIjIJCaFHX9/f/z9999l7j937hxq165tyi2IiIiITGJS2ImKikJMTAxWrVqFrKws7fasrCysXLkS586dQ1RUlMmFJCIiIqosk6ae9+7dG7Gxsdi1axd2794NT09PAEBaWhpEUUTHjh3Rt29fsxSUiIiIqDJMCjuCIODNN99Ep06dEB0drV1UsHXr1mjbti0aN25slkISERERVZZZFhVs0qQJmjRporddpVIhJiYGkZGR5rgNERERkdHMEnZKu3LlCo4cOYKTJ0/i4cOHWL9+vSVuQ0RERPRIZgs79+7dw9GjR3H06FEkJyfDwcEBzZs3Z6sOERERVSmTwk5qaiqOHTuGo0ePIjY2FnK5HPn5+RgxYgSeffZZSKUWaTgiIiIiqjCj00h2djZOnjyJo0eP4t9//4VcLkdkZCSGDx8OX19fTJo0CXXq1GHQISIiomrB6EQyduxYAEDLli3xzjvvIDIyEnK5HACQmJho3tIRERERmcjoRQULCgrg7OwMX19f1K5dWxt0iIiIiKojo1t2lixZgiNHjuDo0aPYsWMH/Pz80L59e7Rv377c52QRERERVQWjw05AQABGjBiBESNG4PLlyzhy5Aj27t2LTZs2wdfXFwDw8OFDsxeUiIiIqDJMGkUcERGBiIgIjB49GjExMTh8+DDS0tLwww8/YNu2bWjVqhUiIyO5kjIRERFVGbNMmbKzs0OrVq3QqlUr5OTkIDo6GkeOHMGuXbuwc+dOLipIREREVcbosJOeng53d/cy9zs6OqJLly7o0qULUlNTcfz4cZMKSERERGSKSk09r1+/Pp588kk8+eSTCA0NLfNYLy8v9OvXz6QCEhEREZnC6LAzefJkxMTE4MCBA/jtt9/g7u6OFi1aIDIyEs2aNYOjo6MlyklERERUKUaHHc3YHAC4c+cOzp49i5iYGCxduhSCIKBBgwbaVp+AgACzF5iIiIjIGCYNUA4KCkJQUBAGDhyI7OxsnDt3DjExMdi2bRt++eUX+Pr6omXLlnjyySfRuHFjyGQyc5WbiIiIqELM9gArJycntGvXDu3atQMAXL9+Xdvqs2/fPgwdOhRDhw411+2IiIiIKsRiT+sMCwtDWFgYhg0bhvT0dGRnZ1vqVkRERERlMinspKSkICUlBREREdptsbGx2LFjBwoKCtC+fXu0adMG7u7u5U5XJyIiIrIUox8EWtL//d//4bffftO+VygUmDNnDqKjo/Hvv/9i8eLFiI6ONrmQRERERJVlUti5ceMGmjZtqn1/+PBh5Ofn47PPPsPy5cvRtGlTbN++3eRCEhEREVWWSWEnMzNTp3vqzJkzaNSoEfz8/CCRSNCmTRvExcWZXEgiIiKiyjIp7Li5uSE5ORkAkJWVhWvXrqF58+ba/SqVCiqVyrQSEhEREZnApAHKTZs2xe7du+Hk5IRLly5BFEW0adNGu//evXuoVauWyYUkIiIiqiyTws7IkSORkJCAn3/+GVKpFC+99BJ8fX0BAAUFBThx4gTat29vloISERERVYZJYcfDwwOffPIJsrOzIZfLIZUWX04URcycORPe3t4mF5KIiIiossyyqKCTk5PeNrlcjpCQEHNcnoiIiKjSTAo7Fy5cwK1bt9C/f3/tNs3T0JVKJdq3b4+XX34ZEolJ46CJiIiIKs2kFPLbb78hNjZW+/7OnTv44Ycf4ObmhkaNGmH37t3Ytm2bqWUkIiIiqjSTwk5cXBzq16+vfX/48GE4Ojpi7ty5eP/999GtWzccPnzY5EISERERVZZJYSc3NxeOjo7a9+fOnUOLFi1gb28PQP0wUM06PERERERVwaSw4+3tjRs3bgAAEhMTcffuXTRr1ky7PzMzEzKZzLQSEhEREZnApAHKHTp0wMaNG5Gamop79+7B2dkZrVu31u6/efMm/P39TS4kERERUWWZFHYGDx4MpVKJmJgYeHt7480334SzszMAdavOpUuX0KdPH7MUlIiIiKgyTAo7dnZ2eP755/H888/r7XNxccEPP/xgyuWJiIiITGaWRQUB9WDllJQUAOqxPA4ODua6NBEREVGlmRx2rl+/jl9//RWXL1/WPuFcIpEgIiICL774os7U9Iras2cPtm/fDoVCgeDgYIwePRphYWGPPO/YsWP48ssv0apVK0yZMsXo+xIREZHtMWk21rVr1zBr1izcvHkTUVFReOWVV/DKK68gKioKt27dwqxZs3D9+nWjrnn8+HGsXr0aQ4cOxcKFCxEcHIz58+cjPT293POSkpLw888/o2HDhqZ8JCIiIrIxJoWddevWwcvLC19++SXGjBmDPn36oE+fPhgzZgyWLl0KT09PrF271qhr7tixA926dUPXrl0RGBiIMWPGQC6X4+DBg2Weo1Kp8PXXX2PYsGHap64TERERAWZo2enRowc8PDz09nl4eKB79+64du1aha+nVCpx8+ZNNG3atLiAEgmaNm2Kq1evlnnexo0b4ebmhqioKKPKT0RERLbPpDE7giCgsLCwzP0qlQqCIFT4ehkZGVCpVHrhycPDA/Hx8QbPuXz5Mg4cOIBFixZV6B4FBQUoKCjQvhcEQbsKtDFlrQjN9cx9XdLFerYO1rN1sJ6th3VtHdWhnk0KOw0aNMDevXvRoUMH+Pj46OxLSUnBvn37EBERYVIBy5OTk4Ovv/4a48aNg5ubW4XO2bx5MzZu3Kh9X69ePSxcuFCv/Obk5+dnsWtTMdazdbCerYP1bD2sa+uoyno2Kew8//zzmDVrFt577z20adNGu1pyfHw8Tp8+DYlEYnANnrK4ublBIpFAoVDobFcoFAa7yu7fv4/k5GQsXLhQu00URQDAiBEjsHTpUr3KHTRoEPr166d9r0maycnJUCqVFS5rRQiCAD8/PyQmJmrLRebHerYO1rN1sJ6th3VtHZaqZ6lUWuGGCpPCTr169bBgwQKsXbsWp0+fRn5+PgBALpejRYsWeO655+Dq6lrh60mlUoSGhuLixYto06YNAHVX2MWLF9GrVy+94+vUqYPPP/9cZ9u6deuQm5uLV199Fd7e3nrnyGSyMp/XZakfdlEU+YtkBaxn62A9Wwfr2XpY19ZRlfVs8jo7gYGBmDx5MlQqFTIyMgAUt9D8/vvvWL9+PdavX1/h6/Xr1w/ffPMNQkNDERYWhl27diEvLw9dunQBACxbtgxeXl4YOXIk5HI5goKCdM7XPK6i9HYiIiJ6PJltBWWJRGKwq8lY7dq1Q0ZGBjZs2ACFQoGQkBBMnz5de+2UlBQOJiMiIqIKM1vYMadevXoZ7LYCgNmzZ5d77oQJEyxQIiIiIqqpTFpnh4iIiKi6Y9ghIiIim2Z0N9bNmzcrfGxqaqqxlyciIiIyK6PDzocffmiJchARERFZhNFh54033rBEOYiIiIgswuiwo1nvhoiIiKgm4ABlIiIismkMO0RERGTTGHaIiIjIpjHsEBERkU1j2CEiIiKbxrBDRERENo1hh4iIiGwaww4RERHZNIYdIiIismkMO0RERGTTGHaIiIjIpjHsEBERkU1j2CEiIiKbxrBDRERENo1hh4iIiGwaww4RERHZNIYdIiIismkMO0RERGTTGHaIiIjIpjHsEBERkU1j2CEiIiKbxrBDRERENo1hh4iIiGwaww4RERHZNIYdIiIismkMO0RERGTTGHaIiIjIpjHsEBERkU2TVnUBagKlUons7OxKnZuTk4P8/Hwzl4hKe1Q9i6IIqVQKZ2dnK5aKiIiqA4adR1AqlcjKyoKrqyskEuMbwmQyGQoKCixQMiqpIvWclZWFvLw82NvbW6lURERUHbAb6xGys7MrHXSoenFyckJeXl5VF4OIiKyM/4JXAIOObRAEoaqLQEREVYD/ihMREZFNY9ghIiIim8awQ4/Utm1b/PDDD2a51vHjxxEQEID09HSzXI+IiOhROBvLRg0dOhSNGjXC3LlzTb7Wrl274OTkZIZSERERWR/DzmNKFEUUFhZCKn30j0CtWrWsUCIiIiLLYDeWDXrvvfdw4sQJ/PTTTwgICEBAQADWr1+PgIAAHDhwAL169UK9evXw119/ITY2FqNGjULz5s0RHh6OPn364PDhwzrXK92NFRAQgDVr1uC1115D/fr10b59e+zbt6/S5d25cye6du2KevXqoW3btli+fLnO/pUrV6J9+/YIDQ1F8+bNMWbMGO2+HTt2oFu3bggKCkLjxo0xfPjwSi8ASUREtoktO0YSRRHIr/haLaKqEKK5FhWU21do+vTcuXNx8+ZNRERE4IMPPgAAXLlyBQCwYMECfPzxxwgKCoK7uzvi4+MRFRWFqVOnQi6XY+PGjRg1ahQOHz6MgICAMu+xZMkSfPTRR/joo4+wYsUKvPXWW4iOjoanp6dRH+n8+fMYP348Jk6ciP79++P06dOYPn06PD09MXz4cPz999/4+OOP8dVXX6FVq1ZQKBSIjo4GANy/fx8TJkzAjBkz8Oyzz2r3iaJoVBmIiMi2MewYKz8PqreGVfhwcy5hJ1m2AbB3eORxbm5ukMvlcHBwgK+vLwDg+vXrAIDJkyejU6dO2mM9PT3RuHFj7fspU6Zgz5492LdvH0aNGlXmPYYNG4aBAwcCAKZNm4affvoJ586dQ9euXY36TN9//z06dOiA999/HwBQv359XLt2DcuXL8fw4cMRFxcHJycndO/eHS4uLggMDESTJk0AAElJSVAqlejTpw+CgoLg7++Phg0bGnV/IiKyfezGesw0a9ZM531WVhbmzp2Lzp07o2HDhggPD8e1a9cQFxdX7nVKhgonJye4uroiJSXF6PJcu3YNrVu31tnWunVr3Lp1C4WFhejUqRMCAwPx9NNP4+2338bvv/+OnJwcAECjRo3QoUMHdOvWDa+99hp+/fVXKBQKo8tARES2jS07xpLbq1tYHkHMzwcy0yEpLISqIB9QFgDldq8IgFQKSGVFX9LiP2UyCBI7QG76M51Kz6qaO3cujhw5gpkzZyIkJAQODg4YO3bsIx9eKpPJdEsvCFCpVCaXrzQXFxfs2bMHx48fx+HDh/H5559j8eLF2LVrF9zd3bFu3TqcPn0aR44cwYoVK7Bw4ULs2LEDQUFBZi8LERHVTAw7RhIEoUJdSYK9A+Dqpn1ApSiKgFKpDj3KAqCgoPi1sgDQBAVVIZBfCJTOGnZ2gFQGUSoDZLISoUgG2NnpjeWRyWQVCh+nT5/Gc889h969ewNQt/Tcu3evQnVhDuHh4Th16pTOtlOnTiE0NBR2dnYAAKlUik6dOqFTp06YOHEiGjZsiGPHjqFPnz4QBAGtW7dGu3bt8O6776JNmzbYvXs3xo0bZ7XPQERE1RvDjpUIgqAOKaVaRICiQc+qQt0AVFBQFI7ygcLC4q+8XP2LSyTqEKT5kskQ6O+Ps2fP4M6dO3BxcSkz+NSrVw+7d+9Gjx49IAgCPvvsM4u00JRl3Lhx6NOnD7744gv0798fZ86cwYoVK7BgwQIAwP/+9z/cuXMHbdu2hYeHB/bv3w+VSoX69evj7NmzOHr0KDp37gw/Pz/89ddfSE1NRXh4uNXKT0RE1R/DTjUgCAJgJ1V/wVFvv6gqBAqUui1B2mCkVLcK5efpzBIbP7Af3pt3AV27dEFuXh6WzP5Yfa0MBUSZnTYYzZo1CxMnTsSAAQPg5eWFCRMmIDMz01ofHU2bNsXy5cvx+eef48svv4Svry8mT56M4cOHAwDc3d2xe/duLFmyBLm5uahXrx6++eYbNGjQANeuXUN0dDR+/PFHZGZmIiAgAB9//DGioqKsVn4iIqr+BJHzdAEAycnJKDAwRTwjIwNubm6Vvq6mG8tSRFGlDjylu8U0LUPiI1pp7KTa1qCSLUOQygCJpMY8Kbyi9Wzq9/NxJggC/P39kZCQwOn9FsR6th7WtXVYqp5lMhl8fHwqdCxbdmo4QZAAMrn6qxRRFNVdX6VbgzR/qgqBQqX6Ky9H/+Ilu8dKhyE7aY0JQkRE9Hhj2LFhgqCZ4VVG95ihIKTpGtMMmi7VPVbi4nrjhCCVYdqs2fh9yxaD5Rk8eDAWLlxo3g9JRET0CAw7jzHBzk49y8vA7DJRpdINPqW7yUQRKMhXf5XwwcjnMG5A36LuMbvibjKpFK7uHhALC9X3JSIishKGHTJIkEjU6/oYWNtH3T2m1O8WUxbAu1YteJf1yIiCHODuTYgSO8NjhMqYRk9ERGQKhh0ymrp7rCiclKI7jd7AukKFSvX+vDKm0QtF44RkUoNhiEGIiIiMxbBDZqU7jV6ftnvM0OyxwqLZYwV56i/9q0OU6s8eE2QyiOwaIyKiMjDskFU9sntMG36KFlQsOWZIVBXvL9EoJAIoAHTGB+l1k0nYPUZE9Lhi2KFqQ73KdNE0+lKTx/Sm0ZduHSosOY3ewMWLptGLaWlQ/XsW8PGH4OMH+PgBXj4cNE1EZMMYdqhGeNQ0eqmdBMrsbIg6LUMGVpl+mA5x72YA6hYhAOoZabVqA75+RQHIX/snfGpDMMMDWImIqOow7JBBbdu2xeuvv44xY8Y88tiAgAD89NNP6NWrlxVKZpggUU+hF8qcRl8UfkQJhG7PQkxKAJITgZRE9b6keCApXhuAdNb49PACfPwg+PoXBSA/CD7+6nDk7GqNj0dERCZg2CGbpx4nJAfkcgi1fCAZURzgRJUKUDwAkhIgJicCyQlAUmLR60QgJwtQpAKKVIjX/ik+T/PCyVm3S8zHD4JvHfVrDy/1vYmIqEox7NBjTZBIAC8f9bidiGY6+0RRBLIeAsmJxS1B2lCUCKSnAtlZwO3rEG9fLz5P80IqKw5Amu4x36JQVKs2BJn+1H0iIjI/hh0b9Msvv2DJkiU4ffo0JCVaFkaNGgVPT0+88847mDNnDs6ePYvs7GyEh4dj2rRp6NSpk1nu/++//+Ljjz/G2bNn4eDggL59+2LWrFlwdnYGABw/fhzz58/HlStXIJPJ8MQTT+Cbb75BYGAgLl26hFmzZuH8+fMQBAH16tXDwoUL0bx5c7OUzRiCIAAuboCLG4R6T+jtF/Py1N1gyQkQk9QBSEwuCkUPktTdZgl3gYS7+t1jgqAOWYaCkI8/BEcna31MIiKbVy3Dzp49e7B9+3YoFAoEBwdj9OjRCAsLM3jsH3/8gcOHD+Pu3bsAgNDQUDz//PNlHm8qURSRV1jxp7YWQoUC5SOePF5B9nZChaZP9+vXDzNnzsSxY8fQsWNHAEBaWhoOHTqE1atXIysrC1FRUZg6dSrkcjk2btyIUaNG4fDhwwgICDCpjNnZ2XjhhRcQGRmJnTt3IiUlBZMnT8aMGTOwdOlSKJVKvPbaaxg5ciS++eYbFBQUICYmRvu53n77bTRu3Bj/+c9/IJFIcOnSJUil1fLHFIK9PRAQDAQEo/R3RSwsBFKTDQeh5ET1gooPkoAHSRAvn1efU/ICLm46Y4OKw5A/4ObBafREREaodv+KHD9+HKtXr8aYMWMQHh6OnTt3Yv78+Vi6dCnc3d31jv/nn3/Qvn17NGjQADKZDFu3bsW8efOwZMkSeHl5mb18eYUihq+/avbrVsT64U/AQfrof+Q8PDzQtWtXbNmyRRt2du7cCS8vL7Rv3x4SiQSNGzfWHj9lyhTs2bMH+/btw6hRo0wq4+bNm5GXl4cvv/wSTk7q1ol58+bh1VdfxYwZMyCVSpGRkYHu3bsjJCQEABAeHq49Py4uDuPHj9eG1dDQUJPKU1UEO7viLqxGuvtEUQQeKorHBiUlqEORJgg9TAcyM4DMDIi3in/WtGHI3gHwrq3TGiQUDZxGLV9OoyciKqXahZ0dO3agW7du6Nq1KwBgzJgxOHv2LA4ePIiBAwfqHf/OO+/ovB8/fjyio6Nx4cIFdO7c2RpFrpYGDRqEKVOmYMGCBbC3t8fmzZvRv39/SCQSZGVlYfHixdi/fz+SkpKgVCqRm5uLuLg4k+977do1NGzYUBt0AKB169ZQqVS4ceMGnnrqKQwbNgwvvPACOnbsiI4dO+LZZ59F7dq1AQBjx47F5MmTsWnTJnTs2BH9+vXThiJbIQgC4OYJuHlCCGuot1/Myda2AGlag7ShKDVF3SoUdxuIu63fPWZnV9Q9ZiAI+fgZnK1GRGTrqlXYUSqVuHnzpk6okUgkaNq0Ka5erVhrSl5eHpRKJVxcXAzuLygoQEFBgfa9IAhwdHTUvn4UezsB64frj98oi0wqQ4Gy4NEHVoC9XcW7Lnr06AFRFLF//340b94c0dHRmD17NgBg7ty5OHLkCGbOnImQkBA4ODhg7NixyM/PL/+iZvLFF1/gtddew8GDB7Ft2zYsWrQIa9euRWRkJCZNmoSBAwdi//79OHjwIBYvXoxvv/0WvXv3Ntv9q3sXkODkDATXV3+VIioLgJSk4hCUlFAiFN1XP4VeE5SKJo/pdI+5e2qn0Wunz2vCkItbuXWj2Vfd66+mYz1bD+vaOqpDPVersJORkQGVSgUPDw+d7R4eHoiPj6/QNX799Vd4eXmhadOmBvdv3rwZGzdu1L7XDID18fExeHxOTg5kpWbNyCtUkmIOMusvSieTydC3b19s2bIFd+7cQVhYGJ588kkAwJkzZzBixAj0798fAJCZmYl79+7Bzs5O+1kFQdB5/yiaYyMiIvDbb78hPz9fOyA5JiYGEolE29UIAC1btkTLli0xceJE9O7dG9u2bcNTTz0FAIiIiEBERAQmTJiAcePG4bffftOW9VGf+VHkcjn8/f0r9JmqrbpBBjeLKhUKU5OhTLhX/JV4D8qEOBQm3IMqMwNITwPS0yBe/xelR54JTs6Q+gdC6heo/rNOXe1ru1rFq0z7+flZ+AMSwHq2Jta1dVRlPVersGOqLVu24NixY5g9ezbkcsORZNCgQejXr5/2vSZpJicnQ6lU6h2fn5+v0xJkLJlMZtL5phgwYABeffVVXL58GYMHD9aWIyQkBDt27EBUVBQEQcBnn30GlUqFwsJC7TGiKOq8fxTNsQMGDMCiRYswYcIETJo0CQ8ePMCHH36IIUOGwNPTEzdu3MCvv/6KHj16wM/PDzdu3MDNmzcxZMgQZGRkYN68eejbty+CgoKQkJCAmJgY9OnT55HlqGg95+fnIyEhoUKfqcbyrqP+atpGu0kCQMjKLB4wnRQPseSg6bQHELOzUHDjCgpuXNG/plQKePvBITAY+e5eJabUF60yLTP2vwBUFkEQ4Ofnh8TERPX4LrIY1rV1WKqepVJpmQ0Vesea7a5m4ObmBolEAoVCobNdoVDotfaUtm3bNmzZsgUzZ85EcHBwmcfJZLIyWwBs7Ye9Q4cO8PDwwI0bNzBo0CDt9lmzZmHixIkYMGAAvLy8MGHCBGRmZprlno6Ojvj111/x8ccfo2/fvjpTzzX7r1+/jt9++w1paWnw9fXFq6++ipdeeglKpRJpaWl49913kZKSAi8vL/Tu3RuTJk0yS9k0bO37XGFOzkBwGIRg9eDvkg3KYn4ekHK/uEus5MKKKffVq0wn3kNu4j396woC4Fmr1OKKJcYMORnuUqbyiaL4+P6sWhnr2jqqsp4FsZp9h6dPn46wsDCMHj0aAKBSqfDmm2+iV69eBgcoA8DWrVvx+++/Y8aMGXjiiYqPpykpOTnZYMtARkYG3NzcKnVNoGpbdh4nFa1nU7+fjyNRVageGJ1yH+552VBcv1I0VqioVSg3p/wLOLsWrydU9MgN9Ws/wN2L4yVKEQQB/v7+SEhI4D/AFsa6tg5L1bNMJquZLTuAeo2Yb775BqGhoQgLC8OuXbuQl5eHLl26AACWLVsGLy8vjBw5EoC662rDhg1455134Ovrq20VcnBwgIMDZ54QmUqQ2AHetSH4+MHF3x8PS/yFJYqiepp8UoK2RUhnTaEMhXoV6qyHEGOvaa+p/etOLge8/XTWFNKGIi9fCNV0jSUiqlmq3d8k7dq1Q0ZGBjZs2ACFQoGQkBBMnz5d242VkpKi8z/B//3vf1AqlViyZInOdYYOHYphw4ZZs+g26ffff8fUqVMN7gsMDMTBgwetXCKqTgRBAFzdAVd3CPUj9PaLuTnqVaa13WIJxY/eSE0G8vOB+DtA/B39afSaR3mUDkKah7E6OFrrYxJRDVfturGqCruxDMvMzERycrLBfTKZDIGBgVYukWHsxrI8czdFi0olkJqkG4Q044SSE9RBqDyu7oBmCn1Rt5j2tat7je0eY9eK9bCurYPdWFTtubi4lLlmEZEpBKkU8K0D+NbRf9yGKKoftFoiCGkXV0xOADIfqleafpgO8cbl4vM0L+wdSwQgP91Q5OWt7pojoscGww4RVTuCIAAetQCPWhCeaKy3X8zO0rYAFS+sWBSE0h4AeTnAvVvAvVsGVpmWArV8dbrFirvHakOQW39dLCKyLIYdIqpxSq4yrdcqVJAPpCTpdItpxwmlJKqn0SfFq9ca0pxT8gIetfTHB2nGDDm7WucDEpFZMewQkU0RZHLAPxDwD9QPQqpCIC21RBAqtaZQThageAAoHkC8eqn4PM0LJ+cSU+f9dZ895uEFQSKx1sckIiMw7BDRY0OQ2AG1fIBaPhAimunsE0VRPU0+qYwglJ4KZGcBt69DvH29+DzNC5m86Gn0JbrHigIRvH0hSCv26BUiMj+GHSIiFI0TcnFTPxA1tIHefjEvT90NpnnkRok/kZqsfghrwl0g4a5+95ggAby8SwWhEqtNOzpZ62MSPZYYduiR2rZti9dffx1jxoyp6qIQVRnB3h4ICAYCgvW7xwoL1YFHG4BKLKyYlADk5wEPkoAHSRAvn1efU/ICru46q0xnhUdAlDlC9PED3Dxq7DR6ouqCYcdGDR06FI0aNcLcuXNNvtauXbvg5MT/eRKVRbCzK344aiPdfaIoqleSLhGEdNYUKppCj4fpEG+qH8KaWvIC9g5F3WOa1qDiP+FV/DR6Iiobw85jSvNUc2kFluOvVauWFUpEZJsEQQDcPQF3TwhhjfT2iznZRQGoaNZYSiLk6anIu3db/UyyvFwg7jYQd9vANHq7olWmSzx4VTNg2scPgj0fmUMEMOzYpPfeew8nTpzAiRMn8NNPPwEAlixZgokTJ+Lnn3/GokWLcPnyZaxZswZ16tTBnDlzcPbsWWRnZyM8PBzTpk1Dp06dtNcr3Y0VEBCAzz77DPv378ehQ4fg5+eHWbNmoWfPno8sW2FhIaZMmYJjx44hOTkZderUwSuvvILXX39d57h169bhu+++Q2xsLDw8PNCnTx/Mnz8fAJCeno758+dj7969ePjwIUJCQjBz5kx07drVXFVIZDWCoxMQFAoEhUKAOhz5Fq02q9JOoy/uFhM1XWPJiYCyoDgo/aO+nk73mLtXie6xUmsKubiye4weGww7RlK3iFT8eEEQoVSaZ3lsOztU6C+nuXPn4ubNm4iIiMAHH3wAALhyRd08vmDBAnz88ccICgqCu7s74uPjERUVhalTp0Iul2Pjxo0YNWoUDh8+jICAgDLvsWTJEnz00Uf46KOPsGLFCrz11luIjo6Gp6dnuWVTqVTw9/fHd999B09PT5w+fRpTpkyBr68v+vfvDwBYtWoV5s6diw8//BBdu3bFw4cPcerUKe35L774IrKysvD1118jODgYV69ehR2b8skGCVIZ4BcA+AUYmEavAhSpuuODSq4plJ2pnkGWngrx+j/F52leODrprCGkE4Q8a3EaPdkUhh0jFRYCuzelV8m9ew9xR0UeAu3m5ga5XA4HBwf4+voCAK5fV0+VnTx5sk6rjaenJxo3Ll6hdsqUKdizZw/27duHUaNGlXmPYcOGYeDAgQCAadOm4aeffsK5c+ce2boik8m0AQwAgoKCcObMGWzfvl0bdr766iuMHTtWp7WnRYsWAIAjR47g3LlzOHToEOrXrw8ACA4OrvHPICMyliApmuHl5Q2hQRO9/WLWw6Kp8wm644SSEtVrCeVkA3duQrxzs/gczQuptHickKZLzNdfHYS8a0OQcRo91SwMO4+ZZs101xbJysrC4sWLsX//fiQlJUGpVCI3NxdxcXHlXqdhw4ba105OTnB1dUVKSkqFyrBy5UqsW7cOcXFxyM3NRUFBgTZwpaSkIDExER06dDB47qVLl+Dv768NOkRkmODsCtRzhVAvXG+fmJ8HpNwv0RJUIgg9SFKvMp0YByTGGZhGLwCetXSCkM6YISc+S4+qH4YdI9nZqVtYKsqcLQ7m6KkpPatq7ty5OHLkCGbOnImQkBA4ODhg7NixyH/EE6dlpf5nJwgCVCrVI++/detWfPLJJ5g5cyZatWoFZ2dn/Pe//0VMTAwAwMGh/AGVj9pPRI8myO2BOkFAnSDDq0ynphR3j5V8GGtSovq5Y6kpQGoKxCsXis/TvHBx1Q9CmjFD7l4cJ0RVgmHHSIIgVKgrSUMqFSCK1v/llslkFQofp0+fxnPPPYfevXsDULf03Lt3z2LlOnXqFCIjI/Hqq69qt92+fVv72sXFBXXr1sXRo0fRvn17vfMbNmyIhIQE3Lhxg607RBYgSOzUXVjetSE0bK6zTxRF9TT5EkFIZ8xQhkL9RPrMhxBvXS0+T/NCLge8dbvFtEHIyxeCMX+5EhmBP1k2qm7duoiJicHdu3fh7OxcZvCpV68edu/ejR49ekAQBHz22WcVCkmVVa9ePWzcuBGHDh1C3bp1sWnTJvz999+oW7eu9piJEyfiww8/hLe3N7p27YqsrCycOnUKo0ePxtNPP422bdti7NixmDVrFkJCQnD9+nXIZDJ07NjRYuUmoqIJEm4e6oUO60fo7Rdzc9SrTCcVd4tpg9CDZCA/H4i/A8Tf0e8ek0iKptGXePCq5hlk3n4QHByt9CnJFjHs2Khx48bhvffeQ5cuXZCbm4slS5YYPG7WrFmYOHEiBgwYAC8vL0yYMAGZmZkWK9eLL76Iixcv4o033oAgCBgwYABeeeUVHDhwQHvMsGHDkJeXhx9++AGffPIJvLy80LdvX+1+zfY333wTOTk52qnnRFS1BAdHILAeEFhPv3tMqQRSk3S6xXSeRp+frx5HlHIf4r9/q88peQE3D911hHxLvHZ1Z/cYlUsQRdE886JruOTkZINjazIyMuDm5lbp63KWkHVUtJ5N/X4+zgRBgH/R+i/8a8NyHsd6FkVRPU2+5Pig5BKvMx+WfwEHR73xQdog5OWt7poz4HGs66pgqXqWyWTw8fGp0LFs2SEioiolCALgUQvwqAXhicZ6+8XszKKZYwaCUNoDIDcHuHsLuHvLwCrTUqCWr063WMlVpunxwLBDZjV16lT8/vvvBvcNHjwYCxcutHKJiKimE5xcgOAwCMFhevtE7SrTxd1i2iCUcl89jT4pHkiK1w9CAOJr+aKwlk/xgoolxww5u1rl85HlMeyQWU2ePBnjx483uM/VlX9xEJF5CTI54B8I+AcankafllriwaulptLnZKNQ8zT6q5eKz9O8cHIpMXOs1LPHPLy4ynQNwrBDZuXt7Q1vb++qLgYRkXqsTi0foJYPhAjdBVVFUYSQ9RC1VEqkXL6gbhXSBqFE9Rii7Ezg9nWIt68Xn6d5IZMXrTJdHIa0QcjbV/2oD6o2GHaIiOixIwgCBFd32Pv7Q+JeS2/grJiXW/y8Mc04Ic2YoQdJQEE+kHAXSLhrYJXpokd5aB7C6uNf3Drk6wfBQXdxV7I8hh0iIqJSBHsHIDAECAzR7x4rLARSk4vGCSXq/InkRCA/Tx2IHiRBvHxefU7JC7i66wQhdetQ0Ws3D06jtwCGHSIiIiMIdnbFY3ga6e4TRVG9krQ2AJV8CGsCkJmhXoX6YTrEm1eKz9O8sHfQGx+kDUJePup7k9EYdoiIiMxEEATA3RNw94QQ1khvv5iTXTx9PqlEEEpOVD9zLC8XuBcL3Is1MI3ermiVaX9tANIGIW8/CPb2VvqUNQ/DDhERkZUIjk5AUH0gqL6BVaYLSkyjLxWEkhMBZUHxOKJ/is4peQF3r+LuMU0Y0jxyw9n1se4eY9ghg9q2bYvXX38dY8aMqeqiEBE9FgSpDPALAPwCDEyjVwGKVN0HryYnFq0tlABkZ6lnkKWnQrz+T/F5mheOzoaDkI8/4FnL5qfRM+wQERFVc4KkaIaXlzeEBk309otZD3UfvJpc/DBWKB4AOVnAnRsQ79woPkfzQiotmkbvX2IavaZ7rDYEWc2fRs+wQ0REVMMJzq5APVcI9cL19on5eUDyfZ3FFbVB6EGSepXpxDggMc7ANHoB8KxVoiVIs65QUShycrbWRzQJw44N+uWXX7BkyRKcPn0akhJNk6NGjYKnpyfeeecdzJkzB2fPnkV2djbCw8Mxbdo0dOrUqVL3++6777Bhwwbcvn0bHh4e6NGjBz766CM4Oxf/Epw6dQoLFy5ETEwM7O3t0aJFC3z77bfw8PCASqXC8uXL8euvvyI+Ph7e3t548cUX8e6775pcF0REjztBbg8EBAEBQYZXmU5N0ekS0wah5EQgL0e9PzUF4pUL6nNKXsDFVScI6YwTcvesNuOEGHaMJIoilEqlUeeY66nnUqm0Qj84/fr1w8yZM3Hs2DF07NgRAJCWloZDhw5h9erVyMrKQlRUFKZOnQq5XI6NGzdi1KhROHz4MAICAowul0Qiwdy5cxEUFITbt29j+vTpmDdvHj799FMAwMWLFzF8+HAMHz4cc+bMgVQqxfHjx6FSqQAAn376KdasWYNZs2ahTZs2SEpKwvXr18u7JRERmYEgsVN3YXnXhtCwuc4+URTV0+Q144SSSiyymJSg3pf5EMh8CPHW1eLzNC/k9tousfQmLYEufa33wUoRRD7XHgCQnJxsMJRkZGTAzc1N+76goAD//e9/rVk0rTfeeAOyCvadjh49Gp6enli8eDEAdWvPF198gVOnTum09mhERUXhpZdewqhRowCYNkB5x44dmDZtGi5evAgAmDBhAuLi4rBlyxa9YzMzM9GsWTPMmzcPI0eONPpeGjKZrEKhsvT3kypOEAT4+/sjISFBb7VZMh/Ws/Wwrk0j5mbrdo+VHDP0IBkQVdpj5Q2bQTVpvlnrWSaTwcfHp0LHsmXHRg0aNAhTpkzBggULYG9vj82bN6N///6QSCTIysrC4sWLsX//fiQlJUGpVCI3NxdxcXGVutfhw4exbNky3LhxAw8fPkRhYSFyc3ORk5MDR0dHXLp0Cf369TN47rVr15CXl4cOHTqY8nGJiMjKBAcnoG49oG49A9PolUBqkroFKPk+XAICkVElpVRj2DGSVCrFG2+8UeHjK9riUNF7V1SPHj0giiL279+P5s2bIzo6GrNnzwYAzJ07F0eOHMHMmTMREhICBwcHjB07Fvn5+UaX6e7du3j11Vfx0ksvYerUqfDw8MCpU6cwadIk5Ofnw9HREQ4ODmWeX94+IiKqmQSpFPCtA/jWgSAIcPb3R0ZCQpWVh2HHSIIgVKgrqVAloqBQhAAJCmGe5b0LlSJKDQ0rm50cPZ/phY2bfse1G7cQGlof4RGNkVugwl+nTmHQkKHo2v0ZAEBWVhbu3r2HNm2B3AJ1s6MoAspCUfteT1GMPxPzN1QqFabOmKntHtu8dRsAIE+pQq5ShSciInD4yFG89d5EvcvUqRsMBwcHHPzzCIY//3zFK6MUJQqhVJZR1hKy8wuR9CC3zP3mGktXPYbkFTPH5xIEAZl2mUhOy1X/gFQT5hoAabbvmYkXEiAgR5aFlPQ8szT5V5fPVXwZ8/12mHolQRBQ4JCN5If51etn2lzXqSZ/EQmCAFlmXpWWgWHHQgoKRdzLyANQdd/gdj374cO3xuDfy1fQo9+AovIAtQODsWPXLjR5qjMEQcBPy75AoaoQmfmF2mMKRRGKXKX2fVkcvOugoKAAX/33B7TrEoULMWfwy88/AwDiMvKRgTwMemksRg3pg4mTp2LAsJGQymSI+eskuvTsDQ9PLzw/aiw+XTAfD5UCmrZ8EorUVMTeuIa+g4cZ8WkrVs/xD3Kx+PR9I65Lum5VdQEeEzerugCPkRuPPoRM1rROMuZHGT8BxlwYdixEEACZnQB1Rq/8/xhM+b9Gm6fbwdXdA3dib+KZvv0hlahj/rtTZmDBzKmY8PIweHh44oXXxiEnKwuCAO0xACCRCDrvDYlo2AhvT5mBNSu+x/dffY4Wka0x/r3J+GT6B5AWnV8vNBRffL8K3335OcaPHAx7Bwc0atpcW6bRb7wNmVSKFd8uRUpSEmr5+GDgsJGPvLcOQajQ/8xkdgK8ndQ/9mb5f5yZ/jNojsuY7f+l5dSjxM4OqsJCq5TFfJ+nWlzCqOtIJBLtbEX9i5heGmt/HstfpPKXEQRB24JmrsYd81zGDN/navR55HZVu0IzZ2MVqehsLGOZc8wOlY2zsSyPM1esg/VsPaxr67BUPRszG8u2H4ZBREREjz12Y1G5fv/9d0ydOtXgvsDAQBw8eNDKJSIiIjIOww6Vq2fPnmjZsqXBfRVd4JCIiKgqMexQuVxcXODi4lLVxSAiIqo0jtkhIiIim8awQ0RERDaNYacCylzvgmoUTi0lIno8Mew8gpOTEx4+fMjAYwOys7Nhb29f1cUgIiIr4wDlR5BKpXB2dkZmZmalzpfL5ZV6wCYZ51H1LIoipFIpww4R0WOIYacCpFJppVbd5eqc1sF6JiKi8rAbi4iIiGwaww4RERHZNIYdIiIismkMO0RERGTTOEC5iFRquaqw5LWpGOvZOljP1sF6th7WtXWYu56NuZ4gcvoKERER2TB2Y1lQTk4Opk6dipycnKouik1jPVsH69k6WM/Ww7q2jupQzww7FiSKIm7dusW1XyyM9WwdrGfrYD1bD+vaOqpDPTPsEBERkU1j2CEiIiKbxrBjQTKZDEOHDoVMJqvqotg01rN1sJ6tg/VsPaxr66gO9czZWERERGTT2LJDRERENo1hh4iIiGwaww4RERHZNIYdIiIisml8IIiJ9uzZg+3bt0OhUCA4OBijR49GWFhYmcefOHEC69evR3JyMvz8/PDCCy/gySeftGKJayZj6vmPP/7A4cOHcffuXQBAaGgonn/++XK/L6Rm7M+zxrFjx/Dll1+iVatWmDJlihVKWrMZW89ZWVlYu3Yt/vrrL2RmZsLHxwevvPIK/+54BGPreefOndi3bx9SUlLg5uaGtm3bYuTIkZDL5VYsdc3yzz//YNu2bbh16xbS0tLwwQcfoE2bNuWec+nSJaxevRp3795FrVq1MGTIEHTp0sWi5WTLjgmOHz+O1atXY+jQoVi4cCGCg4Mxf/58pKenGzz+ypUr+PLLLxEVFYWFCxeidevW+Oyzz3Dnzh0rl7xmMbae//nnH7Rv3x6zZs3CvHnzUKtWLcybNw+pqalWLnnNYmw9ayQlJeHnn39Gw4YNrVTSms3YelYqlZg3bx6Sk5MxceJELF26FOPGjYOXl5eVS16zGFvPR48exZo1a/Dcc8/hiy++wPjx43HixAmsXbvWyiWvWfLy8hASEoLXXnutQscnJSXhP//5Dxo3boxFixahb9++WL58Oc6dO2fRcjLsmGDHjh3o1q0bunbtisDAQIwZMwZyuRwHDx40ePyuXbvQokUL9O/fH4GBgRgxYgRCQ0OxZ88eK5e8ZjG2nt955x0888wzCAkJQUBAAMaPHw9RFHHhwgUrl7xmMbaeAUClUuHrr7/GsGHD4Ovra8XS1lzG1vOBAweQmZmJyZMnIyIiAr6+vmjUqBFCQkKsW/Aaxth6vnLlCho0aIAOHTrA19cXzZs3R/v27XH9+nUrl7xmadmyJUaMGPHI1hyNffv2wdfXFy+//DICAwPRq1cvPPXUU9i5c6dFy8mwU0lKpRI3b95E06ZNtdskEgmaNm2Kq1evGjzn6tWrOscDQPPmzXHt2jWLlrUmq0w9l5aXlwelUgkXFxdLFbPGq2w9b9y4EW5uboiKirJGMWu8ytTzmTNnEB4ejp9++gljxozBpEmT8Pvvv0OlUlmr2DVOZeq5QYMGuHnzpjbc3L9/HzExMWjZsqVVyvy4uHbtmsF/Byv693llccxOJWVkZEClUsHDw0Nnu4eHB+Lj4w2eo1Ao4O7urrPN3d0dCoXCQqWs+SpTz6X9+uuv8PLy0vsFo2KVqefLly/jwIEDWLRokRVKaBsqU8/3799HcnIyOnTogA8//BCJiYn48ccfUVhYiOeee84Kpa55KlPPHTp0QEZGBmbOnAkAKCwsRI8ePTB48GBLF/exUta/gzk5OcjPz7fY+CiGHbJpW7ZswbFjxzB79mwOMjSjnJwcfP311xg3bhzc3Nyqujg2TRRFuLm5Ydy4cZBIJAgNDUVqaiq2bdvGsGNGly5dwubNm/H6668jPDwciYmJWLFiBTZu3IihQ4dWdfHIRAw7leTm5gaJRKLXKqNQKPT+N6Hh4eGhNzguPT29zOOpcvWssW3bNmzZsgUzZ85EcHCw5QppA4ytZ01rw8KFC7XbNE+eGTFiBJYuXQo/Pz9LFrlGquzfG1KpFBJJ8aiDgIAAKBQKKJVKSKX8a7y0ytTz+vXr0alTJ3Tr1g0AEBQUhNzcXHz//fcYPHiwTv1T5ZX176Cjo6NF/0PK714lSaVShIaG4uLFi9ptKpUKFy9exBNPPGHwnCeeeEJvkOz58+cRHh5u0bLWZJWpZwDYunUrNm3ahOnTp6N+/frWKGqNZmw916lTB59//jkWLVqk/YqMjNTOsPD29rZm8WuMyvw8N2jQAImJiTpjdBISEuDp6cmgU4bK1HNeXh4EQdDZxoBjfuHh4Qb/HSzv73Nz4HfSBP369cP+/ftx6NAh3Lt3Dz/++CPy8vK06wUsW7YMa9as0R7fp08f/P3339i+fTvi4uKwYcMG3LhxA7169aqiT1AzGFvPW7Zswfr16/HGG2/A19cXCoUCCoUCubm5VfQJagZj6lkulyMoKEjny9nZGQ4ODggKCuI/wuUw9ue5Z8+eyMzMxMqVKxEfH4+zZ89i8+bNeOaZZ6roE9QMxtZzZGQk/ve//+HYsWNISkrC+fPnsX79ekRGRjL0lCM3NxexsbGIjY0FoJ5aHhsbi5SUFADAmjVrsGzZMu3xPXv2RFJSEn755RfExcVh7969OHHiBPr27WvRcvJvJBO0a9cOGRkZ2LBhAxQKBUJCQjB9+nRtM2lKSorO/xQaNGiAd955B+vWrcPatWvh7++PyZMnIygoqIo+Qc1gbD3/73//g1KpxJIlS3SuM3ToUAwbNsyaRa9RjK1nqhxj69nb2xszZszAqlWrMHnyZHh5eaF3794YOHBg1XyAGsLYeh4yZAgEQcC6deuQmpoKNzc3REZG4vnnn6+iT1Az3LhxA3PmzNG+X716NQCgc+fOmDBhAtLS0rTBBwB8fX0xbdo0rFq1Crt27UKtWrUwfvx4tGjRwqLlFERNRzsRERGRDWLbHBEREdk0hh0iIiKyaQw7REREZNMYdoiIiMimMewQERGRTWPYISIiIpvGsENEREQ2jWGHiB5Lhw4dwrBhw3Djxo2qLgoRWRhXUCYiizh06BC+/fbbMvfPmzfP4s/DsaZTp05h8eLFWLlyJRwcHLBixQrcvn0bs2fPruqiET32GHaIyKKGDRsGX19fve229lT0a9euISgoCA4ODgCAq1evokmTJlVcKiICGHaIyMJatmz5WDx5/saNGwgPDwcA5OfnIzY2FoMGDariUhERwLBDRFUsKSkJb731Fl588UVIJBLs2rUL6enpCAsLw2uvvab3oNyLFy9iw4YNuHXrFuzs7NCoUSOMHDkSgYGBOselpqZi/fr1OHfuHB4+fAhPT0+0aNECo0aN0nkqe0FBAVatWoXDhw8jPz8fzZo1w7hx4+Dm5vbIsmdkZGhf37hxA61atUJGRgZu3LiBwsJC1K5dGxkZGbC3t4e9vb2JNUVElcUHgRKRRWjG7MycORPBwcE6+wRBgKurK4DisBMUFIScnBz07NkTBQUF2LVrFyQSCT7//HPtk6rPnz+PTz/9FL6+vujWrRvy8/Oxe/duqFQqLFy4UNtdlpqaig8//BDZ2dno1q0bAgICkJqaipMnT2LevHlwdnbWlq9evXpwdnZGmzZtkJSUhF27dqFt27Z4//33H/kZhw0bVqG6GDp0aIWPJSLzY8sOEVnUJ598ordNJpPh119/1dmWmJiIr776Cl5eXgCAFi1aYPr06di6dSteeeUVAMAvv/wCFxcXzJ8/Hy4uLgCA1q1bY8qUKdiwYQPeeustAMCaNWugUCiwYMECnS604cOHo/T/71xcXPDRRx9BEAQAgCiK2L17N7Kzs+Hk5FTuZ/voo48AACdPnsSpU6fw9ttvAwB+/fVXeHp6ok+fPgCA2rVrV6CmiMhSGHaIyKJee+01+Pv762yTSPRXvWjdurU26ABAWFgYwsPDERMTg1deeQVpaWmIjY1F//79tUEHAIKDg9GsWTPExMQAAFQqFU6dOoXIyEiDY4U0oUaje/fuOtsaNmyInTt3Ijk5Wa9FqrRmzZoBAPbt24cmTZqgWbNmUKlUSExMRO/evbX7iahqMewQkUWFhYVVaIBy6UCk2XbixAkAQHJyMgCgTp06escFBATg77//Rm5uLnJzc5GTk6M31qcs3t7eOu+dnZ0BAFlZWeWel5mZCZVKBQD4559/MHjwYGRkZODOnTva+2dkZEAul2tnaBFR1WDYIaLHmqFWJgB63V2lTZ06VRvAAGD16tVYvXq19v20adMAAJ07d8aECRPMUFIiqiyGHSKqFhISEgxu8/HxAQDtn/Hx8XrHxcfHw9XVFQ4ODpDL5XB0dMSdO3csWt63334b+fn5OHXqFE6cOIF33nkHALBu3Tq4urqib9++AKDTNUdEVYOPiyCiauHUqVNITU3Vvr9+/TquXbuGFi1aAAA8PT0REhKCP//8U6eL6c6dO/j777/RsmVLAOqWmtatW+PMmTMGHwVhrgmoERERaNasGXJycvDEE0+gWbNmaNasGVJSUhAZGal9X3pKPBFZH1t2iMiiYmJiEBcXp7e9QYMGOrOU/Pz8MHPmTJ2p566urhgwYID2mBdffBGffvopPvroI3Tt2hX5+fnYs2cPnJycdKZ2jxw5EufPn8fs2bPRrVs3BAYGIi0tDSdPnsTcuXO143LM4cqVK+jevTsA4P79+1AoFGjQoIHZrk9EpmPYISKL2rBhg8Htb775pk7Y6dSpEyQSCXbu3ImMjAyEhYVh9OjR8PT01B7TrFkzTJ8+HRs2bMCGDRu0iwq+8MILOo+k8PLywoIFC7Bu3TocPXoUOTk58PLyQosWLcy6uJ9CocD9+/e14ebq1atwdHRE3bp1zXYPIjIdFxUkoipVcgXl/v37V3VxiMgGccwOERER2TSGHSIiIrJpDDtERERk0zhmh4iIiGwaW3aIiIjIpjHsEBERkU1j2CEiIiKbxrBDRERENo1hh4iIiGwaww4RERHZNIYdIiIismkMO0RERGTTGHaIiIjIpv0/NZQmahODZqAAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# plotting the training loss and accuracy\n", + "N = len(H.history['loss'])\n", + "plt.style.use(\"ggplot\")\n", + "plt.figure()\n", + "plt.plot(np.arange(0,N), H.history[\"loss\"], label=\"train_loss\")\n", + "plt.plot(np.arange(0,len(H.history['val_loss'])), H.history[\"val_loss\"], label=\"val_loss\")\n", + "plt.plot(np.arange(0,N), H.history[\"accuracy\"], label=\"train_acc\")\n", + "plt.plot(np.arange(0,len(H.history[\"val_accuracy\"])), H.history[\"val_accuracy\"], label=\"val_acc\")\n", + "plt.title(\"Training Loss and Accuracy\")\n", + "plt.xlabel(\"Epoch #\")\n", + "plt.ylabel(\"Loss/Accuracy\")\n", + "plt.legend(loc=\"lower left\")\n", + "plt.savefig(\"plot.png\")" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "id": "eaee9298", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'accuracy': [0.9156405925750732, 0.96875],\n", + " 'loss': [0.25978943705558777, 0.0960015207529068],\n", + " 'val_accuracy': [0.974189281463623, 0.9735274910926819],\n", + " 'val_loss': [0.0842733383178711, 0.08401167392730713]}" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "H.history" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f907650a", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/mask_detector.ipynb b/notebooks/mask_detector.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..88ddce1f0cb2cb096c12782241ce7461ff651908 --- /dev/null +++ b/notebooks/mask_detector.ipynb @@ -0,0 +1,853 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "4d70291b", + "metadata": {}, + "outputs": [], + "source": [ + "# import the necessary packages\n", + "from tensorflow.keras.applications.mobilenet_v2 import preprocess_input\n", + "from tensorflow.keras.preprocessing.image import img_to_array\n", + "from tensorflow.keras.models import load_model\n", + "from imutils.video import VideoStream\n", + "import numpy as np\n", + "import imutils\n", + "import time\n", + "import cv2\n", + "import os" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "d59f4c2f", + "metadata": {}, + "outputs": [], + "source": [ + "def detect_and_predict_mask(frame, faceNet, maskNet):\n", + " # grab the dimensions of the frame and then construct a blob from it\n", + " (h, w) = frame.shape[:2]\n", + " blob = cv2.dnn.blobFromImage(frame, 1.0, (224,224),(104.0,177.0,123.0) )\n", + " \n", + " # pass the blob through the network and obtain the face detections\n", + " faceNet.setInput(blob)\n", + " detections = faceNet.forward()\n", + " print(detections.shape)\n", + " \n", + " # initialize our list of faces, their corresponding locations, and the list of predictions from our face mask network\n", + " faces = []\n", + " locs = []\n", + " preds = []\n", + " # loop over the detections\n", + " for i in range(0,detections.shape[2]):\n", + " # extract the confidence (i.e., probability) associated with the detection\n", + " confidence = detections[0,0,i,2]\n", + " \n", + " # filter out weak detections by ensuring the confidence is greater than minimum confidence\n", + " if confidence > 0.5:\n", + " # compute the (x, y)-cordinates of the bounding box for the object\n", + " box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])\n", + " (startX, startY, endX, endY) = box.astype(\"int\")\n", + " \n", + " # ensure the bounding boxes fall within the dimensions of the frame\n", + " (startX , startY) = (max(0,startX) , max(0,startY))\n", + " (endX, endY) = (min(w-1,endX) , min(h-1,endY))\n", + " \n", + " # extract the face ROI, convert it from BGR to RGB channel ordering, resize it to 224x224, and preprocess it face=frame[startY:endY, startX:endX]\n", + " # bounding mask only for face detected\n", + " face = frame[startY:endY , startX:endX]\n", + " face = cv2.cvtColor(face, cv2.COLOR_BGR2RGB)\n", + " face = cv2.resize(face, (224,224))\n", + " face = img_to_array(face)\n", + " face = preprocess_input(face)\n", + " \n", + " # add the face and bounding boxes to their respective lists\n", + " faces.append(face)\n", + " locs.append((startX, startY, endX, endY))\n", + " \n", + " # only make a predictions if at least one face was detected\n", + " if len(faces) > 0:\n", + " # far faster inference we'll make batch predictions on *all* faces at the same time rather than one-by-one predictions in the above 'for' loop\n", + " faces = np.array(faces,dtype=\"float32\")\n", + " preds = maskNet.predict(faces, batch_size=32)\n", + " \n", + " # return a 2-tuple of the face locations and their corresponding locations\n", + " return (locs, preds)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "74bfdab6", + "metadata": {}, + "outputs": [], + "source": [ + "# load our serialized face detector model from disk\n", + "prototxtPath = r\"deploy.prototxt.txt\"\n", + "weightsPath = r\"res10_300x300_ssd_iter_140000.caffemodel\"\n", + "faceNet = cv2.dnn.readNet(prototxtPath,weightsPath)\n", + "\n", + "# load the face mask detector model from disk\n", + "maskNet = load_model(\"mask_detector.model\")" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "52cc9df2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[INFO] starting video stream...\n", + "[INFO] starting video stream...\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 62ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 64ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 59ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 111ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 78ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 67ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 63ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 59ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 56ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 49ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 55ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 64ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 67ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 51ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 56ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 57ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 57ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 51ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 55ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 49ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 48ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 51ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 56ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 54ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 60ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 54ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 58ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 54ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 70ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 68ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 56ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 57ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 49ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 58ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 59ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 55ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 54ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 53ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 54ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 61ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 53ms/step\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 46ms/step\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 54ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 54ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 54ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 56ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 51ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 55ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 53ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 59ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 55ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 53ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 64ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 51ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 51ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 49ms/step\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 49ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 61ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 55ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 74ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 62ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 58ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 59ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 49ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 48ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 51ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 55ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 51ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 53ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 54ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 51ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 53ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 53ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 51ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 55ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 53ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 49ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 57ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 60ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 51ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 59ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 57ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 62ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 59ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 54ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 51ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 53ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 54ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 59ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 51ms/step\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 48ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 53ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 54ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 54ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 60ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 60ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 49ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 49ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 47ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 47ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 48ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 51ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 55ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 54ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 51ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 49ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 48ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 54ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 48ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 47ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 51ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 49ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 53ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 53ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 51ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 49ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 49ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 49ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 51ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 53ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 51ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 51ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 49ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 50ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 52ms/step\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 51ms/step\n" + ] + } + ], + "source": [ + "# initialize the video stream\n", + "print(\"[INFO] starting video stream...\")\n", + "vs = VideoStream(src=0).start()\n", + "\n", + "# initialize the video stream\n", + "print(\"[INFO] starting video stream...\")\n", + "vs = VideoStream(src=0).start()\n", + "# loop over the frames from the video stream\n", + "while True:\n", + " # grab the frame from the threaded video stream and resize it to have a max width of 400 pixels\n", + " frame = vs.read()\n", + " frame = imutils.resize(frame,width=400)\n", + " \n", + " # detect faces in the frame and determine if they are wearing a face mask or not\n", + " (locs, preds) = detect_and_predict_mask(frame, faceNet, maskNet)\n", + " \n", + " # loop over the detected face locations and their correspondings locations\n", + " for (box, pred) in zip(locs, preds):\n", + " # unpack the bounding box and predictions\n", + " (startX, startY, endX, endY) = box\n", + " (mask, withoutMask) = pred\n", + " \n", + " # determine the class label and color we'll use to draw the bounding box and text\n", + " label = \"Mask\" if mask> withoutMask else \"No Mask\"\n", + " color = (0,255,0) if label==\"Mask\" else (0,0,255)\n", + " \n", + " # include the probability in the label\n", + " label = \"{}: {:.2f}%\".format(label,max(mask, withoutMask) *100)\n", + " \n", + " # display the label and bounding box rectangle on the output frame\n", + " cv2.putText(frame,label,(startX,startY-10), cv2.FONT_HERSHEY_SIMPLEX, 0.45, color, 2)\n", + " cv2.rectangle(frame, (startX,startY), (endX,endY),color,2)\n", + " \n", + " # show the output frame\n", + " cv2.imshow(\"Frame\",frame)\n", + " key = cv2.waitKey(1) & 0xFF\n", + " \n", + " # if the 'q' key was pressed, break from the loop\n", + " if key == ord(\"q\"):\n", + " break\n", + " \n", + " \n", + "# do a bit of cleanup\n", + "cv2.destroyAllWindows()\n", + "vs.stop()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "8b404a2f", + "metadata": {}, + "outputs": [], + "source": [ + "vs.stop()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "7fe320b0", + "metadata": {}, + "outputs": [], + "source": [ + "cv2.destroyAllWindows()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a24deadc", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/mask_detector_with_gradio.ipynb b/notebooks/mask_detector_with_gradio.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..06d6d0b01782a724424247be504bcc6cbe529a48 --- /dev/null +++ b/notebooks/mask_detector_with_gradio.ipynb @@ -0,0 +1,461 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 5, + "id": "f51609a4", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "& was unexpected at this time.\n" + ] + } + ], + "source": [ + "!pip install gradio" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "9d989bf2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2.16.1\n" + ] + } + ], + "source": [ + "import tensorflow as tf\n", + "print(tf.version.VERSION)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "d789a404", + "metadata": {}, + "outputs": [], + "source": [ + "from tensorflow.keras.models import load_model\n", + "from tensorflow.keras.layers import TFSMLayer" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "1ca99ffa", + "metadata": {}, + "outputs": [ + { + "ename": "OSError", + "evalue": "SavedModel file does not exist at: mask_detector.model\\{saved_model.pbtxt|saved_model.pb}", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mOSError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[7], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m model \u001b[38;5;241m=\u001b[39m \u001b[43mTFSMLayer\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mmask_detector.model\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcall_endpoint\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mserving_default\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32md:\\Programming\\Projects\\Mask_detector\\maskVenv\\Lib\\site-packages\\keras\\src\\export\\export_lib.py:710\u001b[0m, in \u001b[0;36mTFSMLayer.__init__\u001b[1;34m(self, filepath, call_endpoint, call_training_endpoint, trainable, name, dtype)\u001b[0m\n\u001b[0;32m 707\u001b[0m \u001b[38;5;66;03m# Initialize an empty layer, then add_weight() etc. as needed.\u001b[39;00m\n\u001b[0;32m 708\u001b[0m \u001b[38;5;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39m\u001b[38;5;21m__init__\u001b[39m(trainable\u001b[38;5;241m=\u001b[39mtrainable, name\u001b[38;5;241m=\u001b[39mname, dtype\u001b[38;5;241m=\u001b[39mdtype)\n\u001b[1;32m--> 710\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_reloaded_obj \u001b[38;5;241m=\u001b[39m \u001b[43mtf\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msaved_model\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mload\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfilepath\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 712\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfilepath \u001b[38;5;241m=\u001b[39m filepath\n\u001b[0;32m 713\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcall_endpoint \u001b[38;5;241m=\u001b[39m call_endpoint\n", + "File \u001b[1;32md:\\Programming\\Projects\\Mask_detector\\maskVenv\\Lib\\site-packages\\tensorflow\\python\\saved_model\\load.py:912\u001b[0m, in \u001b[0;36mload\u001b[1;34m(export_dir, tags, options)\u001b[0m\n\u001b[0;32m 910\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(export_dir, os\u001b[38;5;241m.\u001b[39mPathLike):\n\u001b[0;32m 911\u001b[0m export_dir \u001b[38;5;241m=\u001b[39m os\u001b[38;5;241m.\u001b[39mfspath(export_dir)\n\u001b[1;32m--> 912\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[43mload_partial\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexport_dir\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[43m)\u001b[49m[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mroot\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n\u001b[0;32m 913\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m result\n", + "File \u001b[1;32md:\\Programming\\Projects\\Mask_detector\\maskVenv\\Lib\\site-packages\\tensorflow\\python\\saved_model\\load.py:1016\u001b[0m, in \u001b[0;36mload_partial\u001b[1;34m(export_dir, filters, tags, options)\u001b[0m\n\u001b[0;32m 1011\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m tags \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(tags, \u001b[38;5;28mset\u001b[39m):\n\u001b[0;32m 1012\u001b[0m \u001b[38;5;66;03m# Supports e.g. tags=SERVING and tags=[SERVING]. Sets aren't considered\u001b[39;00m\n\u001b[0;32m 1013\u001b[0m \u001b[38;5;66;03m# sequences for nest.flatten, so we put those through as-is.\u001b[39;00m\n\u001b[0;32m 1014\u001b[0m tags \u001b[38;5;241m=\u001b[39m nest\u001b[38;5;241m.\u001b[39mflatten(tags)\n\u001b[0;32m 1015\u001b[0m saved_model_proto, debug_info \u001b[38;5;241m=\u001b[39m (\n\u001b[1;32m-> 1016\u001b[0m \u001b[43mloader_impl\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mparse_saved_model_with_debug_info\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexport_dir\u001b[49m\u001b[43m)\u001b[49m)\n\u001b[0;32m 1018\u001b[0m loader \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 1019\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m (\u001b[38;5;28mlen\u001b[39m(saved_model_proto\u001b[38;5;241m.\u001b[39mmeta_graphs) \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m1\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m\n\u001b[0;32m 1020\u001b[0m saved_model_proto\u001b[38;5;241m.\u001b[39mmeta_graphs[\u001b[38;5;241m0\u001b[39m]\u001b[38;5;241m.\u001b[39mHasField(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mobject_graph_def\u001b[39m\u001b[38;5;124m\"\u001b[39m)):\n", + "File \u001b[1;32md:\\Programming\\Projects\\Mask_detector\\maskVenv\\Lib\\site-packages\\tensorflow\\python\\saved_model\\loader_impl.py:59\u001b[0m, in \u001b[0;36mparse_saved_model_with_debug_info\u001b[1;34m(export_dir)\u001b[0m\n\u001b[0;32m 46\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mparse_saved_model_with_debug_info\u001b[39m(export_dir):\n\u001b[0;32m 47\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Reads the savedmodel as well as the graph debug info.\u001b[39;00m\n\u001b[0;32m 48\u001b[0m \n\u001b[0;32m 49\u001b[0m \u001b[38;5;124;03m Args:\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 57\u001b[0m \u001b[38;5;124;03m parsed. Missing graph debug info file is fine.\u001b[39;00m\n\u001b[0;32m 58\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[1;32m---> 59\u001b[0m saved_model \u001b[38;5;241m=\u001b[39m \u001b[43mparse_saved_model\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexport_dir\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 61\u001b[0m debug_info_path \u001b[38;5;241m=\u001b[39m file_io\u001b[38;5;241m.\u001b[39mjoin(\n\u001b[0;32m 62\u001b[0m path_helpers\u001b[38;5;241m.\u001b[39mget_debug_dir(export_dir),\n\u001b[0;32m 63\u001b[0m constants\u001b[38;5;241m.\u001b[39mDEBUG_INFO_FILENAME_PB)\n\u001b[0;32m 64\u001b[0m debug_info \u001b[38;5;241m=\u001b[39m graph_debug_info_pb2\u001b[38;5;241m.\u001b[39mGraphDebugInfo()\n", + "File \u001b[1;32md:\\Programming\\Projects\\Mask_detector\\maskVenv\\Lib\\site-packages\\tensorflow\\python\\saved_model\\loader_impl.py:119\u001b[0m, in \u001b[0;36mparse_saved_model\u001b[1;34m(export_dir)\u001b[0m\n\u001b[0;32m 117\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mIOError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCannot parse file \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mpath_to_pbtxt\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mstr\u001b[39m(e)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m.\u001b[39m\u001b[38;5;124m\"\u001b[39m) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01me\u001b[39;00m\n\u001b[0;32m 118\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m--> 119\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mIOError\u001b[39;00m(\n\u001b[0;32m 120\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mSavedModel file does not exist at: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mexport_dir\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;132;01m{\u001b[39;00mos\u001b[38;5;241m.\u001b[39mpath\u001b[38;5;241m.\u001b[39msep\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 121\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;130;01m{{\u001b[39;00m\u001b[38;5;132;01m{\u001b[39;00mconstants\u001b[38;5;241m.\u001b[39mSAVED_MODEL_FILENAME_PBTXT\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m|\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 122\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mconstants\u001b[38;5;241m.\u001b[39mSAVED_MODEL_FILENAME_PB\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;130;01m}}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 123\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m saved_model\n", + "\u001b[1;31mOSError\u001b[0m: SavedModel file does not exist at: mask_detector.model\\{saved_model.pbtxt|saved_model.pb}" + ] + } + ], + "source": [ + "model = TFSMLayer(\"mask_detector.model\", call_endpoint='serving_default')" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "c3735b5c", + "metadata": {}, + "outputs": [ + { + "ename": "ValueError", + "evalue": "File format not supported: filepath=mask_detector.model. Keras 3 only supports V3 `.keras` files and legacy H5 format files (`.h5` extension). Note that the legacy SavedModel format is not supported by `load_model()` in Keras 3. In order to reload a TensorFlow SavedModel as an inference-only layer in Keras 3, use `keras.layers.TFSMLayer(mask_detector.model, call_endpoint='serving_default')` (note that your `call_endpoint` might have a different name).", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[3], line 2\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;66;03m# load the face mask detector model from disk\u001b[39;00m\n\u001b[1;32m----> 2\u001b[0m maskNet \u001b[38;5;241m=\u001b[39m \u001b[43mload_model\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mmask_detector.model\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32md:\\Programming\\Projects\\Mask_detector\\maskVenv\\Lib\\site-packages\\keras\\src\\saving\\saving_api.py:193\u001b[0m, in \u001b[0;36mload_model\u001b[1;34m(filepath, custom_objects, compile, safe_mode)\u001b[0m\n\u001b[0;32m 187\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[0;32m 188\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mFile not found: filepath=\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfilepath\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m. \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 189\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mPlease ensure the file is an accessible `.keras` \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 190\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mzip file.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 191\u001b[0m )\n\u001b[0;32m 192\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m--> 193\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[0;32m 194\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mFile format not supported: filepath=\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfilepath\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m. \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 195\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mKeras 3 only supports V3 `.keras` files and \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 196\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mlegacy H5 format files (`.h5` extension). \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 197\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mNote that the legacy SavedModel format is not \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 198\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msupported by `load_model()` in Keras 3. In \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 199\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124morder to reload a TensorFlow SavedModel as an \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 200\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124minference-only layer in Keras 3, use \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 201\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m`keras.layers.TFSMLayer(\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 202\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfilepath\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m, call_endpoint=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mserving_default\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m)` \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 203\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m(note that your `call_endpoint` \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 204\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmight have a different name).\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 205\u001b[0m )\n", + "\u001b[1;31mValueError\u001b[0m: File format not supported: filepath=mask_detector.model. Keras 3 only supports V3 `.keras` files and legacy H5 format files (`.h5` extension). Note that the legacy SavedModel format is not supported by `load_model()` in Keras 3. In order to reload a TensorFlow SavedModel as an inference-only layer in Keras 3, use `keras.layers.TFSMLayer(mask_detector.model, call_endpoint='serving_default')` (note that your `call_endpoint` might have a different name)." + ] + } + ], + "source": [ + "# load the face mask detector model from disk\n", + "maskNet = load_model(\"mask_detector.model\")" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "7a0dea2a", + "metadata": {}, + "outputs": [], + "source": [ + "# import the necessary packages\n", + "from tensorflow.keras.applications.mobilenet_v2 import preprocess_input\n", + "from tensorflow.keras.preprocessing.image import img_to_array\n", + "from tensorflow.keras.models import load_model\n", + "from imutils.video import VideoStream\n", + "import numpy as np\n", + "import imutils\n", + "import time\n", + "import cv2\n", + "import os" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "3ea65ae1", + "metadata": {}, + "outputs": [], + "source": [ + "import gradio as gr" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "id": "616836d6", + "metadata": {}, + "outputs": [], + "source": [ + "def detect_and_predict_mask(frame, faceNet, maskNet):\n", + " try:\n", + " # grab the dimensions of the frame and then construct a blob from it\n", + " (h, w) = frame.shape[:2]\n", + " blob = cv2.dnn.blobFromImage(frame, 1.0, (224,224),(104.0,177.0,123.0) )\n", + "\n", + " # pass the blob through the network and obtain the face detections\n", + " faceNet.setInput(blob)\n", + " detections = faceNet.forward()\n", + " print(detections.shape)\n", + "\n", + " # initialize our list of faces, their corresponding locations, and the list of predictions from our face mask network\n", + " faces = []\n", + " locs = []\n", + " preds = []\n", + " # loop over the detections\n", + " for i in range(0,detections.shape[2]):\n", + " # extract the confidence (i.e., probability) associated with the detection\n", + " confidence = detections[0,0,i,2]\n", + "\n", + " # filter out weak detections by ensuring the confidence is greater than minimum confidence\n", + " if confidence > 0.5:\n", + " # compute the (x, y)-cordinates of the bounding box for the object\n", + " box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])\n", + " (startX, startY, endX, endY) = box.astype(\"int\")\n", + "\n", + " # ensure the bounding boxes fall within the dimensions of the frame\n", + " (startX , startY) = (max(0,startX) , max(0,startY))\n", + " (endX, endY) = (min(w-1,endX) , min(h-1,endY))\n", + "\n", + " # extract the face ROI, convert it from BGR to RGB channel ordering, resize it to 224x224, and preprocess it face=frame[startY:endY, startX:endX]\n", + " # bounding mask only for face detected\n", + " face = frame[startY:endY , startX:endX]\n", + " face = cv2.cvtColor(face, cv2.COLOR_BGR2RGB)\n", + " face = cv2.resize(face, (224,224))\n", + " face = img_to_array(face)\n", + " face = preprocess_input(face)\n", + "\n", + " # add the face and bounding boxes to their respective lists\n", + " faces.append(face)\n", + " locs.append((startX, startY, endX, endY))\n", + "\n", + " # only make a predictions if at least one face was detected\n", + " if len(faces) > 0:\n", + " # far faster inference we'll make batch predictions on *all* faces at the same time rather than one-by-one predictions in the above 'for' loop\n", + " faces = np.array(faces,dtype=\"float32\")\n", + " preds = maskNet.predict(faces, batch_size=32)\n", + "\n", + " # return a 2-tuple of the face locations and their corresponding locations\n", + " return (locs, preds)\n", + " except Exception as e:\n", + " print(e)" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "da40c96f", + "metadata": {}, + "outputs": [], + "source": [ + "# load our serialized face detector model from disk\n", + "prototxtPath = r\"deploy.prototxt.txt\"\n", + "weightsPath = r\"res10_300x300_ssd_iter_140000.caffemodel\"\n", + "faceNet = cv2.dnn.readNet(prototxtPath,weightsPath)\n", + "\n", + "# load the face mask detector model from disk\n", + "maskNet = load_model(\"mask_detector.model\")" + ] + }, + { + "cell_type": "code", + "execution_count": 106, + "id": "b5751c2c", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy" + ] + }, + { + "cell_type": "code", + "execution_count": 134, + "id": "04f7d873", + "metadata": {}, + "outputs": [], + "source": [ + "def webcam_stream(frame):\n", + " if type(frame)==type(None):\n", + " return\n", + " while True:\n", + " try:\n", + " # grab the frame from the threaded video stream and resize it to have a max width of 400 pixels\n", + " frame = imutils.resize(frame,width=400)\n", + "\n", + " # detect faces in the frame and determine if they are wearing a face mask or not\n", + " (locs, preds) = detect_and_predict_mask(frame, faceNet, maskNet)\n", + "\n", + " # loop over the detected face locations and their correspondings locations\n", + " for (box, pred) in zip(locs, preds):\n", + " # unpack the bounding box and predictions\n", + " (startX, startY, endX, endY) = box\n", + " (mask, withoutMask) = pred\n", + "\n", + " # determine the class label and color we'll use to draw the bounding box and text\n", + " label = \"Mask\" if mask> withoutMask else \"No Mask\"\n", + " color = (0,255,0) if label==\"Mask\" else (0,0,255)\n", + "\n", + " # include the probability in the label\n", + " label = \"{}: {:.2f}%\".format(label,max(mask, withoutMask) *100)\n", + "\n", + " # display the label and bounding box rectangle on the output frame\n", + " cv2.putText(frame,label,(startX,startY-10), cv2.FONT_HERSHEY_SIMPLEX, 0.45, color, 2)\n", + " cv2.rectangle(frame, (startX,startY), (endX,endY),color,2)\n", + " \n", + "\n", + " # show the output frame\n", + " cv2.imshow(\"Frame\",frame)\n", + " key = cv2.waitKey(1) & 0xFF\n", + "\n", + " # if the 'q' key was pressed, break from the loop\n", + " if key == ord(\"q\"):\n", + " break\n", + " except Exception as e:\n", + " print(e)\n", + " \n", + " return frame\n", + "# do a bit of cleanup\n", + "# cv2.destroyAllWindows()" + ] + }, + { + "cell_type": "code", + "execution_count": 132, + "id": "5c845891", + "metadata": {}, + "outputs": [], + "source": [ + "# def webcam_stream(vid):\n", + "# return vid" + ] + }, + { + "cell_type": "code", + "execution_count": 133, + "id": "b30a1bf8", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running on local URL: http://127.0.0.1:7892\n", + "\n", + "To create a public link, set `share=True` in `launch()`.\n" + ] + }, + { + "data": { + "text/html": [ + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [] + }, + "execution_count": 133, + "metadata": {}, + "output_type": "execute_result" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 64ms/step\n", + "\n", + "\n", + "(1, 1, 200, 7)\n", + "1/1 [==============================] - 0s 67ms/step\n", + "\n" + ] + } + ], + "source": [ + "webcam = gr.Image(source=\"webcam\",every=\"float\",mirror_webcam=True)\n", + "output = gr.Image(source=\"webcam\")\n", + "# Create a Gradio interface with the webcam_stream function\n", + "app = gr.Interface(webcam_stream,inputs=webcam,outputs=output,live=True)\n", + "\n", + "# Start the app\n", + "app.launch() " + ] + }, + { + "cell_type": "code", + "execution_count": 139, + "id": "d6124d93", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Closing server running on port: 7871\n", + "Closing server running on port: 7882\n", + "Closing server running on port: 7887\n", + "Closing server running on port: 7867\n", + "Closing server running on port: 7868\n", + "Closing server running on port: 7866\n", + "Closing server running on port: 7879\n", + "Closing server running on port: 7865\n", + "Closing server running on port: 7860\n", + "Closing server running on port: 7876\n", + "Closing server running on port: 7868\n", + "Closing server running on port: 7863\n", + "Closing server running on port: 7867\n", + "Closing server running on port: 7860\n", + "Closing server running on port: 7873\n", + "Closing server running on port: 7886\n", + "Closing server running on port: 7888\n", + "Closing server running on port: 7872\n", + "Closing server running on port: 7870\n", + "Closing server running on port: 7870\n", + "Closing server running on port: 7869\n", + "Closing server running on port: 7882\n", + "Closing server running on port: 7863\n", + "Closing server running on port: 7892\n", + "Closing server running on port: 7890\n", + "Closing server running on port: 7875\n", + "Closing server running on port: 7889\n", + "Closing server running on port: 7869\n", + "Closing server running on port: 7878\n", + "Closing server running on port: 7885\n", + "Closing server running on port: 7877\n", + "Closing server running on port: 7884\n", + "Closing server running on port: 7891\n", + "Closing server running on port: 7880\n", + "Closing server running on port: 7881\n", + "Closing server running on port: 7871\n", + "Closing server running on port: 7881\n", + "Closing server running on port: 7861\n", + "Closing server running on port: 7876\n", + "Closing server running on port: 7878\n", + "Closing server running on port: 7883\n", + "Closing server running on port: 7874\n", + "Closing server running on port: 7864\n", + "Closing server running on port: 7862\n", + "Closing server running on port: 7877\n", + "Closing server running on port: 7873\n", + "Closing server running on port: 7879\n", + "Closing server running on port: 7866\n", + "Closing server running on port: 7875\n", + "Closing server running on port: 7874\n", + "Closing server running on port: 7865\n", + "Closing server running on port: 7872\n", + "Closing server running on port: 7861\n", + "Closing server running on port: 7862\n", + "Closing server running on port: 7864\n", + "Closing server running on port: 7880\n" + ] + } + ], + "source": [ + "gr.close_all()" + ] + }, + { + "cell_type": "code", + "execution_count": 138, + "id": "efd8e5b3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Closing server running on port: 7892\n" + ] + } + ], + "source": [ + "app.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "29d9ea46", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/plot.png b/notebooks/plot.png new file mode 100644 index 0000000000000000000000000000000000000000..580c81e10684ee5f9629c19f069a4f8af0f72689 Binary files /dev/null and b/notebooks/plot.png differ diff --git a/packages.txt b/packages.txt new file mode 100644 index 0000000000000000000000000000000000000000..d4458ef18f1d7c83facf3d8f9653b23a58947437 --- /dev/null +++ b/packages.txt @@ -0,0 +1 @@ +python3-opencv \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..b2ad2228bdf54050e840815be826fcf4c844b939 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,125 @@ +absl-py==2.1.0 +aiofiles==23.2.1 +altair==5.3.0 +annotated-types==0.7.0 +anyio==4.4.0 +asttokens==2.4.1 +astunparse==1.6.3 +attrs==23.2.0 +certifi==2024.6.2 +charset-normalizer==3.3.2 +click==8.1.7 +colorama==0.4.6 +comm==0.2.2 +contourpy==1.2.1 +cycler==0.12.1 +debugpy==1.8.1 +decorator==5.1.1 +dnspython==2.6.1 +email_validator==2.1.2 +executing==2.0.1 +fastapi==0.111.0 +fastapi-cli==0.0.4 +ffmpy==0.3.2 +filelock==3.15.1 +flatbuffers==24.3.25 +fonttools==4.53.0 +fsspec==2024.6.0 +gast==0.5.4 +google-pasta==0.2.0 +gradio==4.36.1 +gradio_client==1.0.1 +grpcio==1.64.1 +h11==0.14.0 +h5py==3.11.0 +httpcore==1.0.5 +httptools==0.6.1 +httpx==0.27.0 +huggingface-hub==0.23.4 +idna==3.7 +importlib_resources==6.4.0 +imutils==0.5.4 +ipykernel==6.29.4 +ipython==8.25.0 +jedi==0.19.1 +Jinja2==3.1.4 +joblib==1.4.2 +jsonschema==4.22.0 +jsonschema-specifications==2023.12.1 +jupyter_client==8.6.2 +jupyter_core==5.7.2 +keras==3.3.3 +kiwisolver==1.4.5 +libclang==18.1.1 +Markdown==3.6 +markdown-it-py==3.0.0 +MarkupSafe==2.1.5 +matplotlib==3.9.0 +matplotlib-inline==0.1.7 +mdurl==0.1.2 +ml-dtypes==0.3.2 +namex==0.0.8 +nest-asyncio==1.6.0 +numpy==1.26.4 +opencv-python==4.10.0.82 +opt-einsum==3.3.0 +optree==0.11.0 +orjson==3.10.5 +packaging==24.1 +pandas==2.2.2 +parso==0.8.4 +pillow==10.3.0 +platformdirs==4.2.2 +prompt_toolkit==3.0.47 +protobuf==4.25.3 +psutil==5.9.8 +pure-eval==0.2.2 +pydantic==2.7.4 +pydantic_core==2.18.4 +pydub==0.25.1 +Pygments==2.18.0 +pyparsing==3.1.2 +python-dateutil==2.9.0.post0 +python-dotenv==1.0.1 +python-multipart==0.0.9 +pytz==2024.1 +pywin32==306 +PyYAML==6.0.1 +pyzmq==26.0.3 +referencing==0.35.1 +requests==2.32.3 +rich==13.7.1 +rpds-py==0.18.1 +ruff==0.4.9 +scikit-learn==1.5.0 +scipy==1.13.1 +semantic-version==2.10.0 +shellingham==1.5.4 +six==1.16.0 +sniffio==1.3.1 +stack-data==0.6.3 +starlette==0.37.2 +tensorboard==2.16.2 +tensorboard-data-server==0.7.2 +tensorflow==2.16.1 +tensorflow-intel==2.16.1 +tensorflow-io-gcs-filesystem==0.31.0 +termcolor==2.4.0 +tf_keras==2.16.0 +threadpoolctl==3.5.0 +tomlkit==0.12.0 +toolz==0.12.1 +tornado==6.4.1 +tqdm==4.66.4 +traitlets==5.14.3 +typer==0.12.3 +typing_extensions==4.12.2 +tzdata==2024.1 +ujson==5.10.0 +urllib3==2.2.2 +uvicorn==0.30.1 +watchfiles==0.22.0 +wcwidth==0.2.13 +websockets==11.0.3 +Werkzeug==3.0.3 +wrapt==1.16.0