Real-Time Face Recognition Systems with OpenCV and Deep Learning
Published on December 10, 2025
Face recognition has evolved from a research curiosity to a practical technology used in security, attendance systems, and photo organization. In this post, I'll walk through building a real-time face recognition system that processes 200+ students per session—achieving an 80% reduction in attendance processing time.
System Architecture
Our system uses a three-stage pipeline:
- Face Detection: Locate faces in video frames
- Face Encoding: Convert faces to numerical representations
- Face Recognition: Match encodings against a database
1. Face Detection with Haar Cascades
import cv2
import numpy as np
class FaceDetector:
def __init__(self):
# Load pre-trained Haar cascade
self.face_cascade = cv2.CascadeClassifier(
cv2.data.haarcascades + 'haarcascade_frontalface_default.xml'
)
def detect_faces(self, frame):
"""Detect faces in a frame."""
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = self.face_cascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30)
)
return faces # Returns (x, y, w, h) for each face
# For better accuracy, use dlib's HOG or CNN detector
import dlib
class DlibFaceDetector:
def __init__(self, use_cnn=False):
if use_cnn:
self.detector = dlib.cnn_face_detection_model_v1(
'mmod_human_face_detector.dat'
)
else:
self.detector = dlib.get_frontal_face_detector()
def detect_faces(self, frame):
rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
return self.detector(rgb, 1)
2. Face Encoding with Deep Learning
import face_recognition
class FaceEncoder:
def __init__(self):
self.known_encodings = {}
self.known_names = []
def encode_face(self, image, face_location=None):
"""Generate 128-dimensional face encoding."""
rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
if face_location:
encodings = face_recognition.face_encodings(
rgb,
known_face_locations=[face_location]
)
else:
encodings = face_recognition.face_encodings(rgb)
return encodings[0] if encodings else None
def register_face(self, name, images):
"""Register a person with multiple face images."""
encodings = []
for img in images:
encoding = self.encode_face(img)
if encoding is not None:
encodings.append(encoding)
if encodings:
# Store average encoding for robustness
self.known_encodings[name] = np.mean(encodings, axis=0)
self.known_names.append(name)
return True
return False
3. Face Recognition and Matching
class FaceRecognizer:
def __init__(self, encoder, threshold=0.6):
self.encoder = encoder
self.threshold = threshold
def recognize(self, frame, face_locations):
"""Recognize faces in frame."""
results = []
rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# Get encodings for detected faces
encodings = face_recognition.face_encodings(rgb, face_locations)
for encoding, location in zip(encodings, face_locations):
# Compare against known faces
distances = face_recognition.face_distance(
list(self.encoder.known_encodings.values()),
encoding
)
if len(distances) > 0:
min_idx = np.argmin(distances)
min_distance = distances[min_idx]
if min_distance < self.threshold:
name = self.encoder.known_names[min_idx]
confidence = 1 - min_distance
else:
name = "Unknown"
confidence = 0
else:
name = "Unknown"
confidence = 0
results.append({
'name': name,
'confidence': confidence,
'location': location
})
return results
4. Complete Attendance System
import datetime
import csv
class AttendanceSystem:
def __init__(self, encoder_path='encodings.pkl'):
self.detector = FaceDetector()
self.encoder = FaceEncoder()
self.recognizer = FaceRecognizer(self.encoder)
self.attendance_log = {}
# Load pre-computed encodings
self.load_encodings(encoder_path)
def mark_attendance(self, name):
"""Mark attendance for recognized person."""
if name not in self.attendance_log:
timestamp = datetime.datetime.now()
self.attendance_log[name] = timestamp
print(f"✓ {name} marked present at {timestamp.strftime('%H:%M:%S')}")
return True
return False
def run_camera(self):
"""Run real-time recognition from camera."""
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if not ret:
break
# Detect faces
face_locations = self.detector.detect_faces(frame)
# Recognize faces
results = self.recognizer.recognize(frame, face_locations)
# Draw results and mark attendance
for result in results:
name = result['name']
confidence = result['confidence']
x, y, w, h = result['location']
# Mark attendance
if name != "Unknown":
self.mark_attendance(name)
# Draw bounding box
color = (0, 255, 0) if name != "Unknown" else (0, 0, 255)
cv2.rectangle(frame, (x, y), (x+w, y+h), color, 2)
cv2.putText(
frame,
f"{name} ({confidence:.2f})",
(x, y-10),
cv2.FONT_HERSHEY_SIMPLEX,
0.5, color, 2
)
cv2.imshow('Attendance System', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
def export_attendance(self, filename='attendance.csv'):
"""Export attendance log to CSV."""
with open(filename, 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(['Name', 'Timestamp'])
for name, timestamp in self.attendance_log.items():
writer.writerow([name, timestamp.isoformat()])
Performance Optimization
For real-time performance with 200+ students:
- Frame skipping: Process every 3rd frame
- Face tracking: Use tracking between detections
- Batch processing: Encode multiple faces simultaneously
- GPU acceleration: Use CUDA-enabled dlib
Results
Our deployed system achieved:
- Recognition accuracy: 97.3%
- Processing speed: 15 FPS on standard laptop
- Time savings: 80% reduction vs. manual attendance
Related Project: Automated Face Recognition
Attendance System on GitHub