{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "designing-serve",
   "metadata": {},
   "outputs": [],
   "source": [
    "# USAGE\n",
    "# python recognize.py --detector face_detection_model \\\n",
    "#\t--embedding-model openface_nn4.small2.v1.t7 \\\n",
    "#\t--recognizer output/recognizer.pickle \\\n",
    "#\t--le output/le.pickle --image images/adrian.jpg\n",
    "\n",
    "# import the necessary packages\n",
    "import numpy as np\n",
    "import argparse\n",
    "import imutils\n",
    "import pickle\n",
    "import cv2\n",
    "import os\n",
    "\n",
    "# construct the argument parser and parse the arguments\n",
    "ap = argparse.ArgumentParser()\n",
    "ap.add_argument(\"-i\", \"--image\", required=True,\n",
    "\thelp=\"path to input image\")\n",
    "ap.add_argument(\"-d\", \"--detector\", required=True,\n",
    "\thelp=\"path to OpenCV's deep learning face detector\")\n",
    "ap.add_argument(\"-m\", \"--embedding-model\", required=True,\n",
    "\thelp=\"path to OpenCV's deep learning face embedding model\")\n",
    "ap.add_argument(\"-r\", \"--recognizer\", required=True,\n",
    "\thelp=\"path to model trained to recognize faces\")\n",
    "ap.add_argument(\"-l\", \"--le\", required=True,\n",
    "\thelp=\"path to label encoder\")\n",
    "ap.add_argument(\"-c\", \"--confidence\", type=float, default=0.5,\n",
    "\thelp=\"minimum probability to filter weak detections\")\n",
    "args = vars(ap.parse_args())\n",
    "\n",
    "# load our serialized face detector from disk\n",
    "print(\"[INFO] loading face detector...\")\n",
    "protoPath = os.path.sep.join([args[\"detector\"], \"deploy.prototxt\"])\n",
    "modelPath = os.path.sep.join([args[\"detector\"],\n",
    "\t\"res10_300x300_ssd_iter_140000.caffemodel\"])\n",
    "detector = cv2.dnn.readNetFromCaffe(protoPath, modelPath)\n",
    "\n",
    "# load our serialized face embedding model from disk\n",
    "print(\"[INFO] loading face recognizer...\")\n",
    "embedder = cv2.dnn.readNetFromTorch(args[\"embedding_model\"])\n",
    "\n",
    "# load the actual face recognition model along with the label encoder\n",
    "recognizer = pickle.loads(open(args[\"recognizer\"], \"rb\").read())\n",
    "le = pickle.loads(open(args[\"le\"], \"rb\").read())\n",
    "\n",
    "# load the image, resize it to have a width of 600 pixels (while\n",
    "# maintaining the aspect ratio), and then grab the image dimensions\n",
    "image = cv2.imread(args[\"image\"])\n",
    "image = imutils.resize(image, width=600)\n",
    "(h, w) = image.shape[:2]\n",
    "\n",
    "# construct a blob from the image\n",
    "imageBlob = cv2.dnn.blobFromImage(\n",
    "\tcv2.resize(image, (300, 300)), 1.0, (300, 300),\n",
    "\t(104.0, 177.0, 123.0), swapRB=False, crop=False)\n",
    "\n",
    "# apply OpenCV's deep learning-based face detector to localize\n",
    "# faces in the input image\n",
    "detector.setInput(imageBlob)\n",
    "detections = detector.forward()\n",
    "\n",
    "# loop over the detections\n",
    "for i in range(0, detections.shape[2]):\n",
    "\t# extract the confidence (i.e., probability) associated with the\n",
    "\t# prediction\n",
    "\tconfidence = detections[0, 0, i, 2]\n",
    "\n",
    "\t# filter out weak detections\n",
    "\tif confidence > args[\"confidence\"]:\n",
    "\t\t# compute the (x, y)-coordinates of the bounding box for the\n",
    "\t\t# face\n",
    "\t\tbox = detections[0, 0, i, 3:7] * np.array([w, h, w, h])\n",
    "\t\t(startX, startY, endX, endY) = box.astype(\"int\")\n",
    "\n",
    "\t\t# extract the face ROI\n",
    "\t\tface = image[startY:endY, startX:endX]\n",
    "\t\t(fH, fW) = face.shape[:2]\n",
    "\n",
    "\t\t# ensure the face width and height are sufficiently large\n",
    "\t\tif fW < 20 or fH < 20:\n",
    "\t\t\tcontinue\n",
    "\n",
    "\t\t# construct a blob for the face ROI, then pass the blob\n",
    "\t\t# through our face embedding model to obtain the 128-d\n",
    "\t\t# quantification of the face\n",
    "\t\tfaceBlob = cv2.dnn.blobFromImage(face, 1.0 / 255, (96, 96),\n",
    "\t\t\t(0, 0, 0), swapRB=True, crop=False)\n",
    "\t\tembedder.setInput(faceBlob)\n",
    "\t\tvec = embedder.forward()\n",
    "\n",
    "\t\t# perform classification to recognize the face\n",
    "\t\tpreds = recognizer.predict_proba(vec)[0]\n",
    "\t\tj = np.argmax(preds)\n",
    "\t\tproba = preds[j]\n",
    "\t\tname = le.classes_[j]\n",
    "\n",
    "\t\t# draw the bounding box of the face along with the associated\n",
    "\t\t# probability\n",
    "\t\ttext = \"{}: {:.2f}%\".format(name, proba * 100)\n",
    "\t\ty = startY - 10 if startY - 10 > 10 else startY + 10\n",
    "\t\tcv2.rectangle(image, (startX, startY), (endX, endY),\n",
    "\t\t\t(0, 0, 255), 2)\n",
    "\t\tcv2.putText(image, text, (startX, y),\n",
    "\t\t\tcv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 2)\n",
    "\n",
    "# show the output image\n",
    "cv2.imshow(\"Image\", image)\n",
    "cv2.waitKey(0)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
