How to Build a Face Recognition System Using FaceNet in Python

Abhinav Anand - Sep 4 - - Dev Community

Face recognition technology has become increasingly prevalent in various applications, from security systems to social media. One of the most effective models for this task is FaceNet, a deep learning model designed for face verification, recognition, and clustering.

In this tutorial, I'll show you how to build a face recognition system in Python using FaceNet. We'll cover everything from loading the model to comparing faces. By the end of this guide, you'll have a solid foundation to implement face recognition in your own projects.

What is FaceNet?

FaceNet is a deep learning model developed by Google that maps faces into a 128-dimensional Euclidean space. These embeddings represent the essential features of a face, making it easy to compare and recognize faces with high accuracy. Unlike traditional face recognition methods, FaceNet focuses on embedding learning, which makes it highly effective and scalable.

Prerequisites

Before diving into the code, ensure you have the following installed:

  • Python 3.x
  • TensorFlow or Keras (for the deep learning model)
  • NumPy (for numerical operations)
  • OpenCV (for image processing)
  • Scikit-learn (for applying nearest neighbor search)

You can install these dependencies using pip:

pip install tensorflow numpy opencv-python scikit-learn
Enter fullscreen mode Exit fullscreen mode

Step 1: Loading the Pre-trained FaceNet Model

First, we'll load a pre-trained FaceNet model. You can either download the model from a trusted source or use the one available through the keras-facenet library.

from keras.models import load_model

# Load the pre-trained FaceNet model
model = load_model('facenet_keras.h5')
print("Model Loaded Successfully")
Enter fullscreen mode Exit fullscreen mode

Loading the model is the first step in setting up our face recognition system. The model will be used to generate embeddings for the images, which are numerical representations of the faces.

Step 2: Preprocessing Images for FaceNet

FaceNet expects input images to be 160x160 pixels in RGB format. Additionally, the pixel values need to be normalized before they are fed into the model.

import cv2
import numpy as np

def preprocess_image(image_path):
    # Load the image using OpenCV
    img = cv2.imread(image_path)

    # Convert the image to RGB (FaceNet expects RGB images)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

    # Resize the image to 160x160 pixels
    img = cv2.resize(img, (160, 160))

    # Normalize the pixel values
    img = img.astype('float32') / 255.0

    # Expand dimensions to match the input shape of FaceNet (1, 160, 160, 3)
    img = np.expand_dims(img, axis=0)

    return img
Enter fullscreen mode Exit fullscreen mode

This function handles the image preprocessing required by FaceNet. It converts the image to the appropriate format and size, ensuring that the model receives input it can effectively work with.

Step 3: Generating Face Embeddings

Next, we’ll use the FaceNet model to generate embeddings from the preprocessed images. These embeddings will serve as the unique numerical representations of the faces.

def get_face_embedding(model, image_path):
    # Preprocess the image
    img = preprocess_image(image_path)

    # Generate the embedding
    embedding = model.predict(img)

    return embedding
Enter fullscreen mode Exit fullscreen mode

The get_face_embedding function takes in the model and an image path, processes the image, and returns the embedding. This embedding is what we'll use for face comparison.

Step 4: Comparing Faces Using Embeddings

To determine if two faces match, we compare their embeddings by calculating the Euclidean distance between them. If the distance is below a certain threshold, the faces are considered a match.

from numpy import linalg as LA

def compare_faces(embedding1, embedding2, threshold=0.5):
    # Compute the Euclidean distance between the embeddings
    distance = LA.norm(embedding1 - embedding2)

    # Compare the distance to the threshold
    if distance < threshold:
        print("Face Matched.")
    else:
        print("Faces are different.")

    return distance
Enter fullscreen mode Exit fullscreen mode

The compare_faces function calculates the distance between two embeddings. If this distance is less than the specified threshold (0.5 by default), the function prints "Face Matched." Otherwise, it prints "Faces are different."

Step 5: Testing the Face Recognition System

Finally, let’s test our face recognition system with two images to see if it correctly identifies them as the same person or not.

# Load the FaceNet model
model = load_model('facenet_keras.h5')

# Get embeddings for two images
embedding1 = get_face_embedding(model, 'face1.jpg')
embedding2 = get_face_embedding(model, 'face2.jpg')

# Compare the two faces
distance = compare_faces(embedding1, embedding2)

print(f"Euclidean Distance: {distance}")
Enter fullscreen mode Exit fullscreen mode

Output

  • If the faces match, you'll see: Face Matched.
  • If they don't match, you'll see: Faces are different.

Additionally, the Euclidean distance between the two embeddings will be printed.

Conclusion

You've just built a simple yet powerful face recognition system using FaceNet in Python. This system can be easily expanded to include more faces, handle real-time recognition, or be integrated into larger projects. FaceNet's high accuracy and efficiency make it an excellent choice for face recognition tasks.

Feel free to experiment with the threshold values, or try using this system in a real-time application like a webcam-based face recognition tool.

If you have any questions or need further assistance, leave a comment below. Happy coding!


. . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player