{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import cv2\n", "import dlib\n", "import os\n", "import numpy as np\n", "import pandas as pd\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'/Users/pareshar/Personal/Github/temp/Facial-feature-detector'" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "current_dir = os.getcwd()\n", "parent_dir = os.path.dirname(current_dir)\n", "os.chdir(parent_dir)\n", "os.getcwd()" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# static variables\n", "path_to_images = \"data/images_age_gender/\"\n", "image_files = os.listdir(path_to_images)\n", "face_detector_weights = \"models/face_detection/res10_300x300_ssd_iter_140000.caffemodel\"\n", "face_detector_config = \"models/face_detection/deploy.prototxt.txt\"\n", "age_weights = \"models/face_age/age_net.caffemodel\"\n", "age_config = \"models/face_age/age_deploy.prototxt\"\n", "gender_weights = \"models/face_gender/gender_net.caffemodel\"\n", "gender_config = \"models/face_gender/gender_deploy.prototxt\"\n", "age_list = ['(0-2)', '(4-6)', '(8-12)', '(15-20)', '(25-32)', '(38-43)', '(48-53)', '(60-100)']\n", "gender_list = ['Male', 'Female']\n", "model_mean = (78.4263377603, 87.7689143744, 114.895847746) # taken from paper" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "df = pd.DataFrame(columns=[\"file_name\", \"model\", \"confidence_face_detected\", \"age_range\", \"age_confidence\", \"gender\", \"gender_confidence\"])\n", "df_list = []\n", "\n", "\n", "for image_file in image_files:\n", " image = cv2.imread(path_to_images + image_file)\n", " h, w = image.shape[:2]\n", " blob = cv2.dnn.blobFromImage(image=image, scalefactor=1.0, size=(300, 300))\n", " \n", " face_detector_net = cv2.dnn.readNetFromCaffe(face_detector_config, face_detector_weights)\n", " face_detector_net.setInput(blob)\n", " face_detections = face_detector_net.forward() \n", " age_net = cv2.dnn.readNet(age_weights, age_config)\n", " gender_net = cv2.dnn.readNet(gender_weights, gender_config)\n", " \n", " d = None\n", " \n", " for i in range(0, face_detections.shape[2]):\n", " confidence = face_detections[0, 0, i, 2]\n", " if confidence > 0.97:\n", " box = face_detections[0, 0, i, 3:7] * np.array([w, h, w, h])\n", " (startX, startY, endX, endY) = box.astype(\"int\")\n", " face = image[startY:endY, startX:endX]\n", " \n", " blob = cv2.dnn.blobFromImage(face, 1.0, (227, 227), model_mean, swapRB=False)\n", " \n", " age_net.setInput(blob)\n", " age_preds = age_net.forward()\n", " i = age_preds[0].argmax()\n", " age = age_list[i]\n", " age_confidence_score = age_preds[0][i]\n", " \n", " gender_net.setInput(blob)\n", " gender_preds = gender_net.forward()\n", " i = gender_preds[0].argmax()\n", " gender = gender_list[i]\n", " gender_confidence_score = gender_preds[0][i]\n", " \n", " # plt.imshow(face)\n", " # plt.show() \n", " \n", " d = {\n", " \"file_name\": image_file,\n", " \"model\": \"ageNet\",\n", " \"confidence_face_detected\": confidence,\n", " \"age_range\": age,\n", " \"age_confidence\": age_confidence_score,\n", " \"gender\": gender,\n", " \"gender_confidence\": gender_confidence_score \n", " }\n", " df_list.append(d)\n", " break\n", " \n", " if d is None or image_file != d[\"file_name\"]:\n", " \n", " d = {\n", " \"file_name\": image_file,\n", " \"model\": \"ageNet\",\n", " \"confidence_face_detected\": confidence,\n", " \"age_range\": \"NA\",\n", " \"age_confidence\": \"NA\",\n", " \"gender\": \"NA\",\n", " \"gender_confidence\": \"NA\" \n", " }\n", " \n", " df_list.append(d)\n", " \n", "df = pd.concat([df, pd.DataFrame(df_list)], ignore_index=True).round(2)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\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", "
file_namemodelconfidence_face_detectedage_rangeage_confidencegendergender_confidence
122_me.jpgageNet0.98(25-32)0.67165Male1.0
325_32_woman.jpgageNet1.00(25-32)0.859894Female0.952863
238_43_man.jpgageNet1.00(25-32)0.681306Male0.999431
838_43_woman.jpgageNet0.99(48-53)0.886763Female0.998737
74_6_boy.jpgageNet0.99(4-6)0.639939Male0.999049
44_6_girl.jpgageNet0.99(4-6)0.319971Female0.998801
660_100_man.jpgageNet0.99(4-6)0.548595Male0.999973
560_100_woman.jpgageNet1.00(60-100)0.332936Female0.984078
960_100_woman_2.jpgageNet1.00(38-43)0.414388Male0.518144
0minion.jpgageNet0.00NANANANA
\n", "
" ], "text/plain": [ " file_name model confidence_face_detected age_range \\\n", "1 22_me.jpg ageNet 0.98 (25-32) \n", "3 25_32_woman.jpg ageNet 1.00 (25-32) \n", "2 38_43_man.jpg ageNet 1.00 (25-32) \n", "8 38_43_woman.jpg ageNet 0.99 (48-53) \n", "7 4_6_boy.jpg ageNet 0.99 (4-6) \n", "4 4_6_girl.jpg ageNet 0.99 (4-6) \n", "6 60_100_man.jpg ageNet 0.99 (4-6) \n", "5 60_100_woman.jpg ageNet 1.00 (60-100) \n", "9 60_100_woman_2.jpg ageNet 1.00 (38-43) \n", "0 minion.jpg ageNet 0.00 NA \n", "\n", " age_confidence gender gender_confidence \n", "1 0.67165 Male 1.0 \n", "3 0.859894 Female 0.952863 \n", "2 0.681306 Male 0.999431 \n", "8 0.886763 Female 0.998737 \n", "7 0.639939 Male 0.999049 \n", "4 0.319971 Female 0.998801 \n", "6 0.548595 Male 0.999973 \n", "5 0.332936 Female 0.984078 \n", "9 0.414388 Male 0.518144 \n", "0 NA NA NA " ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.sort_values(\"file_name\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Hugging face pre-trained VIT model" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Users/pareshar/.pyenv/versions/3.8.10/lib/python3.8/site-packages/requests/__init__.py:102: RequestsDependencyWarning: urllib3 (1.26.15) or chardet (5.1.0)/charset_normalizer (2.0.12) doesn't match a supported version!\n", " warnings.warn(\"urllib3 ({}) or chardet ({})/charset_normalizer ({}) doesn't match a supported \"\n", "/Users/pareshar/.pyenv/versions/3.8.10/lib/python3.8/site-packages/urllib3/connectionpool.py:1045: InsecureRequestWarning: Unverified HTTPS request is being made to host 'huggingface.co'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings\n", " warnings.warn(\n", "/Users/pareshar/.pyenv/versions/3.8.10/lib/python3.8/site-packages/urllib3/connectionpool.py:1045: InsecureRequestWarning: Unverified HTTPS request is being made to host 'huggingface.co'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings\n", " warnings.warn(\n", "/Users/pareshar/.pyenv/versions/3.8.10/lib/python3.8/site-packages/transformers/models/vit/feature_extraction_vit.py:28: FutureWarning: The class ViTFeatureExtractor is deprecated and will be removed in version 5 of Transformers. Please use ViTImageProcessor instead.\n", " warnings.warn(\n" ] } ], "source": [ "# age\n", "\n", "import os\n", "import cv2\n", "from transformers import ViTImageProcessor, ViTForImageClassification\n", "\n", "os.environ[\n", " \"CURL_CA_BUNDLE\"\n", " ] = \"\" # fixes VPN issue when connecting to hugging face hub\n", "\n", "\n", "image = cv2.imread(\"data/4_6_boy.jpg\")\n", "\n", "\n", "# Init model, transforms\n", "model = ViTForImageClassification.from_pretrained('nateraw/vit-age-classifier')\n", "transforms = ViTImageProcessor.from_pretrained('nateraw/vit-age-classifier')\n", "\n", "# Transform our image and pass it through the model\n", "inputs = transforms(image, return_tensors='pt')\n", "output = model(**inputs)\n", "\n", "# Predicted Class probabilities\n", "proba = output.logits.softmax(1)\n", "\n", "# Predicted Classes\n", "preds = proba.argmax(1)\n" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.7176125645637512" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "max(proba[0]).item()" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'3-9'" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "id2label = {\n", " 0: \"0-2\",\n", " 1: \"3-9\",\n", " 2: \"10-19\",\n", " 3: \"20-29\",\n", " 4: \"30-39\",\n", " 5: \"40-49\",\n", " 6: \"50-59\",\n", " 7: \"60-69\",\n", " 8: \"more than 70\"\n", " }\n", "\n", "id2label[int(preds)]" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Users/pareshar/.pyenv/versions/3.8.10/lib/python3.8/site-packages/urllib3/connectionpool.py:1045: InsecureRequestWarning: Unverified HTTPS request is being made to host 'huggingface.co'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings\n", " warnings.warn(\n", "/Users/pareshar/.pyenv/versions/3.8.10/lib/python3.8/site-packages/urllib3/connectionpool.py:1045: InsecureRequestWarning: Unverified HTTPS request is being made to host 'huggingface.co'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings\n", " warnings.warn(\n" ] } ], "source": [ "# gender\n", "\n", "import os\n", "import cv2\n", "from transformers import ViTImageProcessor, ViTForImageClassification\n", "\n", "os.environ[\n", " \"CURL_CA_BUNDLE\"\n", " ] = \"\" # fixes VPN issue when connecting to hugging face hub\n", "\n", "\n", "image = cv2.imread(\"data/gigi_hadid.webp\")\n", "\n", "\n", "# Init model, transforms\n", "model = ViTForImageClassification.from_pretrained('rizvandwiki/gender-classification')\n", "transforms = ViTImageProcessor.from_pretrained('rizvandwiki/gender-classification')\n", "\n", "# Transform our image and pass it through the model\n", "inputs = transforms(image, return_tensors='pt')\n", "output = model(**inputs)\n", "\n", "# Predicted Class probabilities\n", "proba = output.logits.softmax(1)\n", "\n", "# Predicted Classes\n", "preds = proba.argmax(1)\n" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.9677436351776123" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "max(proba[0]).item()" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'female'" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "id2label = {\n", " 0: \"female\",\n", " 1: \"male\",\n", " }\n", "\n", "id2label[int(preds)]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Other\n", "- Dataset used to train model: https://talhassner.github.io/home/projects/Adience/Adience-data.html#agegender" ] } ], "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.8.10" }, "orig_nbformat": 4 }, "nbformat": 4, "nbformat_minor": 2 }