How to Build a Real-Time Face Recognition System with Dlib and OpenCV in Python

This guide walks through constructing a Python‑based real‑time face recognition pipeline using Dlib and OpenCV, covering dataset creation, feature extraction, Euclidean distance matching, and live video stream identification, complete with code snippets, parameter tuning tips, and troubleshooting advice.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
How to Build a Real-Time Face Recognition System with Dlib and OpenCV in Python
Libraries used: dlib + OpenCV , Python version: 3.8 , Development environment: Jupyter Notebook (Anaconda3)

0. Dlib Face Feature Detection Principle

Extract facial landmarks (refer to relevant documentation).

Capture multiple images, compute a feature dataset and average feature vector, store them in a CSV file, then compare Euclidean distances between live camera face features and the stored averages to identify the closest match.

1. Build Face Feature Dataset

1. Install Dlib

Please refer to the official Dlib installation guide.

2. Construct Your Own Dataset

2.1 Capture Face Images

Capture 20 face images of size 256×256 from a video stream; these images form the training dataset.

The image size can be adjusted; larger images improve accuracy but increase training time.

Key considerations:

Lighting: discard overexposed or dark images; use the same device for data collection.

Code for capturing images:

import cv2
import dlib
import os
import sys
import random
# Store location
output_dir = 'D:/No1WorkSpace/JupyterNotebook/Facetrainset/Num&Name'  # number + name
size = 256  # image side length
if not os.path.exists(output_dir):
    os.makedirs(output_dir)
# Adjust brightness and contrast
def relight(img, light=1, bias=0):
    w = img.shape[1]
    h = img.shape[0]
    for i in range(0, w):
        for j in range(0, h):
            for c in range(3):
                tmp = int(img[j, i, c] * light + bias)
                if tmp > 255:
                    tmp = 255
                elif tmp < 0:
                    tmp = 0
                img[j, i, c] = tmp
    return img
# Use Dlib frontal_face_detector
detector = dlib.get_frontal_face_detector()
# Open camera
camera = cv2.VideoCapture(0)
index = 1
while True:
    if index <= 20:
        print('Being processed picture %s' % index)
        success, img = camera.read()
        gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        dets = detector(gray_img, 1)
        for i, d in enumerate(dets):
            x1 = d.top() if d.top() > 0 else 0
            y1 = d.bottom() if d.bottom() > 0 else 0
            x2 = d.left() if d.left() > 0 else 0
            y2 = d.right() if d.right() > 0 else 0
            face = img[x1:y1, x2:y2]
            face = relight(face, random.uniform(0.5, 1.5), random.randint(-50, 50))
            face = cv2.resize(face, (size, size))
            cv2.imshow('image', face)
            cv2.imwrite(os.path.join(output_dir, f'{index}.jpg'), face)
            index += 1
        key = cv2.waitKey(30) & 0xff
        if key == 27:
            break
    else:
        print('Finished!')
        camera.release()
        cv2.destroyAllWindows()
        break

Running effect:

2.2 Analyze Each Face's Feature Vector and Save to CSV

Extract 128‑dimensional features from the captured images and store them, along with their averages, in a CSV file.

The intermediate 68‑point feature sets can be discarded after averaging; they are shown here for learning purposes.

Code for feature extraction and CSV generation:

# Extract face features and save to CSV
# Features extraction from images and save into features_all.csv

from cv2 import cv2 as cv2
import os
import dlib
from skimage import io
import csv
import numpy as np

path_images_from_camera = "D:/No1WorkSpace/JupyterNotebook/Facetrainset/"

detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("D:/No1WorkSpace/JupyterNotebook/model/shape_predictor_68_face_landmarks.dat")
face_rec = dlib.face_recognition_model_v1("D:/No1WorkSpace/JupyterNotebook/model/dlib_face_recognition_resnet_model_v1.dat")

def return_128d_features(path_img):
    img_rd = io.imread(path_img)
    img_gray = cv2.cvtColor(img_rd, cv2.COLOR_BGR2RGB)
    faces = detector(img_gray, 1)
    print("%-40s %-20s" % ("Detected image with faces:", path_img), '
')
    if len(faces) != 0:
        shape = predictor(img_gray, faces[0])
        face_descriptor = face_rec.compute_face_descriptor(img_gray, shape)
    else:
        face_descriptor = 0
        print("no face")
    return face_descriptor

def return_features_mean_personX(path_faces_personX):
    features_list_personX = []
    photos_list = os.listdir(path_faces_personX)
    if photos_list:
        for i in range(len(photos_list)):
            with open("D:/No1WorkSpace/JupyterNotebook/feature/featuresGiao"+str(i)+".csv", "w", newline="") as csvfile:
                writer = csv.writer(csvfile)
                print("%-40s %-20s" % ("Reading image:", path_faces_personX + "/" + photos_list[i]))
                features_128d = return_128d_features(os.path.join(path_faces_personX, photos_list[i]))
                print(features_128d)
                writer.writerow(features_128d)
                if features_128d == 0:
                    i += 1
                else:
                    features_list_personX.append(features_128d)
    else:
        print("Warning: No images in " + path_faces_personX + '/', '
')
    if features_list_personX:
        features_mean_personX = np.array(features_list_personX).mean(axis=0)
    else:
        features_mean_personX = '0'
    return features_mean_personX

people = os.listdir(path_images_from_camera)
people.sort()
with open("D:/No1WorkSpace/JupyterNotebook/feature/features_all.csv", "w", newline="") as csvfile:
    writer = csv.writer(csvfile)
    for person in people:
        print("##### " + person + " #####")
        features_mean_personX = return_features_mean_personX(os.path.join(path_images_from_camera, person))
        writer.writerow(features_mean_personX)
        print("Mean of features:", list(features_mean_personX), '
')
    print("All face data saved to: D:/myworkspace/JupyterNotebook/People/feature/features_all2.csv")
If you run the code directly, using Chinese directories may cause garbled characters.

Running effect:

2. Recognize Faces and Match Dataset

1. Principle

Compute Euclidean distance between the feature vector of a live face and each stored vector; the smallest distance indicates the best match.

Euclidean distance (or L2 norm) measures the straight‑line distance between two points in an m‑dimensional space.

2. Real‑Time Video Stream Face Recognition

Code for live face identification using the camera:

# Real‑time face recognition with camera
import os
import dlib
import csv
import time
import sys
import numpy as np
from cv2 import cv2 as cv2
import pandas as pd

facerec = dlib.face_recognition_model_v1("D:/No1WorkSpace/JupyterNotebook/model/dlib_face_recognition_resnet_model_v1.dat")

def return_euclidean_distance(feature_1, feature_2):
    feature_1 = np.array(feature_1)
    feature_2 = np.array(feature_2)
    dist = np.sqrt(np.sum(np.square(feature_1 - feature_2)))
    return dist

path_features_known_csv = "D:/No1WorkSpace/JupyterNotebook/feature/features_all.csv"
csv_rd = pd.read_csv(path_features_known_csv, header=None)
features_known_arr = []
for i in range(csv_rd.shape[0]):
    features_someone_arr = []
    for j in range(len(csv_rd.loc[i, :])):
        features_someone_arr.append(csv_rd.loc[i, :][j])
    features_known_arr.append(features_someone_arr)
print("Faces in Database:", len(features_known_arr))

detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('D:/No1WorkSpace/JupyterNotebook/model/shape_predictor_68_face_landmarks.dat')
cap = cv2.VideoCapture(0)
cap.set(3, 480)
while cap.isOpened():
    flag, img_rd = cap.read()
    kk = cv2.waitKey(1)
    img_gray = cv2.cvtColor(img_rd, cv2.COLOR_RGB2GRAY)
    faces = detector(img_gray, 0)
    font = cv2.FONT_HERSHEY_COMPLEX
    pos_namelist = []
    name_namelist = []
    if kk == ord('q'):
        break
    else:
        if len(faces) != 0:
            features_cap_arr = []
            for i, d in enumerate(faces):
                shape = predictor(img_rd, d)
                features_cap_arr.append(facerec.compute_face_descriptor(img_rd, shape))
            for k in range(len(faces)):
                name_namelist.append('unknown')
                pos_namelist.append(tuple([faces[k].left(), int(faces[k].bottom() + (faces[k].bottom() - faces[k].top())/4)]))
                e_distance_list = []
                for i in range(len(features_known_arr)):
                    if str(features_known_arr[i][0]) != '0.0':
                        e_distance_tmp = return_euclidean_distance(features_cap_arr[k], features_known_arr[i])
                        e_distance_list.append(e_distance_tmp)
                    else:
                        e_distance_list.append(999999999)
                similar_person_num = e_distance_list.index(min(e_distance_list))
                if min(e_distance_list) < 0.4:
                    folder_name = 'D:/No1WorkSpace/JupyterNotebook/Facetrainset/'
                    file_names = os.listdir(folder_name)
                    key_id = 1
                    for name in file_names:
                        if similar_person_num + 1 == key_id:
                            name_namelist[k] = name[1:]
                        key_id += 1
                    # Save recognized face image
                    x1 = faces[k].top() if faces[k].top() > 0 else 0
                    y1 = faces[k].bottom() if faces[k].bottom() > 0 else 0
                    x2 = faces[k].left() if faces[k].left() > 0 else 0
                    y2 = faces[k].right() if faces[k].right() > 0 else 0
                    face = img_rd[x1:y1, x2:y2]
                    face = cv2.resize(face, (64, 64))
                    now_time = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime())
                    save_path = f"D:/No1WorkSpace/JupyterNotebook/KnownFacetrainset/{now_time}{name_namelist[k]}.jpg"
                    cv2.imwrite(save_path, face)
                else:
                    # Save unknown face image
                    x1 = faces[k].top() if faces[k].top() > 0 else 0
                    y1 = faces[k].bottom() if faces[k].bottom() > 0 else 0
                    x2 = faces[k].left() if faces[k].left() > 0 else 0
                    y2 = faces[k].right() if faces[k].right() > 0 else 0
                    face = img_rd[x1:y1, x2:y2]
                    face = cv2.resize(face, (64, 64))
                    now_time = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime())
                    save_path = f"D:/No1WorkSpace/JupyterNotebook/UnKnownFacetrainset/{now_time}unknown.jpg"
                    cv2.imwrite(save_path, face)
                # Draw rectangle and name
                cv2.rectangle(img_rd, (faces[k].left(), faces[k].top()), (faces[k].right(), faces[k].bottom()), (0, 255, 255), 2)
                cv2.putText(img_rd, name_namelist[k], pos_namelist[k], font, 0.8, (0, 255, 255), 1, cv2.LINE_AA)
            cv2.putText(img_rd, "Face Recognition", (20, 40), font, 1, (0, 0, 255), 1, cv2.LINE_AA)
            cv2.putText(img_rd, "Visitors: " + str(len(faces)), (20, 100), font, 1, (0, 0, 255), 1, cv2.LINE_AA)
            cv2.imshow('camera', img_rd)
        else:
            cv2.putText(img_rd, "Face Recognition", (20, 40), font, 1, (0, 0, 255), 1, cv2.LINE_AA)
            cv2.imshow('camera', img_rd)
cap.release()
cv2.destroyAllWindows()
If you run the code directly, using Chinese directory names may cause garbled output.

Running effect:

In the screenshot, two known faces are correctly identified, while an unknown face is labeled as "unknown".

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Real-Timeface recognitiondlibeuclidean distance
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.