<commit_before>{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# OpenCV Face Recognition"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#import OpenCV module\n",
    "import cv2\n",
    "#import os module for reading training data directories and paths\n",
    "import os\n",
    "#matplotlib for display our images\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Prepare training data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#function to detect face using OpenCV\n",
    "def detect_face(img):\n",
    "    #load OpenCV face detector, I am using LBP which is fast\n",
    "    #there is also a more accurate but slow Haar classifier\n",
    "    face_cascade = cv2.CascadeClassifier('opencv-files/lbpcascade_frontalface.xml')\n",
    "    \n",
    "    #img_copy = np.copy(colored_img)\n",
    "    \n",
    "    #convert the test image to gray image as opencv face detector expects gray images\n",
    "    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n",
    "    \n",
    "    #let's detect multiscale (some images may be closer to camera than others) images\n",
    "    #result is a list of faces\n",
    "    faces = face_cascade.detectMultiScale(gray);\n",
    "    \n",
    "    #if no faces are detected then return original img\n",
    "    if (len(faces) == 0):\n",
    "        return None\n",
    "    \n",
    "    #under the assumption that there will be only one face,\n",
    "    #extract the face area\n",
    "    (x, y, w, h) = faces[0]\n",
    "    \n",
    "    #return only the face part of the image\n",
    "    return img[y:y+w, x:x+h]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "#this function will read all persons' training images, detect face from each image\n",
    "#and will return two lists of exactly same size, one list \n",
    "# of faces and another list of labels for each face\n",
    "def prepare_training_data(data_folder_path):\n",
    "    \n",
    "    #list the directories (one directory for each subject) in data folder\n",
    "    dirs = os.listdir(data_folder_path)\n",
    "    \n",
    "    #list to hold all subject faces\n",
    "    faces = []\n",
    "    #list to hold labels for all subjects\n",
    "    labels = []\n",
    "    \n",
    "    #let's go through each directory and read images within it\n",
    "    for dir_name in dirs:\n",
    "        \n",
    "        #our subject directories start with letter 's' so\n",
    "        #ignore any non-relevant directories if any\n",
    "        if not dir_name.startswith(\"s\"):\n",
    "            continue;\n",
    "            \n",
    "        #extract label number of subject from dir_name\n",
    "        #format of dir name = slabel\n",
    "        #, so removing letter 's' from dir_name will give us label\n",
    "        label = int(dir_name.replace(\"s\", \"\"))\n",
    "        \n",
    "        #build path of directory containin images for current subject subject\n",
    "        #sample subject_dir_path = \"training-data/s1\"\n",
    "        subject_dir_path = data_folder_path + \"/\" + dir_name\n",
    "        \n",
    "        #get the images names that are inside the given subject directory\n",
    "        subject_images_names = os.listdir(subject_dir_path)\n",
    "        \n",
    "        #go through each image name, read image, \n",
    "        #detect face and add face to list of faces\n",
    "        for image_name in subject_images_names:\n",
    "            #build image path\n",
    "            #sample image path = training-data/s1/1.pgm\n",
    "            image_path = subject_dir_path + \"/\" + image_name\n",
    "            \n",
    "            #read image\n",
    "            image = cv2.imread(image_path)\n",
    "            \n",
    "            cv2.imshow(\"Adding training image...\", image)\n",
    "            cv2.waitKey(100)\n",
    "            \n",
    "            #detect face\n",
    "            face = detect_face(image)\n",
    "            \n",
    "            #add face to list of faces\n",
    "            faces.append(face)\n",
    "            #add label for this face\n",
    "            labels.append(label)\n",
    "            \n",
    "    cv2.destroyAllWindows()\n",
    "    cv2.waitKey(1)\n",
    "    cv2.destroyAllWindows()\n",
    "    \n",
    "    return faces, labels"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Preparing data...\n",
      "Data prepared\n",
      "Total faces:  40\n",
      "Total labels:  40\n"
     ]
    }
   ],
   "source": [
    "print(\"Preparing data...\")\n",
    "faces, labels = prepare_training_data(\"training-data\")\n",
    "print(\"Data prepared\")\n",
    "\n",
    "print(\"Total faces: \", len(faces))\n",
    "print(\"Total labels: \", len(labels))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {<commit_msg>feat: Add face recognizer training and prediction<commit_after>{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# OpenCV Face Recognition"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#import OpenCV module\n",
    "import cv2\n",
    "#import os module for reading training data directories and paths\n",
    "import os\n",
    "#import numpy to convert python lists to numpy arrays as \n",
    "#it is needed by OpenCV face recognizers\n",
    "import numpy as np\n",
    "\n",
    "#matplotlib for display our images\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Prepare training data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 130,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#function to detect face using OpenCV\n",
    "def detect_face(img):\n",
    "    #load OpenCV face detector, I am using LBP which is fast\n",
    "    #there is also a more accurate but slow Haar classifier\n",
    "    face_cascade = cv2.CascadeClassifier('opencv-files/lbpcascade_frontalface.xml')\n",
    "    \n",
    "    #img_copy = np.copy(colored_img)\n",
    "    \n",
    "    #convert the test image to gray image as opencv face detector expects gray images\n",
    "    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n",
    "    \n",
    "    #gray = np.array(gray, \"uint8\")\n",
    "    #let's detect multiscale (some images may be closer to camera than others) images\n",
    "    #result is a list of faces\n",
    "    faces = face_cascade.detectMultiScale(gray);\n",
    "    \n",
    "    #if no faces are detected then return original img\n",
    "    if (len(faces) == 0):\n",
    "        return None\n",
    "    \n",
    "    #under the assumption that there will be only one face,\n",
    "    #extract the face area\n",
    "    (x, y, w, h) = faces[0]\n",
    "    \n",
    "    #return only the face part of the image\n",
    "    return gray[y:y+w, x:x+h]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 131,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "#this function will read all persons' training images, detect face from each image\n",
    "#and will return two lists of exactly same size, one list \n",
    "# of faces and another list of labels for each face\n",
    "def prepare_training_data(data_folder_path):\n",
    "    \n",
    "    #list the directories (one directory for each subject) in data folder\n",
    "    dirs = os.listdir(data_folder_path)\n",
    "    \n",
    "    #list to hold all subject faces\n",
    "    faces = []\n",
    "    #list to hold labels for all subjects\n",
    "    labels = []\n",
    "    \n",
    "    #let's go through each directory and read images within it\n",
    "    for dir_name in dirs:\n",
    "        \n",
    "        #our subject directories start with letter 's' so\n",
    "        #ignore any non-relevant directories if any\n",
    "        if not dir_name.startswith(\"s\"):\n",
    "            continue;\n",
    "            \n",
    "        #extract label number of subject from dir_name\n",
    "        #format of dir name = slabel\n",
    "        #, so removing letter 's' from dir_name will give us label\n",
    "        label = int(dir_name.replace(\"s\", \"\"))\n",
    "        \n",
    "        #build path of directory containin images for current subject subject\n",
    "        #sample subject_dir_path = \"training-data/s1\"\n",
    "        subject_dir_path = data_folder_path + \"/\" + dir_name\n",
    "        \n",
    "        #get the images names that are inside the given subject directory\n",
    "        subject_images_names = os.listdir(subject_dir_path)\n",
    "        \n",
    "        #go through each image name, read image, \n",
    "        #detect face and add face to list of faces\n",
    "        for image_name in subject_images_names:\n",
    "            #build image path\n",
    "            #sample image path = training-data/s1/1.pgm\n",
    "            image_path = subject_dir_path + \"/\" + image_name\n",
    "            print(\"adding image path: \", image_path)\n",
    "            \n",
    "            #read image\n",
    "            image = cv2.imread(image_path)\n",
    "            \n",
    "            #detect face\n",
    "            face = detect_face(image)\n",
    "            if face is not None:\n",
    "                print(\"Face detected: \", face.shape)\n",
    "                \n",
    "            cv2.imshow(\"Adding training image...\", image)\n",
    "            cv2.waitKey(100)\n",
    "            \n",
    "            #for the purpose of this tutorial\n",
    "            #we will ignore faces that are not detected\n",
    "            if face is not None:\n",
    "                #add face to list of faces\n",
    "                faces.append(face)\n",
    "                #add label for this face\n",
    "                labels.append(label)\n",
    "            \n",
    "    cv2.destroyAllWindows()\n",
    "    cv2.waitKey(1)\n",
    "    cv2.destroyAllWindows()\n",
    "    \n",
    "    return faces, labels"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 132,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Preparing data...\n",
      "adding image path:  training-data/s1/1.pgm\n",
      "Face detected:  (82, 82)\n",
      "adding image path:  training-data/s1/10.pgm\n",
      "Face detected:  (61, 61)\n",
      "adding image path:  training-data/s1/2.pgm\n",
      "adding image path:  training-data/s1/3.pgm\n",
      "Face detected:  (79, 79)\n",
      "adding image path:  training-data/s1/4.pgm\n",
      "adding image path:  training-data/s1/5.pgm\n",
      "adding image path:  training-data/s1/6.pgm\n",
      "adding image path:  training-data/s1/7.pgm\n",
      "Face detected:  (86, 86)\n",
      "adding image path:  training-data/s1/8.pgm\n",
      "Face detected:  (81, 81)\n",
      "adding image path:  training-data/s1/9.pgm\n",
      "Face detected:  (83, 83)\n",
      "adding image path:  training-data/s2/1.pgm\n",
      "Face detected:  (85, 85)\n",
      "adding image path:  training-data/s2/10.pgm\n",
      "Face detected:  (76, 76)\n",
      "adding image path:  training-data/s2/2.pgm\n",
      "adding image path:  training-data/s2/3.pgm\n",
      "Face detected:  (82, 82)\n",
      "adding image path:  training-data/s2/4.pgm\n",
      "Face detected:  (87, 87)\n",
      "adding image path:  training-data/s2/5.pgm\n",
      "adding image path:  training-data/s2/6.pgm\n",
      "adding image path:  training-data/s2/7.pgm\n",
      "Face detected:  (79, 79)\n",
      "adding image path:  training-data/s2/8.pgm\n",
      "adding image path:  training-data/s2/9.pgm\n",
      "adding image path:  training-data/s3/1.pgm\n",
      "Face detected:  (78, 78)\n",
      "adding image path:  training-data/s3/10.pgm\n",
      "Face detected:  (75, 75)\n",
      "adding image path:  training-data/s3/2.pgm\n",
      "Face detected:  (76, 76)\n",
      "adding image path:  training-data/s3/3.pgm\n",
      "Face detected:  (73, 73)\n",
      "adding image path:  training-data/s3/4.pgm\n",
      "adding image path:  training-data/s3/5.pgm\n",
      "adding image path:  training-data/s3/6.pgm\n",
      "Face detected:  (76, 76)\n",
      "adding image path:  training-data/s3/7.pgm\n",
      "Face detected:  (74, 74)\n",
      "adding image path:  training-data/s3/8.pgm\n",
      "Face detected:  (75, 75)\n",
      "adding image path:  training-data/s3/9.pgm\n",
      "Face detected:  (76, 76)\n",
      "adding image path:  training-data/s4/1.pgm\n",
      "Face detected:  (78, 78)\n",
      "adding image path:  training-data/s4/10.pgm\n",
      "adding image path:  training-data/s4/2.pgm\n",
      "Face detected:  (80, 80)\n",
      "adding image path:  training-data/s4/3.pgm\n",
      "Face detected:  (74, 74)\n",
      "adding image path:  training-data/s4/4.pgm\n",
      "Face detected:  (76, 76)\n",
      "adding image path:  training-data/s4/5.pgm\n",
      "Face detected:  (74, 74)\n",
      "adding image path:  training-data/s4/6.pgm\n",
      "Face detected:  (68, 68)\n",
      "adding image path:  training-data/s4/7.pgm\n",
      "Face detected:  (76, 76)\n",
      "adding image path:  training-data/s4/8.pgm\n",
      "Face detected:  (76, 76)\n",
      "adding image path:  training-data/s4/9.pgm\n",
      "Face detected:  (79, 79)\n",
      "Data prepared\n",
      "Total faces:  28\n",
      "Total labels:  28\n"
     ]
    }
   ],
   "source": [
    "print(\"Preparing data...\")\n",
    "faces, labels = prepare_training_data(\"training-data\")\n",
    "print(\"Data prepared\")\n",
    "\n",
    "print(\"Total faces: \", len(faces))\n",
    "print(\"Total labels: \", len(labels))\n",
    "\n",
    "# img = cv2.imread(\"training-data/s1/4.pgm\")\n",
    "# plt.imshow(img)\n",
    "\n",
    "# face = detect_face(img)\n",
    "# if face is not None:\n",
    "#     plt.imshow(face)\n",
    "# else:\n",
    "#     print(\"No face detected\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 128,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "#create our LBPH face recognizer \n",
    "face_recognizer = cv2.face.createLBPHFaceRecognizer()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 129,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "#train our face recognizer of our training faces\n",
    "face_recognizer.train(faces, np.array(labels))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 146,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4\n"
     ]
    }
   ],
   "source": [
    "img = cv2.imread(\"training-data/s4/4.pgm\")\n",
    "face = detect_face(img)\n",
    "\n",
    "label= face_recognizer.predict(face)\n",
    "print(label)\n",
    "#print(\"Predicted: label, confidence\", label, confidence)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
{'fraction_non_alphanumeric': 0.17115936603020093, 'fraction_numerical': 0.017534007238237864, 'mean_word_length': 1.9862120365194709, 'pattern_counts': {'":': 103, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1348654', 'n_tokens_mistral': 5829, 'n_tokens_neox': 5654, 'n_words': 1356}