Recognize faces from Python using deep learning models with state-of-the-art accuracy
npx @tessl/cli install tessl/pypi-face-recognition@1.3.0A comprehensive Python library for face detection, recognition, and manipulation using state-of-the-art deep learning models. Built on dlib's deep learning models with 99.38% accuracy on the Labeled Faces in the Wild benchmark, this library provides simple APIs for detecting faces, extracting facial landmarks, generating face encodings, and comparing faces for identification.
pip install face_recognitionimport face_recognitionAll functions are available directly from the main module:
# Import specific functions
from face_recognition import load_image_file, face_locations, face_encodings, compare_facesimport face_recognition
# Load images
known_image = face_recognition.load_image_file("known_person.jpg")
unknown_image = face_recognition.load_image_file("unknown_person.jpg")
# Find face encodings
known_encoding = face_recognition.face_encodings(known_image)[0]
unknown_encoding = face_recognition.face_encodings(unknown_image)[0]
# Compare faces
results = face_recognition.compare_faces([known_encoding], unknown_encoding)
print(results[0]) # True if match, False otherwise
# Get similarity distance (lower = more similar)
distance = face_recognition.face_distance([known_encoding], unknown_encoding)
print(distance[0]) # e.g., 0.45The library is built on a modular architecture using dlib's machine learning models:
This design enables a complete face recognition pipeline from raw images to identification results.
Load image files into numpy arrays suitable for face processing.
def load_image_file(file, mode='RGB'):
"""
Loads an image file (.jpg, .png, etc) into a numpy array.
Args:
file: Image file name or file object to load
mode: Format to convert the image to. 'RGB' (8-bit RGB, 3 channels) or 'L' (black and white)
Returns:
numpy.ndarray: Image contents as numpy array
"""Detect and locate faces in images, returning bounding box coordinates.
def face_locations(img, number_of_times_to_upsample=1, model="hog"):
"""
Returns an array of bounding boxes of human faces in an image.
Args:
img: An image (as a numpy array)
number_of_times_to_upsample: How many times to upsample the image looking for faces. Higher numbers find smaller faces
model: Which face detection model to use. "hog" is less accurate but faster on CPUs. "cnn" is more accurate deep-learning model which is GPU/CUDA accelerated (if available)
Returns:
list: List of tuples of found face locations in CSS (top, right, bottom, left) order
"""def batch_face_locations(images, number_of_times_to_upsample=1, batch_size=128):
"""
Returns a 2D array of bounding boxes of human faces in images using the CNN face detector.
Optimized for GPU processing of multiple images at once.
Args:
images: A list of images (each as a numpy array)
number_of_times_to_upsample: How many times to upsample the image looking for faces
batch_size: How many images to include in each GPU processing batch
Returns:
list: 2D list of tuples of found face locations in CSS (top, right, bottom, left) order
"""Usage example:
import face_recognition
image = face_recognition.load_image_file("group_photo.jpg")
# Basic face detection
face_locations = face_recognition.face_locations(image)
print(f"Found {len(face_locations)} faces")
# For higher accuracy (GPU recommended)
face_locations_cnn = face_recognition.face_locations(image, model="cnn")
# Batch processing for multiple images
images = [face_recognition.load_image_file(f"photo_{i}.jpg") for i in range(5)]
batch_locations = face_recognition.batch_face_locations(images)Extract detailed facial feature locations (eyes, nose, mouth, chin) from detected faces.
def face_landmarks(face_image, face_locations=None, model="large"):
"""
Given an image, returns a dict of face feature locations (eyes, nose, etc) for each face in the image.
Args:
face_image: Image to search
face_locations: Optionally provide a list of face locations to check
model: Which model to use. "large" (default) returns 68 points, "small" returns 5 points but is faster
Returns:
list: List of dicts of face feature locations (eyes, nose, etc)
"""Landmark structure for "large" model (68 points):
chin: 17 points along jawlineleft_eyebrow: 5 pointsright_eyebrow: 5 pointsnose_bridge: 4 pointsnose_tip: 5 pointsleft_eye: 6 pointsright_eye: 6 pointstop_lip: 12 pointsbottom_lip: 12 pointsLandmark structure for "small" model (5 points):
nose_tip: 1 pointleft_eye: 2 pointsright_eye: 2 pointsUsage example:
import face_recognition
image = face_recognition.load_image_file("face.jpg")
# Get detailed facial landmarks (68 points)
landmarks = face_recognition.face_landmarks(image)
for face_landmarks in landmarks:
# Access specific features
left_eye = face_landmarks['left_eye']
nose_tip = face_landmarks['nose_tip']
# Get faster landmarks (5 points)
landmarks_small = face_recognition.face_landmarks(image, model="small")Generate 128-dimensional numerical representations of faces for recognition and comparison.
def face_encodings(face_image, known_face_locations=None, num_jitters=1, model="small"):
"""
Given an image, return the 128-dimension face encoding for each face in the image.
Args:
face_image: The image that contains one or more faces
known_face_locations: Optional - the bounding boxes of each face if you already know them
num_jitters: How many times to re-sample the face when calculating encoding. Higher is more accurate, but slower (i.e. 100 is 100x slower)
model: Which model to use. "small" (default) which only returns 5 points but is faster, or "large" which returns 68 points but is more detailed
Returns:
list: List of 128-dimensional face encodings (one for each face in the image)
"""Usage example:
import face_recognition
image = face_recognition.load_image_file("person.jpg")
# Generate face encodings
encodings = face_recognition.face_encodings(image)
if len(encodings) > 0:
encoding = encodings[0] # Get first face encoding
print(f"Encoding shape: {encoding.shape}") # (128,)
# For higher accuracy (slower)
accurate_encoding = face_recognition.face_encodings(image, num_jitters=100)[0]Compare face encodings to determine if faces match or calculate similarity distances.
def compare_faces(known_face_encodings, face_encoding_to_check, tolerance=0.6):
"""
Compare a list of face encodings against a candidate encoding to see if they match.
Args:
known_face_encodings: A list of known face encodings
face_encoding_to_check: A single face encoding to compare against the list
tolerance: How much distance between faces to consider it a match. Lower is more strict. 0.6 is typical best performance
Returns:
list: List of True/False values indicating which known_face_encodings match the face encoding to check
"""def face_distance(face_encodings, face_to_compare):
"""
Given a list of face encodings, compare them to a known face encoding and get a euclidean distance
for each comparison face. The distance tells you how similar the faces are.
Args:
face_encodings: List of face encodings to compare
face_to_compare: A face encoding to compare against
Returns:
numpy.ndarray: Array with the distance for each face in the same order as the 'face_encodings' array
"""Usage example:
import face_recognition
# Load known faces
known_image = face_recognition.load_image_file("known_person.jpg")
known_encoding = face_recognition.face_encodings(known_image)[0]
# Load unknown face
unknown_image = face_recognition.load_image_file("unknown_person.jpg")
unknown_encoding = face_recognition.face_encodings(unknown_image)[0]
# Compare faces
matches = face_recognition.compare_faces([known_encoding], unknown_encoding)
print(f"Match: {matches[0]}")
# Get distance (0.0 = identical, >1.0 = very different)
distances = face_recognition.face_distance([known_encoding], unknown_encoding)
print(f"Distance: {distances[0]:.2f}")
# Custom tolerance
strict_matches = face_recognition.compare_faces([known_encoding], unknown_encoding, tolerance=0.5)The package includes two command-line utilities for batch processing:
Compare faces in images against a directory of known people:
face_recognition ./pictures_of_people_i_know/ ./unknown_pictures/Additional options:
# Use CPU cores for parallel processing (default: 1, use -1 for all cores)
face_recognition --cpus 4 ./known_people/ ./unknown_pictures/
# Adjust tolerance for matching (default: 0.6, lower = stricter)
face_recognition --tolerance 0.5 ./known_people/ ./unknown_pictures/
# Show distance values in output
face_recognition --show-distance ./known_people/ ./unknown_pictures/Output format: filename,person_name or filename,person_name,distance (with --show-distance)
Detect and locate faces in images:
face_detection ./unknown_pictures/Additional options:
# Use CNN model for better accuracy (default: hog)
face_detection --model cnn ./unknown_pictures/
# Use multiple CPU cores for parallel processing
face_detection --cpus 4 ./unknown_pictures/Output format: filename,top,right,bottom,left (CSS-style coordinates)
Tuples in CSS order: (top, right, bottom, left) as pixel coordinates.
128-dimensional numpy arrays (float64) representing facial features.
Common error patterns and handling:
import face_recognition
# Check if faces were found
image = face_recognition.load_image_file("photo.jpg")
encodings = face_recognition.face_encodings(image)
if len(encodings) == 0:
print("No faces found in image")
else:
encoding = encodings[0] # Safe to access first encoding
# Handle invalid model parameters
try:
landmarks = face_recognition.face_landmarks(image, model="invalid")
except ValueError as e:
print(f"Invalid model: {e}")
# Verify face_recognition_models is installed
try:
import face_recognition_models
except ImportError:
print("Please install face_recognition_models package")batch_face_locations() for multiple images on GPUnum_jitters increases accuracy but reduces speed exponentially