├── thumbnail.png ├── README.md └── Covid_19_Face_Mask_Detection.ipynb /thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kvnptl/Face-Mask-Detection-Using-Google-Colab/HEAD/thumbnail.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Face-Mask-Detection 2 | 3 | ## Youtube Video: 4 | [![Face Mask Detection](https://img.youtube.com/vi/ihzur7gKpbE/0.jpg)](https://youtu.be/ihzur7gKpbE) 5 | -------------------------------------------------------------------------------- /Covid_19_Face_Mask_Detection.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "Covid-19 Face Mask Detection.ipynb", 7 | "provenance": [], 8 | "collapsed_sections": [ 9 | "eTxOhS8brv3q", 10 | "ECQdqCO-Ytx8", 11 | "m8YtQCtQyrxq", 12 | "d0410JRuhB6U", 13 | "EZwHKA9Gy1Fw", 14 | "cgbFKjPNM2UF", 15 | "_s8RnmP0bN-L" 16 | ], 17 | "toc_visible": true, 18 | "mount_file_id": "1itbEWIELNYO6QW5iIRlGDYr7ULeAPJ3w", 19 | "authorship_tag": "ABX9TyN77q4PmANjqqEYwuk8knz0", 20 | "include_colab_link": true 21 | }, 22 | "kernelspec": { 23 | "name": "python3", 24 | "display_name": "Python 3" 25 | }, 26 | "accelerator": "GPU" 27 | }, 28 | "cells": [ 29 | { 30 | "cell_type": "markdown", 31 | "metadata": { 32 | "id": "view-in-github", 33 | "colab_type": "text" 34 | }, 35 | "source": [ 36 | "\"Open" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": { 42 | "id": "3HVlhnQxGbNR", 43 | "colab_type": "text" 44 | }, 45 | "source": [ 46 | "#Reference From: [COVID-19: Face Mask Detector](https://www.pyimagesearch.com/2020/05/04/covid-19-face-mask-detector-with-opencv-keras-tensorflow-and-deep-learning/)\n", 47 | "\n", 48 | "#For more such awesome content check out [pyImageSearch](https://www.pyimagesearch.com)" 49 | ] 50 | }, 51 | { 52 | "cell_type": "markdown", 53 | "metadata": { 54 | "id": "deF91mf0YjW3", 55 | "colab_type": "text" 56 | }, 57 | "source": [ 58 | "**Mount Google drive to colab**" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "metadata": { 64 | "id": "nabMFpJCiEVf", 65 | "colab_type": "code", 66 | "colab": {} 67 | }, 68 | "source": [ 69 | "from google.colab import drive\n", 70 | "drive.mount('/content/drive')" 71 | ], 72 | "execution_count": 0, 73 | "outputs": [] 74 | }, 75 | { 76 | "cell_type": "markdown", 77 | "metadata": { 78 | "id": "7QLUBHeZI0jF", 79 | "colab_type": "text" 80 | }, 81 | "source": [ 82 | "#**Step 1: Download face-mask-detector.zip** from [pyImageSearch](https://www.pyimagesearch.com/2020/05/04/covid-19-face-mask-detector-with-opencv-keras-tensorflow-and-deep-learning/)\n", 83 | "\n", 84 | "#**Step 2: Put it in your Google Drive**" 85 | ] 86 | }, 87 | { 88 | "cell_type": "markdown", 89 | "metadata": { 90 | "id": "xeh9fFJNictQ", 91 | "colab_type": "text" 92 | }, 93 | "source": [ 94 | "#**Step 3: UnZip face-mask-detector.zip**" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "metadata": { 100 | "id": "Ij7XsORvibmX", 101 | "colab_type": "code", 102 | "colab": {} 103 | }, 104 | "source": [ 105 | "import zipfile\n", 106 | "with zipfile.ZipFile('/content/drive/My Drive/face-mask-detector.zip', 'r') as zip_ref:\n", 107 | " zip_ref.extractall('/content/drive/My Drive/')" 108 | ], 109 | "execution_count": 0, 110 | "outputs": [] 111 | }, 112 | { 113 | "cell_type": "markdown", 114 | "metadata": { 115 | "id": "eTxOhS8brv3q", 116 | "colab_type": "text" 117 | }, 118 | "source": [ 119 | "#Step 4: Change directory to face-mask-detector" 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "metadata": { 125 | "id": "9fXlb1_Xo46M", 126 | "colab_type": "code", 127 | "outputId": "7271d2db-a6aa-4893-9dd0-5825f2405fe1", 128 | "colab": { 129 | "base_uri": "https://localhost:8080/", 130 | "height": 34 131 | } 132 | }, 133 | "source": [ 134 | "%cd /content/drive/My\\ Drive/face-mask-detector" 135 | ], 136 | "execution_count": 0, 137 | "outputs": [ 138 | { 139 | "output_type": "stream", 140 | "text": [ 141 | "/content/drive/My Drive/face-mask-detector\n" 142 | ], 143 | "name": "stdout" 144 | } 145 | ] 146 | }, 147 | { 148 | "cell_type": "code", 149 | "metadata": { 150 | "id": "aBvwaNKaouFM", 151 | "colab_type": "code", 152 | "outputId": "f770d857-1709-4827-f44d-b69a8d759bbb", 153 | "colab": { 154 | "base_uri": "https://localhost:8080/", 155 | "height": 34 156 | } 157 | }, 158 | "source": [ 159 | "%pwd" 160 | ], 161 | "execution_count": 0, 162 | "outputs": [ 163 | { 164 | "output_type": "execute_result", 165 | "data": { 166 | "text/plain": [ 167 | "'/content/drive/My Drive/face-mask-detector'" 168 | ] 169 | }, 170 | "metadata": { 171 | "tags": [] 172 | }, 173 | "execution_count": 3 174 | } 175 | ] 176 | }, 177 | { 178 | "cell_type": "markdown", 179 | "metadata": { 180 | "id": "ECQdqCO-Ytx8", 181 | "colab_type": "text" 182 | }, 183 | "source": [ 184 | "#**Step 5: Train Model**" 185 | ] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "metadata": { 190 | "id": "b7HzGdw7onVv", 191 | "colab_type": "code", 192 | "colab": {} 193 | }, 194 | "source": [ 195 | "!python train_mask_detector.py --dataset dataset" 196 | ], 197 | "execution_count": 0, 198 | "outputs": [] 199 | }, 200 | { 201 | "cell_type": "markdown", 202 | "metadata": { 203 | "id": "m8YtQCtQyrxq", 204 | "colab_type": "text" 205 | }, 206 | "source": [ 207 | "#**Predict on Single Image**" 208 | ] 209 | }, 210 | { 211 | "cell_type": "code", 212 | "metadata": { 213 | "id": "JemeauwhjdY7", 214 | "colab_type": "code", 215 | "colab": {} 216 | }, 217 | "source": [ 218 | "# USAGE\n", 219 | "# Give input image file path (check other paths also)\n", 220 | "\n", 221 | "# import the necessary packages\n", 222 | "from tensorflow.keras.applications.mobilenet_v2 import preprocess_input\n", 223 | "from tensorflow.keras.preprocessing.image import img_to_array\n", 224 | "from tensorflow.keras.models import load_model\n", 225 | "import numpy as np\n", 226 | "import argparse\n", 227 | "import cv2\n", 228 | "import os\n", 229 | "from google.colab.patches import cv2_imshow\n", 230 | "from natsort import natsorted, ns\n", 231 | "\n", 232 | "input_file_path = \"/content/drive/My Drive/face-mask-detector/examples/example_01.png\"\n", 233 | "\n", 234 | "# load our serialized face detector model from disk\n", 235 | "print(\"[INFO] loading face detector model...\")\n", 236 | "prototxtPath = \"/content/drive/My Drive/face-mask-detector/face_detector/deploy.prototxt\"\n", 237 | "weightsPath = \"/content/drive/My Drive/face-mask-detector/face_detector/res10_300x300_ssd_iter_140000.caffemodel\"\n", 238 | "net = cv2.dnn.readNet(prototxtPath, weightsPath)\n", 239 | "\n", 240 | "# load the face mask detector model from disk\n", 241 | "print(\"[INFO] loading face mask detector model...\")\n", 242 | "model = load_model(\"mask_detector.model\")\n", 243 | "\n", 244 | "def process_images(input_file_path):\n", 245 | "\t# load the input image from disk, clone it, and grab the image spatial\n", 246 | " # dimensions\n", 247 | "\timage = cv2.imread(input_file_path)\n", 248 | "\t# orig = image.copy()\n", 249 | "\t(h, w) = image.shape[:2]\n", 250 | "\n", 251 | "\t# construct a blob from the image\n", 252 | "\tblob = cv2.dnn.blobFromImage(image, 1.0, (300, 300),\n", 253 | "\t\t(104.0, 177.0, 123.0))\n", 254 | "\n", 255 | "\t# pass the blob through the network and obtain the face detections\n", 256 | "\tprint(\"[INFO] computing face detections...\")\n", 257 | "\tnet.setInput(blob)\n", 258 | "\tdetections = net.forward()\n", 259 | "\n", 260 | "\t# loop over the detections\n", 261 | "\tfor i in range(0, detections.shape[2]):\n", 262 | "\t\t# extract the confidence (i.e., probability) associated with\n", 263 | "\t\t# the detection\n", 264 | "\t\tconfidence = detections[0, 0, i, 2]\n", 265 | "\n", 266 | "\t\t# filter out weak detections by ensuring the confidence is\n", 267 | "\t\t# greater than the minimum confidence\n", 268 | "\t\tif confidence > 0.5:\n", 269 | "\t\t\t# compute the (x, y)-coordinates of the bounding box for\n", 270 | "\t\t\t# the object\n", 271 | "\t\t\tbox = detections[0, 0, i, 3:7] * np.array([w, h, w, h])\n", 272 | "\t\t\t(startX, startY, endX, endY) = box.astype(\"int\")\n", 273 | "\n", 274 | "\t\t\t# ensure the bounding boxes fall within the dimensions of\n", 275 | "\t\t\t# the frame\n", 276 | "\t\t\t(startX, startY) = (max(0, startX), max(0, startY))\n", 277 | "\t\t\t(endX, endY) = (min(w - 1, endX), min(h - 1, endY))\n", 278 | "\n", 279 | "\t\t\t# extract the face ROI, convert it from BGR to RGB channel\n", 280 | "\t\t\t# ordering, resize it to 224x224, and preprocess it\n", 281 | "\t\t\tface = image[startY:endY, startX:endX]\n", 282 | "\t\t\tface = cv2.cvtColor(face, cv2.COLOR_BGR2RGB)\n", 283 | "\t\t\tface = cv2.resize(face, (224, 224))\n", 284 | "\t\t\tface = img_to_array(face)\n", 285 | "\t\t\tface = preprocess_input(face)\n", 286 | "\t\t\tface = np.expand_dims(face, axis=0)\n", 287 | "\n", 288 | "\t\t\t# pass the face through the model to determine if the face\n", 289 | "\t\t\t# has a mask or not\n", 290 | "\t\t\t(mask, withoutMask) = model.predict(face)[0]\n", 291 | "\n", 292 | "\t\t\t# determine the class label and color we'll use to draw\n", 293 | "\t\t\t# the bounding box and text\n", 294 | "\t\t\tlabel = \"Mask\" if mask > withoutMask else \"No Mask\"\n", 295 | "\t\t\tcolor = (0, 255, 0) if label == \"Mask\" else (0, 0, 255)\n", 296 | "\n", 297 | "\t\t\t# include the probability in the label\n", 298 | "\t\t\tlabel = \"{}: {:.2f}%\".format(label, max(mask, withoutMask) * 100)\n", 299 | "\n", 300 | "\t\t\t# display the label and bounding box rectangle on the output\n", 301 | "\t\t\t# frame\n", 302 | "\t\t\tcv2.putText(image, label, (startX, startY - 10),\n", 303 | "\t\t\t\tcv2.FONT_HERSHEY_SIMPLEX, 0.45, color, 2)\n", 304 | "\t\t\tcv2.rectangle(image, (startX, startY), (endX, endY), color, 2)\n", 305 | "\n", 306 | "\t# show the output image\n", 307 | "\tsave_path = input_file_path.split(\".\",1)\n", 308 | "\t# print (save_path[0])\n", 309 | "\t# print (save_path[-1])\n", 310 | "\tcv2_imshow(image)\n", 311 | "\t# cv2.imwrite(save_path[0] + \"_pred.\" + save_path[-1],image)\n", 312 | "\n", 313 | "#start the process\n", 314 | "process_images(input_file_path)" 315 | ], 316 | "execution_count": 0, 317 | "outputs": [] 318 | }, 319 | { 320 | "cell_type": "markdown", 321 | "metadata": { 322 | "id": "d0410JRuhB6U", 323 | "colab_type": "text" 324 | }, 325 | "source": [ 326 | "#**Predict on Multiple Images and make a MP4 video**" 327 | ] 328 | }, 329 | { 330 | "cell_type": "code", 331 | "metadata": { 332 | "colab_type": "code", 333 | "id": "poqfh97Sg-pY", 334 | "colab": {} 335 | }, 336 | "source": [ 337 | "# USAGE\n", 338 | "# Give input images directory and output store directory\n", 339 | "\n", 340 | "# import the necessary packages\n", 341 | "from tensorflow.keras.applications.mobilenet_v2 import preprocess_input\n", 342 | "from tensorflow.keras.preprocessing.image import img_to_array\n", 343 | "from tensorflow.keras.models import load_model\n", 344 | "import numpy as np\n", 345 | "import argparse\n", 346 | "import cv2\n", 347 | "import os\n", 348 | "from google.colab.patches import cv2_imshow\n", 349 | "from natsort import natsorted, ns\n", 350 | "\n", 351 | "# input_file_path = \"/content/drive/My Drive/my_projects/face_mask_detector/testSet/pic7.jpg\"\n", 352 | "input_folder_path = \"/content/drive/My Drive/face-mask-detector/examples/\"\n", 353 | "output_folder_path = \"/content/drive/My Drive/face-mask-detector/test_OUTPUT.mp4\"\n", 354 | "\n", 355 | "# load our serialized face detector model from disk\n", 356 | "print(\"[INFO] loading face detector model...\")\n", 357 | "prototxtPath = \"/content/drive/My Drive/face-mask-detector/face_detector/deploy.prototxt\"\n", 358 | "weightsPath = \"/content/drive/My Drive/face-mask-detector/face_detector/res10_300x300_ssd_iter_140000.caffemodel\"\n", 359 | "net = cv2.dnn.readNet(prototxtPath, weightsPath)\n", 360 | "\n", 361 | "# load the face mask detector model from disk\n", 362 | "print(\"[INFO] loading face mask detector model...\")\n", 363 | "model = load_model(\"mask_detector.model\")\n", 364 | "\n", 365 | "img_array = []\n", 366 | "\n", 367 | "def process_images(input_file_path,count):\n", 368 | "\t# load the input image from disk, clone it, and grab the image spatial\n", 369 | " # dimensions\n", 370 | "\timage = cv2.imread(input_file_path)\n", 371 | "\torig = image.copy()\n", 372 | "\t(h, w) = image.shape[:2]\n", 373 | "\n", 374 | "\t# construct a blob from the image\n", 375 | "\tblob = cv2.dnn.blobFromImage(image, 1.0, (300, 300),\n", 376 | "\t\t(104.0, 177.0, 123.0))\n", 377 | "\n", 378 | "\t# pass the blob through the network and obtain the face detections\n", 379 | "\t# print(\"[INFO] computing face detections...\")\n", 380 | "\tnet.setInput(blob)\n", 381 | "\tdetections = net.forward()\n", 382 | "\t\n", 383 | "\n", 384 | "\t# loop over the detections\n", 385 | "\tfor i in range(0, detections.shape[2]):\n", 386 | "\t\t# extract the confidence (i.e., probability) associated with\n", 387 | "\t\t# the detection\n", 388 | "\t\tconfidence = detections[0, 0, i, 2]\n", 389 | "\n", 390 | "\t\t# filter out weak detections by ensuring the confidence is\n", 391 | "\t\t# greater than the minimum confidence\n", 392 | "\t\tif confidence > 0.5:\n", 393 | "\t\t\t# compute the (x, y)-coordinates of the bounding box for\n", 394 | "\t\t\t# the object\n", 395 | "\t\t\tbox = detections[0, 0, i, 3:7] * np.array([w, h, w, h])\n", 396 | "\t\t\t(startX, startY, endX, endY) = box.astype(\"int\")\n", 397 | "\n", 398 | "\t\t\t# ensure the bounding boxes fall within the dimensions of\n", 399 | "\t\t\t# the frame\n", 400 | "\t\t\t(startX, startY) = (max(0, startX), max(0, startY))\n", 401 | "\t\t\t(endX, endY) = (min(w - 1, endX), min(h - 1, endY))\n", 402 | "\n", 403 | "\t\t\t# extract the face ROI, convert it from BGR to RGB channel\n", 404 | "\t\t\t# ordering, resize it to 224x224, and preprocess it\n", 405 | "\t\t\tface = image[startY:endY, startX:endX]\n", 406 | "\t\t\tface = cv2.cvtColor(face, cv2.COLOR_BGR2RGB)\n", 407 | "\t\t\tface = cv2.resize(face, (224, 224))\n", 408 | "\t\t\tface = img_to_array(face)\n", 409 | "\t\t\tface = preprocess_input(face)\n", 410 | "\t\t\tface = np.expand_dims(face, axis=0)\n", 411 | "\n", 412 | "\t\t\t# pass the face through the model to determine if the face\n", 413 | "\t\t\t# has a mask or not\n", 414 | "\t\t\t(mask, withoutMask) = model.predict(face)[0]\n", 415 | "\n", 416 | "\t\t\t# determine the class label and color we'll use to draw\n", 417 | "\t\t\t# the bounding box and text\n", 418 | "\t\t\tlabel = \"Mask\" if mask > withoutMask else \"No Mask\"\n", 419 | "\t\t\tcolor = (0, 255, 0) if label == \"Mask\" else (0, 0, 255)\n", 420 | "\n", 421 | "\t\t\t# include the probability in the label\n", 422 | "\t\t\tlabel = \"{}: {:.2f}%\".format(label, max(mask, withoutMask) * 100)\n", 423 | "\n", 424 | "\t\t\t# display the label and bounding box rectangle on the output\n", 425 | "\t\t\t# frame\n", 426 | "\t\t\tcv2.putText(image, label, (startX, startY - 10),\n", 427 | "\t\t\t\tcv2.FONT_HERSHEY_SIMPLEX, 1, color, 2)\n", 428 | "\t\t\tcv2.rectangle(image, (startX, startY), (endX, endY), color, 5)\n", 429 | "\n", 430 | "\t# show the output image\n", 431 | "\t\n", 432 | "\t# cv2_imshow(image)\n", 433 | "\theight, width, layers = image.shape\n", 434 | "\tsize = (width,height)\n", 435 | "\timg_array.append(image)\n", 436 | "\t# resized_frame = cv2.resize(image, (400, 225))\n", 437 | "\tcount+=1\n", 438 | "\t# video.write(resized_frame)\n", 439 | "\tprint (\"\\r[INFO] Count: {}\".format(count),end='')\n", 440 | "\treturn size, count\n", 441 | "\t# cv2.imwrite(save_path,image)\n", 442 | "\n", 443 | "#start the process\n", 444 | "x = os.listdir(input_folder_path)\n", 445 | "sorted_path = natsorted(x, key=lambda y: y.lower())\n", 446 | "count = 0\n", 447 | "print (\"[INFO] Total files: {}\".format(len(x)))\n", 448 | "for k in sorted_path: \n", 449 | " file_path = input_folder_path + k\n", 450 | " print (\"\\r[INFO] File name: {}\".format(file_path))\n", 451 | " size, count = process_images(file_path,count)\n", 452 | "\n", 453 | "print (\"\\n[INFO] Total count/frames: {}\".format(count))\n", 454 | "\n", 455 | "#Saving all output frames as MP4 video\n", 456 | "print (\"[INFO] Saving video\")\n", 457 | "video = cv2.VideoWriter(output_folder_path, cv2.VideoWriter_fourcc(*'DIVX'), 1, size)\n", 458 | " \n", 459 | "for i in range(len(img_array)):\n", 460 | " video.write(img_array[i])\n", 461 | "video.release()\n", 462 | "print (\"[INFO] process complete.\")\n" 463 | ], 464 | "execution_count": 0, 465 | "outputs": [] 466 | }, 467 | { 468 | "cell_type": "markdown", 469 | "metadata": { 470 | "id": "EZwHKA9Gy1Fw", 471 | "colab_type": "text" 472 | }, 473 | "source": [ 474 | "#**Predict Using Video frames**" 475 | ] 476 | }, 477 | { 478 | "cell_type": "code", 479 | "metadata": { 480 | "id": "yDZgSIxAncAs", 481 | "colab_type": "code", 482 | "outputId": "1198ce8e-f4fd-45ce-ef32-cf97761ec314", 483 | "colab": { 484 | "base_uri": "https://localhost:8080/", 485 | "height": 139 486 | } 487 | }, 488 | "source": [ 489 | "# USAGE\n", 490 | "# python detect_mask_video.py\n", 491 | "\n", 492 | "# import the necessary packages\n", 493 | "from tensorflow.keras.applications.mobilenet_v2 import preprocess_input\n", 494 | "from tensorflow.keras.preprocessing.image import img_to_array\n", 495 | "from tensorflow.keras.models import load_model\n", 496 | "from imutils.video import VideoStream\n", 497 | "import numpy as np\n", 498 | "import argparse\n", 499 | "import imutils\n", 500 | "import time\n", 501 | "import cv2\n", 502 | "import os\n", 503 | "from imutils.video import FPS\n", 504 | "\n", 505 | "from google.colab.patches import cv2_imshow\n", 506 | "import pdb\n", 507 | "\n", 508 | "#Input video file path\n", 509 | "input_video_path = \"/content/drive/My Drive/test_vid.mp4\"\n", 510 | "\n", 511 | "def detect_and_predict_mask(frame, faceNet, maskNet):\n", 512 | "\t# grab the dimensions of the frame and then construct a blob\n", 513 | "\t# from it\n", 514 | "\t(h, w) = frame.shape[:2]\n", 515 | "\tblob = cv2.dnn.blobFromImage(frame, 1.0, (300, 300),\n", 516 | "\t\t(104.0, 177.0, 123.0))\n", 517 | "\n", 518 | "\t# pass the blob through the network and obtain the face detections\n", 519 | "\tfaceNet.setInput(blob)\n", 520 | "\tdetections = faceNet.forward()\n", 521 | "\n", 522 | "\t# initialize our list of faces, their corresponding locations,\n", 523 | "\t# and the list of predictions from our face mask network\n", 524 | "\tfaces = []\n", 525 | "\tlocs = []\n", 526 | "\tpreds = []\n", 527 | "\n", 528 | "\t# loop over the detections\n", 529 | "\tfor i in range(0, detections.shape[2]):\n", 530 | "\t\t# extract the confidence (i.e., probability) associated with\n", 531 | "\t\t# the detection\n", 532 | "\t\tconfidence = detections[0, 0, i, 2]\n", 533 | "\n", 534 | "\t\t# filter out weak detections by ensuring the confidence is\n", 535 | "\t\t# greater than the minimum confidence\n", 536 | "\t\tif confidence > 0.5:\n", 537 | "\t\t\t# compute the (x, y)-coordinates of the bounding box for\n", 538 | "\t\t\t# the object\n", 539 | "\t\t\tbox = detections[0, 0, i, 3:7] * np.array([w, h, w, h])\n", 540 | "\t\t\t(startX, startY, endX, endY) = box.astype(\"int\")\n", 541 | "\n", 542 | "\t\t\t# ensure the bounding boxes fall within the dimensions of\n", 543 | "\t\t\t# the frame\n", 544 | "\t\t\t(startX, startY) = (max(0, startX), max(0, startY))\n", 545 | "\t\t\t(endX, endY) = (min(w - 1, endX), min(h - 1, endY))\n", 546 | "\n", 547 | "\t\t\t# extract the face ROI, convert it from BGR to RGB channel\n", 548 | "\t\t\t# ordering, resize it to 224x224, and preprocess it\n", 549 | "\t\t\tface = frame[startY:endY, startX:endX]\n", 550 | "\t\t\tface = cv2.cvtColor(face, cv2.COLOR_BGR2RGB)\n", 551 | "\t\t\tface = cv2.resize(face, (224, 224))\n", 552 | "\t\t\tface = img_to_array(face)\n", 553 | "\t\t\tface = preprocess_input(face)\n", 554 | "\t\t\tface = np.expand_dims(face, axis=0)\n", 555 | "\n", 556 | "\t\t\t# add the face and bounding boxes to their respective\n", 557 | "\t\t\t# lists\n", 558 | "\t\t\tfaces.append(face)\n", 559 | "\t\t\tlocs.append((startX, startY, endX, endY))\n", 560 | "\n", 561 | "\t# only make a predictions if at least one face was detected\n", 562 | "\tif len(faces) > 0:\n", 563 | "\t\t# for faster inference we'll make batch predictions on *all*\n", 564 | "\t\t# faces at the same time rather than one-by-one predictions\n", 565 | "\t\t# in the above `for` loop\n", 566 | "\t\tpreds = maskNet.predict(faces)\n", 567 | "\n", 568 | "\t# return a 2-tuple of the face locations and their corresponding\n", 569 | "\t# locations\n", 570 | "\treturn (locs, preds)\n", 571 | "\n", 572 | "# load our serialized face detector model from disk\n", 573 | "print(\"[INFO] loading face detector model...\")\n", 574 | "prototxtPath = \"/content/drive/My Drive/face-mask-detector/face_detector/deploy.prototxt\"\n", 575 | "weightsPath = \"/content/drive/My Drive/face-mask-detector/face_detector/res10_300x300_ssd_iter_140000.caffemodel\"\n", 576 | "faceNet = cv2.dnn.readNet(prototxtPath, weightsPath)\n", 577 | "\n", 578 | "# load the face mask detector model from disk\n", 579 | "print(\"[INFO] loading face mask detector model...\")\n", 580 | "maskNet = load_model(\"mask_detector.model\")\n", 581 | "\n", 582 | "# initialize the video stream and allow the camera sensor to warm up\n", 583 | "print(\"[INFO] starting video stream...\")\n", 584 | "file_path = input_video_path.split(\".\",1)\n", 585 | "vs = cv2.VideoCapture(input_video_path)\n", 586 | "length = int(vs.get(cv2.CAP_PROP_FRAME_COUNT))\n", 587 | "time.sleep(2.0)\n", 588 | "\n", 589 | "#checking video available or not\n", 590 | "grabbed, frame_flip = vs.read()\n", 591 | "if not(grabbed): print (\"INPUT VIDEO NOT FOUND!\")\n", 592 | "\n", 593 | "# loop over the frames from the video stream\n", 594 | "count = 0\n", 595 | "img_array = []\n", 596 | "while grabbed:\n", 597 | "\t(grabbed, frame) = vs.read()\n", 598 | "\tif not(grabbed): break\n", 599 | "\tif (count==0): print (\"[INFO] processing started...\")\n", 600 | "\tframe = imutils.resize(frame, width=400)\n", 601 | " \n", 602 | "\t#Optional step (comment if not needed)\n", 603 | "\tframe = cv2.rotate(frame, cv2.ROTATE_180)\n", 604 | "\t\n", 605 | "\t(locs, preds) = detect_and_predict_mask(frame, faceNet, maskNet)\n", 606 | "\n", 607 | "\t# loop over the detected face locations and their corresponding\n", 608 | "\t# locations\n", 609 | "\tfor (box, pred) in zip(locs, preds):\n", 610 | "\t\t# unpack the bounding box and predictions\n", 611 | "\t\t(startX, startY, endX, endY) = box\n", 612 | "\t\t(mask, withoutMask) = pred\n", 613 | "\n", 614 | "\t\t# determine the class label and color we'll use to draw\n", 615 | "\t\t# the bounding box and text\n", 616 | "\t\tlabel = \"Mask\" if mask > withoutMask else \"No Mask\"\n", 617 | "\t\tcolor = (0, 255, 0) if label == \"Mask\" else (0, 0, 255)\n", 618 | "\n", 619 | "\t\t# include the probability in the label\n", 620 | "\t\tlabel = \"{}: {:.2f}%\".format(label, max(mask, withoutMask) * 100)\n", 621 | "\n", 622 | "\t\t# display the label and bounding box rectangle on the output\n", 623 | "\t\t# frame\n", 624 | "\t\tcv2.putText(frame, label, (startX, startY - 10),\n", 625 | "\t\t\tcv2.FONT_HERSHEY_SIMPLEX, 0.45, color, 2)\n", 626 | "\t\tcv2.rectangle(frame, (startX, startY), (endX, endY), color, 2)\n", 627 | "\t\n", 628 | "\t# cv2_imshow(frame)\n", 629 | "\theight, width, layers = frame.shape\n", 630 | "\tsize = (width,height)\n", 631 | "\timg_array.append(frame)\n", 632 | "\tprint (\"\\r[INFO] Count: {}/{}\".format(count, length),end='')\n", 633 | "\tcount+=1\n", 634 | "\n", 635 | "#Saving all output frames as MP4 video\n", 636 | "print (\"\\n[INFO] Saving video\")\n", 637 | "video = cv2.VideoWriter(file_path[0] + \"_OUTPUT.\" + file_path[-1], cv2.VideoWriter_fourcc(*'DIVX'), 30, size)\n", 638 | " \n", 639 | "for i in range(len(img_array)):\n", 640 | " video.write(img_array[i])\n", 641 | "video.release()\n", 642 | "print (\"[INFO] process complete.\")\n", 643 | "\n", 644 | "# vs.stop()" 645 | ], 646 | "execution_count": 0, 647 | "outputs": [ 648 | { 649 | "output_type": "stream", 650 | "text": [ 651 | "[INFO] loading face detector model...\n", 652 | "[INFO] loading face mask detector model...\n", 653 | "[INFO] starting video stream...\n", 654 | "[INFO] processing started...\n", 655 | "[INFO] Count: 289/291\n", 656 | "[INFO] Saving video\n", 657 | "[INFO] process complete.\n" 658 | ], 659 | "name": "stdout" 660 | } 661 | ] 662 | }, 663 | { 664 | "cell_type": "markdown", 665 | "metadata": { 666 | "id": "cgbFKjPNM2UF", 667 | "colab_type": "text" 668 | }, 669 | "source": [ 670 | "#**Extract images from video (VIDEO -> IMAGES)**" 671 | ] 672 | }, 673 | { 674 | "cell_type": "code", 675 | "metadata": { 676 | "id": "uijKwcJiLomI", 677 | "colab_type": "code", 678 | "colab": {} 679 | }, 680 | "source": [ 681 | "import cv2\n", 682 | "\n", 683 | "# Opens the Video file\n", 684 | "cap= cv2.VideoCapture('/content/drive/My Drive/test_vid.mp4')\n", 685 | "i = 0\n", 686 | "j = 0\n", 687 | "while(cap.isOpened()):\n", 688 | " ret, frame = cap.read()\n", 689 | " # frame = cv2.rotate(frame, cv2.ROTATE_180)\n", 690 | " if ret == False:\n", 691 | " break\n", 692 | " cv2.imwrite('/content/drive/My Drive/face-mask-detector/examples/testImg/test_image_'+str(i)+'.jpg',frame)\n", 693 | " print (\"\\rCount: {}\".format(i),end='')\n", 694 | " j+=1\n", 695 | " i+=1\n", 696 | "\n", 697 | "# print (\"\\n[INFO] Next frame start with: {}\".format(i))\n", 698 | "print (\"\\n[INFO] Total frames: {}\".format(j))\n", 699 | "cap.release()\n", 700 | "cv2.destroyAllWindows()" 701 | ], 702 | "execution_count": 0, 703 | "outputs": [] 704 | }, 705 | { 706 | "cell_type": "markdown", 707 | "metadata": { 708 | "id": "_s8RnmP0bN-L", 709 | "colab_type": "text" 710 | }, 711 | "source": [ 712 | "#**Make a movie from images (IMAGES -> VIDEO)**" 713 | ] 714 | }, 715 | { 716 | "cell_type": "code", 717 | "metadata": { 718 | "id": "fZ0RYaZ0PEig", 719 | "colab_type": "code", 720 | "outputId": "ad099be8-9d6f-4b05-9588-8dedce12771e", 721 | "colab": { 722 | "base_uri": "https://localhost:8080/", 723 | "height": 69 724 | } 725 | }, 726 | "source": [ 727 | "import cv2\n", 728 | "import numpy as np\n", 729 | "import glob\n", 730 | "import pdb\n", 731 | "\n", 732 | "input_folder_path = '/content/drive/My Drive/face-mask-detector/examples/testImg/'\n", 733 | "\n", 734 | "#natural sorting\n", 735 | "x = os.listdir(input_folder_path)\n", 736 | "sorted_path = natsorted(x, key=lambda y: y.lower())\n", 737 | "length = len(sorted_path)\n", 738 | "count = 0\n", 739 | "img_array = []\n", 740 | "# for filename in glob.glob():\n", 741 | "for filename in sorted_path:\n", 742 | " file_path = input_folder_path + filename\n", 743 | " img = cv2.imread(file_path)\n", 744 | " img = cv2.rotate(img, cv2.ROTATE_180)\n", 745 | " height, width, layers = img.shape\n", 746 | " size = (width,height)\n", 747 | " img_array.append(img)\n", 748 | " print (\"\\r[INFO] Count: {}/{}\".format(count, length),end='')\n", 749 | " count+=1\n", 750 | "\n", 751 | "#Saving all output frames as MP4 video\n", 752 | "print (\"\\n[INFO] Saving video\")\n", 753 | "out = cv2.VideoWriter('/content/drive/My Drive/face-mask-detector/examples/testImg_OUTPUT.mp4',cv2.VideoWriter_fourcc(*'DIVX'), 30, size)\n", 754 | " \n", 755 | "for i in range(len(img_array)):\n", 756 | " out.write(img_array[i])\n", 757 | "out.release()\n", 758 | "print (\"[INFO] process complete.\")" 759 | ], 760 | "execution_count": 0, 761 | "outputs": [ 762 | { 763 | "output_type": "stream", 764 | "text": [ 765 | "[INFO] Count: 290/291\n", 766 | "[INFO] Saving video\n", 767 | "[INFO] process complete.\n" 768 | ], 769 | "name": "stdout" 770 | } 771 | ] 772 | } 773 | ] 774 | } --------------------------------------------------------------------------------