Skip to content

Instantly share code, notes, and snippets.

@0187773933
Created April 6, 2025 13:46
Show Gist options
  • Save 0187773933/a6f3e170be0c5151965d3abb4a66ad61 to your computer and use it in GitHub Desktop.
Save 0187773933/a6f3e170be0c5151965d3abb4a66ad61 to your computer and use it in GitHub Desktop.
DeepFace - Retinaface - DeepID
#!/usr/bin/env python3
import os
import cv2
import json
import time
import pickle
from deepface import DeepFace
from deepface.modules import verification
# https://github.com/serengil/retinaface
# https://sefiks.com/2020/06/16/face-recognition-with-deepid-in-keras/
# https://sefiks.com/2020/02/23/face-alignment-for-face-recognition-in-python-within-opencv/
# https://en.wikipedia.org/wiki/Cosine_similarity
# https://en.wikipedia.org/wiki/Euclidean_distance
# something we forgot about ,
# if there are more than one faces found in the search ,
# then don't just take threshold cutoff , we need the lowest one in the whole set
# because they obviously can't appear more than once , and should be the lowest in the group
# add a thing that takes in multiple test inputs ? and uses same threshold
# like age 3 , 5 , 7 , 10 , 12 , 15 , 20 , etc
# so then we match at each age group ?
def write_pickle( file_path , python_object ):
with open( file_path , 'wb') as f:
pickle.dump( python_object , f , protocol=pickle.HIGHEST_PROTOCOL )
def read_pickle( file_path ):
with open( file_path , 'rb' ) as f:
return pickle.load( f )
def write_json( file_path , python_object ):
with open( file_path , 'w' , encoding='utf-8' ) as f:
json.dump( python_object , f , ensure_ascii=False , indent=4 )
def extract_faces( file_path ):
faces = DeepFace.extract_faces(
img_path=image_path ,
detector_backend="retinaface" , # 'retinaface', 'mtcnn', 'ssd', 'dlib', 'mediapipe', 'yolov8', 'yolov11n', 'yolov11s', 'yolov11m', 'centerface'
enforce_detection=False ,
align=True ,
normalize_face=False , # We'll handle normalization inside represent()
# expand_percentage=0 ,
# color_face='rgb' , # optional
# grayscale=False , # optional
# anti_spoofing=False , # optional
)
return faces
def get_ebedding( cropped_face ):
representation = DeepFace.represent(
img_path=cropped_face ,
model_name="DeepID" , # "VGG-Face", "Facenet", "Facenet512", "OpenFace", "DeepFace", "DeepID", "ArcFace", "Dlib", "SFace", "GhostFaceNet"
detector_backend="skip" , # NO detection; face is already cropped
enforce_detection=False ,
align=False , # we already aligned
normalization="ArcFace" ,
# anti_spoofing=False ,
)
if len( representation ) != 1:
return []
embedding = representation[ 0 ][ "embedding" ]
return embedding
def get_test_ebedding( file_path ):
representation = DeepFace.represent(
img_path=file_path ,
model_name="DeepID" , # "VGG-Face", "Facenet", "Facenet512", "OpenFace", "DeepFace", "DeepID", "ArcFace", "Dlib", "SFace", "GhostFaceNet"
detector_backend="retinaface" , # NO detection; face is already cropped
enforce_detection=True ,
align=True ,
normalization="ArcFace" ,
# anti_spoofing=False ,
)
if len( representation ) != 1:
return []
embedding = representation[ 0 ][ "embedding" ]
return embedding
def get_embedding_distance( alpha , beta ):
distance = verification.find_distance( alpha , beta , "cosine" )
return distance
SHOW_IMAGES = True
# image_path = "/Users/morpheous/WORKSPACE/PYTHON/FaceSorter/image-tests/Winner-2022/DSC_0031.JPG"
# image_path = "/Users/morpheous/WORKSPACE/PYTHON/FaceSorter/image-tests/Winner-2018/20181123_170259.jpg"
image_path = "/Users/morpheous/WORKSPACE/PYTHON/FaceSorter/image-tests/Winner-2019/20191130_165001.jpg"
test_path = "/Users/morpheous/WORKSPACE/PYTHON/FaceSorter/image-misc/1.png"
test_embedding = get_test_ebedding( test_path )
faces = extract_faces( image_path )
for i , face in enumerate( faces ):
landmarks = face[ "facial_area" ]
confidence = face[ "confidence" ]
embedding = get_ebedding( face[ "face" ] )
cosine_distance = verification.find_distance( test_embedding , embedding , "cosine" )
euclidean_distance = verification.find_distance( test_embedding , embedding , "euclidean" )
euclidean_l2_distance = verification.find_distance( test_embedding , embedding , "euclidean_l2" )
print( f"Face #{i}:" )
print( f" Bounding box = {landmarks}" )
print( f" Confidence = {confidence}" )
print( f" Embedding = {len(embedding)}" )
print( f" Cosine Distance = {cosine_distance}" )
print( f" Euclidean Distance = {euclidean_distance}" )
print( f" Euclidean L2 Distance = {euclidean_l2_distance}" )
print( "" )
if SHOW_IMAGES:
# Convert RGB -> BGR for correct OpenCV color
face_bgr = cv2.cvtColor( face[ "face" ] , cv2.COLOR_RGB2BGR )
cv2.imshow( f"Face {i} (conf={confidence},cd={cosine_distance})" , face_bgr )
if SHOW_IMAGES:
cv2.waitKey( 0 )
cv2.destroyAllWindows()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment