Logo

dev-resources.site

for different kinds of informations.

Face Recognition with Python and FaceNet

Published at
1/12/2025
Categories
python
ai
machinelearning
pytorch
Author
edgaras
Categories
4 categories in total
python
open
ai
open
machinelearning
open
pytorch
open
Author
7 person written this
edgaras
open
Face Recognition with Python and FaceNet

This guide demonstrates how to use facenet-pytorch to implement a tool for detecting face similarity. Built on the FaceNet model, which generates high-quality face embeddings, the tool compares a target image with multiple pictures to identify the most similar face. Here the process to get started.
**
Key Tools and Libraries**

  1. PyTorch: For deep learning operations.
  2. FaceNet-PyTorch: Provides pre-trained models for face detection and embedding.
  3. Pillow (PIL): For image manipulation.
  4. Matplotlib: For visualizing results.

We'll use two main models:

  • MTCNN: For detecting faces.
  • InceptionResnetV1: For extracting face embeddings.

Initialization

import torch
from facenet_pytorch import MTCNN, InceptionResnetV1
from PIL import Image
import requests
from io import BytesIO
import matplotlib.pyplot as plt

# Initialize the MTCNN module for face detection and the InceptionResnetV1 module for face embedding.
mtcnn = MTCNN(image_size=160, keep_all=True)
resnet = InceptionResnetV1(pretrained='vggface2').eval()
Enter fullscreen mode Exit fullscreen mode

Function Definitions

1. Load Image and Extract Embedding:
This function loads an image from a URL, detects the face, and computes the embedding.

def get_embedding_and_face(image_path):
    """Load an image, detect the face, and return the embedding and face."""
    try:
        response = requests.get(image_path)
        response.raise_for_status()
        content_type = response.headers.get('Content-Type')
        if 'image' not in content_type:
            raise ValueError(f"URL does not point to an image: {content_type}")
        image = Image.open(BytesIO(response.content)).convert("RGB")
    except Exception as e:
        print(f"Error loading image from {image_path}: {e}")
        return None, None

    faces, probs = mtcnn(image, return_prob=True)
    if faces is None or len(faces) == 0:
        return None, None

    embedding = resnet(faces[0].unsqueeze(0))
    return embedding, faces[0]
Enter fullscreen mode Exit fullscreen mode

2. Convert Tensor to Image:
This function prepares a tensor for visualization.

def tensor_to_image(tensor):
    """Convert a normalized tensor to a valid image array."""
    image = tensor.permute(1, 2, 0).detach().numpy()
    image = (image - image.min()) / (image.max() - image.min())
    image = (image * 255).astype('uint8')
    return image
Enter fullscreen mode Exit fullscreen mode

3. Find the Most Similar Face:
This function compares the embeddings of the target image with the candidates.

def find_most_similar(target_image_path, candidate_image_paths):
    """Find the most similar image to the target image from a list of candidate images."""
    target_emb, target_face = get_embedding_and_face(target_image_path)
    if target_emb is None:
        raise ValueError("No face detected in the target image.")

    highest_similarity = float('-inf')
    most_similar_face = None
    most_similar_image_path = None

    candidate_faces = []
    similarities = []

    for candidate_image_path in candidate_image_paths:
        candidate_emb, candidate_face = get_embedding_and_face(candidate_image_path)
        if candidate_emb is None:
            similarities.append(None)
            candidate_faces.append(None)
            continue

        similarity = torch.nn.functional.cosine_similarity(target_emb, candidate_emb).item()
        similarities.append(similarity)
        candidate_faces.append(candidate_face)

        if similarity > highest_similarity:
            highest_similarity = similarity
            most_similar_face = candidate_face
            most_similar_image_path = candidate_image_path

    # Visualization
    plt.figure(figsize=(12, 8))

    # Display target image
    plt.subplot(2, len(candidate_image_paths) + 1, 1)
    plt.imshow(tensor_to_image(target_face))
    plt.title("Target Image")
    plt.axis("off")

    # Display most similar image
    if most_similar_face is not None:
        plt.subplot(2, len(candidate_image_paths) + 1, 2)
        plt.imshow(tensor_to_image(most_similar_face))
        plt.title("Most Similar")
        plt.axis("off")

    # Display all candidate images with similarity scores
    for idx, (candidate_face, similarity) in enumerate(zip(candidate_faces, similarities)):
        plt.subplot(2, len(candidate_image_paths) + 1, idx + len(candidate_image_paths) + 2)
        if candidate_face is not None:
            plt.imshow(tensor_to_image(candidate_face))
            plt.title(f"Score: {similarity * 100:.2f}%")
        else:
            plt.title("No Face")
        plt.axis("off")

    plt.tight_layout()
    plt.show()

    if most_similar_image_path is None:
        raise ValueError("No faces detected in the candidate images.")

    return most_similar_image_path, highest_similarity
Enter fullscreen mode Exit fullscreen mode

Usage

URLs of the images to compare:

image_url_target = 'https://d1mnxluw9mpf9w.cloudfront.net/media/7588/4x3/1200.jpg'
candidate_image_urls = [
    'https://beyondthesinglestory.wordpress.com/wp-content/uploads/2021/04/elon_musk_royal_society_crop1.jpg',
    'https://cdn.britannica.com/56/199056-050-CCC44482/Jeff-Bezos-2017.jpg',
    'https://cdn.britannica.com/45/188745-050-7B822E21/Richard-Branson-2003.jpg'
]

most_similar_image, similarity_score = find_most_similar(image_url_target, candidate_image_urls)
print(f"The most similar image is: {most_similar_image}")
print(f"Similarity score: {similarity_score * 100:.2f}%")
Enter fullscreen mode Exit fullscreen mode

Result

Image description

Conclusion

This example demonstrates the power of facenet-pytorch for facial recognition tasks. By combining face detection and embedding, we can create tools for various applications, such as identity verification, or content filtering.

Featured ones: