|
import io |
|
from deepface import DeepFace |
|
import pandas as pd |
|
import gradio as gr |
|
import matplotlib.pyplot as plt |
|
import requests, validators |
|
import torch |
|
import pathlib |
|
from PIL import Image |
|
import os |
|
|
|
|
|
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE" |
|
|
|
def get_original_image(url_input): |
|
"""Extract image from URL""" |
|
|
|
if validators.url(url_input): |
|
image = Image.open(requests.get(url_input, stream=True).raw) |
|
|
|
return image |
|
|
|
def face_verification(img1, img2, dist,model,detector): |
|
"""Check the similarity of 2 images""" |
|
|
|
try: |
|
result = DeepFace.verify(img1_path=img1,img2_path=img2,distance_metric=dist,model_name=model,detector_backend=detector) |
|
except: |
|
result = DeepFace.verify(img1_path=img1,img2_path=img2,distance_metric=dist,model_name=model,detector_backend=detector,\ |
|
enforce_detection=False) |
|
|
|
return result['verified'],round(result['distance'],2),result['threshold'],result['model'],result['similarity_metric'] |
|
|
|
def facial_analysis(img1, detector): |
|
"""Determine emotion, race, gender and age from models""" |
|
|
|
try: |
|
|
|
obj = DeepFace.analyze(img_path = img1, actions = ['age', 'gender', 'race', 'emotion'],detector_backend=detector) |
|
except: |
|
obj = DeepFace.analyze(img_path = img1, actions = ['age', 'gender', 'race', 'emotion'],detector_backend=detector,\ |
|
enforce_detection=False) |
|
|
|
return obj['age'],obj['gender'],obj['dominant_race'],obj['dominant_emotion'] |
|
|
|
def face_recognition(img1,dir_loc,model,dist,detector): |
|
"""Facial recognition given a database or folder location with images""" |
|
|
|
|
|
rec = DeepFace.find(img_path = img_1, db_path = dir_loc,distance_metric=dist,model_name=model,detector_backend=detector) |
|
|
|
return rec |
|
|
|
|
|
def set_example_image(example: list) -> dict: |
|
return gr.Image.update(value=example[0]) |
|
|
|
def set_example_url(example: list) -> dict: |
|
return gr.Textbox.update(value=example[0]), gr.Image.update(value=get_original_image(example[0])) |
|
|
|
|
|
title = """<h1 id="title">DeepFace for Facial Recognition and Analysis</h1>""" |
|
|
|
description = """ |
|
Deepface is a lightweight face recognition and facial attribute analysis (age, gender, emotion and race) framework for python. It is a hybrid face recognition framework wrapping state-of-the-art models: VGG-Face, Google FaceNet, OpenFace, Facebook DeepFace, DeepID, ArcFace, Dlib and SFace. |
|
|
|
Experiments show that human beings have 97.53% accuracy on facial recognition tasks whereas those models already reached and passed that accuracy level. |
|
Please click on the Github link for more information: [DeepFace](https://github.com/serengil/deepface) |
|
|
|
This space captures facial verification which determines if 2 facial images are the same person and the facial attribute analysis which predicts age,gender, emotion and race. The attribute analysis for age and race is a hit and miss based on my personal experience and the reported test accuracy from the Github page is 68% for race prediction. The age prediction model got ± 4.65 MAE. |
|
|
|
The prediction models work better with images that mainly show the face. |
|
""" |
|
|
|
models = ["VGG-Face", "Facenet", "Facenet512", "OpenFace", "DeepFace", "DeepID", "ArcFace", "Dlib", "SFace"] |
|
metrics = ["cosine", "euclidean", "euclidean_l2"] |
|
backends = ['opencv', 'ssd', 'dlib', 'mtcnn', 'retinaface', 'mediapipe'] |
|
|
|
urls = [["https://media.vanityfair.com/photos/6036a15657f37ea4415256d2/master/w_2560%2Cc_limit/1225292516",\ |
|
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQSuPVx0JaEW2yp4mT8ZwqFANMT3RhoxcwuuGLhnKgxsA&s"]] |
|
|
|
url = [['https://media.vanityfair.com/photos/6036a15657f37ea4415256d2/master/w_2560%2Cc_limit/1225292516']] |
|
|
|
all_images = [[path.as_posix()] for path in sorted(pathlib.Path('images').rglob('*.j*g'))]) |
|
nick = [[path.as_posix()] for path in sorted(pathlib.Path('images').rglob('*nick*.j*g'))]) |
|
nicks_images = [[i[0] for i in nick]] |
|
|
|
twitter_link = """ |
|
[![](https://img.shields.io/twitter/follow/nickmuchi?label=@nickmuchi&style=social)](https://twitter.com/nickmuchi) |
|
""" |
|
|
|
css = ''' |
|
h1#title { |
|
text-align: center; |
|
} |
|
''' |
|
demo = gr.Blocks(css=css) |
|
|
|
with demo: |
|
gr.Markdown(title) |
|
gr.Markdown(description) |
|
gr.Markdown(twitter_link) |
|
model_options = gr.Dropdown(choices=models,label='Facial Recognition Models',value=models[1],show_label=True) |
|
metric_options = gr.Radio(choices=metrics,label='Distance Metric', value=metrics[0],show_label=True) |
|
backends_options = gr.Dropdown(choices=backends,label='Face Detector',value=backends[-2],show_label=True) |
|
|
|
with gr.Tabs(): |
|
with gr.TabItem('Facial Recognition'): |
|
with gr.Tabs(): |
|
with gr.TabItem("URL Images"): |
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
url_input_1_fr = gr.Textbox(lines=2,label='Image URL 1') |
|
url_image_1_fr = gr.Image(label='Image 1',shape=(550,550),interactive=False) |
|
url_input_1_fr.change(get_original_image, url_input_1_fr, url_image_1_fr) |
|
url_input_2 = gr.Textbox(lines=2,label='Image URL 2') |
|
url_image_2 = gr.Image(label='Image 2',shape=(550,550),interactive=False) |
|
url_input_2.change(get_original_image, url_input_2, url_image_2) |
|
|
|
with gr.Column(): |
|
sim_from_url = gr.Label(label='Same Person') |
|
dist_from_url = gr.Label(label = 'Distance') |
|
thresh_from_url = gr.Label(label = 'Threshold to Verify') |
|
model_from_url = gr.Label(label = 'Model Name') |
|
metric_from_url = gr.Label(label = 'Similarity Metric') |
|
|
|
|
|
with gr.Row(): |
|
example_url = gr.Examples(examples=urls,inputs=[url_input_1_fr,url_input_2]) |
|
|
|
url_but_fr = gr.Button('Verify') |
|
|
|
with gr.TabItem("Upload Images"): |
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
upload_image_1_fr = gr.Image(label='Image 1',shape=(550,550),interactive=True) |
|
upload_image_2 = gr.Image(label='Image 2',shape=(550,550),interactive=True) |
|
with gr.Column(): |
|
sim_from_upload = gr.Label(label='Same Person') |
|
dist_from_upload = gr.Label(label = 'Distance') |
|
thresh_from_upload = gr.Label(label = 'Threshold to Verify') |
|
model_from_upload = gr.Label(label = 'Model Name') |
|
metric_from_upload = gr.Label(label = 'Similarity Metric') |
|
|
|
with gr.Row(): |
|
example_images = gr.Examples(examples =nicks_images,inputs=[upload_image_1_fr,upload_image_2]) |
|
|
|
up_but_fr = gr.Button('Verify') |
|
|
|
|
|
with gr.TabItem('Facial Analysis'): |
|
|
|
with gr.Tabs(): |
|
with gr.TabItem("URL Image"): |
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
url_input_1_fa = gr.Textbox(lines=2,label='Enter valid image URL here..') |
|
url_image_1_fa = gr.Image(label='Image 1',shape=(550,550)) |
|
url_input_1_fa.change(get_original_image, url_input_1_fa, url_image_1_fa) |
|
|
|
|
|
with gr.Column(): |
|
age_from_url = gr.Label(label='Age') |
|
gender_from_url = gr.Label(label = 'Gender') |
|
emo_from_url = gr.Label(label = 'Emotion') |
|
race_from_url = gr.Label(label = 'Race') |
|
|
|
with gr.Row(): |
|
example_url = gr.Examples(examples=url,inputs=[url_input_1_fa]) |
|
|
|
url_but_fa = gr.Button('Analyze') |
|
|
|
with gr.TabItem("Upload Image"): |
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
upload_image_1_fa = gr.Image(label='Image 1',shape=(550,550)) |
|
|
|
with gr.Column(): |
|
age_from_upload = gr.Label(label='Age') |
|
gender_from_upload = gr.Label(label = 'Gender') |
|
emo_from_upload = gr.Label(label = 'Emotion') |
|
race_from_upload = gr.Label(label = 'Race') |
|
|
|
with gr.Row(): |
|
example_images = gr.Examples(examples =all_images,inputs=[upload_image_1_fa]) |
|
|
|
up_but_fa = gr.Button('Analyze') |
|
|
|
|
|
with gr.TabItem("WebCam Image"): |
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
web_image = gr.Image(label='WebCam Image',source='webcam',shape=(550,550),streaming=True) |
|
|
|
with gr.Column(): |
|
age_from_web = gr.Label(label='Age') |
|
gender_from_web = gr.Label(label = 'Gender') |
|
emo_from_web = gr.Label(label = 'Emotion') |
|
race_from_web = gr.Label(label = 'Race') |
|
|
|
web_but_fa = gr.Button('Analyze') |
|
|
|
url_but_fr.click(face_verification,inputs=[url_image_1_fr,url_image_2,metric_options,model_options,backends_options],\ |
|
outputs=[sim_from_url,dist_from_url,thresh_from_url,model_from_url,metric_from_url],queue=True) |
|
up_but_fr.click(face_verification,inputs=[upload_image_1_fr,upload_image_2,metric_options,model_options,backends_options],\ |
|
outputs=[sim_from_upload,dist_from_upload,thresh_from_upload,model_from_upload,metric_from_upload],queue=True) |
|
url_but_fa.click(facial_analysis,inputs=[url_image_1_fa,backends_options],\ |
|
outputs=[age_from_url,gender_from_url,race_from_url,emo_from_url],queue=True) |
|
up_but_fa.click(facial_analysis,inputs=[upload_image_1_fa,backends_options],\ |
|
outputs=[age_from_upload,gender_from_upload,race_from_upload,emo_from_upload]) |
|
web_but_fa.click(facial_analysis,inputs=[web_image,backends_options],\ |
|
outputs=[age_from_web,gender_from_web,race_from_web,emo_from_web]) |
|
|
|
|
|
gr.Markdown("![visitor badge](https://visitor-badge.glitch.me/badge?page_id=nickmuchi-deepface)") |
|
|
|
|
|
demo.launch(debug=True,enable_queue=True) |