0
# Face Detection and Recognition
1
2
Comprehensive face detection, landmark prediction, and face recognition capabilities using state-of-the-art deep learning models and traditional computer vision approaches.
3
4
## Capabilities
5
6
### Face Detection
7
8
Built-in face detection using HOG-based and CNN-based approaches for robust face localization in images.
9
10
```python { .api }
11
def get_frontal_face_detector():
12
"""
13
Get default HOG-based frontal face detector.
14
15
Returns:
16
Face detector object for finding frontal faces
17
"""
18
19
class cnn_face_detection_model_v1:
20
"""CNN-based face detector for improved accuracy."""
21
22
def __init__(self, model_filename: str):
23
"""
24
Initialize CNN face detector.
25
26
Args:
27
model_filename: Path to CNN face detection model file
28
"""
29
30
def __call__(self, img, upsample_num_times: int = 0):
31
"""
32
Detect faces in image using CNN.
33
34
Args:
35
img: Input image
36
upsample_num_times: Number of times to upsample image for detection
37
38
Returns:
39
List of face detections with confidence scores
40
"""
41
42
class mmod_rectangle:
43
"""Face detection result with confidence score."""
44
45
@property
46
def rect(self) -> rectangle:
47
"""Bounding rectangle of detected face."""
48
49
@property
50
def confidence(self) -> float:
51
"""Detection confidence score."""
52
```
53
54
**Usage Example:**
55
```python
56
import dlib
57
import cv2
58
59
# Load image
60
img = cv2.imread("group_photo.jpg")
61
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
62
63
# HOG-based face detection
64
detector = dlib.get_frontal_face_detector()
65
faces = detector(gray)
66
67
print(f"Found {len(faces)} faces")
68
for i, face in enumerate(faces):
69
print(f"Face {i}: {face}")
70
71
# CNN-based face detection (requires model file)
72
cnn_detector = dlib.cnn_face_detection_model_v1("mmod_human_face_detector.dat")
73
cnn_faces = cnn_detector(img, upsample_num_times=1)
74
75
for detection in cnn_faces:
76
face_rect = detection.rect
77
confidence = detection.confidence
78
print(f"CNN face: {face_rect}, confidence: {confidence}")
79
```
80
81
### Facial Landmark Detection
82
83
Precise facial landmark localization for face alignment and feature extraction.
84
85
```python { .api }
86
class shape_predictor:
87
"""Facial landmark detector."""
88
89
def __init__(self, predictor_path: str):
90
"""
91
Initialize shape predictor.
92
93
Args:
94
predictor_path: Path to trained shape predictor model
95
"""
96
97
def __call__(self, img, face_rect: rectangle):
98
"""
99
Predict facial landmarks for detected face.
100
101
Args:
102
img: Input image
103
face_rect: Rectangle containing detected face
104
105
Returns:
106
Shape object containing facial landmark points
107
"""
108
109
class full_object_detection:
110
"""Facial landmarks representation."""
111
112
def num_parts(self) -> int:
113
"""Get number of landmark points."""
114
115
def part(self, index: int) -> point:
116
"""Get specific landmark point by index."""
117
118
@property
119
def rect(self) -> rectangle:
120
"""Bounding rectangle of the detection."""
121
122
class full_object_detections:
123
"""Array of full_object_detection objects."""
124
125
def clear(self):
126
"""Remove all detections."""
127
128
def resize(self, size: int):
129
"""Resize container."""
130
131
def extend(self, detection_list: list):
132
"""Add detections from list."""
133
```
134
135
**Usage Example:**
136
```python
137
import dlib
138
import cv2
139
140
# Load image and detect faces
141
img = cv2.imread("face.jpg")
142
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
143
144
detector = dlib.get_frontal_face_detector()
145
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
146
147
faces = detector(gray)
148
149
for face in faces:
150
# Get facial landmarks
151
landmarks = predictor(gray, face)
152
153
print(f"Found {landmarks.num_parts()} landmarks")
154
155
# Access specific landmarks
156
nose_tip = landmarks.part(30) # Nose tip
157
left_eye = landmarks.part(36) # Left eye corner
158
right_eye = landmarks.part(45) # Right eye corner
159
160
print(f"Nose tip: {nose_tip}")
161
print(f"Eyes: {left_eye}, {right_eye}")
162
163
# Draw landmarks
164
for i in range(landmarks.num_parts()):
165
point = landmarks.part(i)
166
cv2.circle(img, (point.x, point.y), 2, (0, 255, 0), -1)
167
168
cv2.imshow("Landmarks", img)
169
cv2.waitKey(0)
170
```
171
172
### Face Recognition
173
174
Deep learning-based face recognition for generating face encodings and computing face similarity.
175
176
```python { .api }
177
class face_recognition_model_v1:
178
"""Face recognition neural network."""
179
180
def __init__(self, model_filename: str):
181
"""
182
Initialize face recognition model.
183
184
Args:
185
model_filename: Path to face recognition model file
186
"""
187
188
def compute_face_descriptor(
189
self,
190
img,
191
face: full_object_detection,
192
num_jitters: int = 0,
193
padding: float = 0.25
194
):
195
"""
196
Compute face descriptor from aligned face.
197
198
Args:
199
img: Input image
200
face: Facial landmarks from shape predictor
201
num_jitters: Number of random jitters for robust encoding
202
padding: Padding around face for extraction
203
204
Returns:
205
128-dimensional face descriptor vector
206
"""
207
208
def compute_face_descriptor_from_aligned_image(
209
self,
210
aligned_img,
211
num_jitters: int = 0
212
):
213
"""
214
Compute face descriptor from pre-aligned 150x150 face image.
215
216
Args:
217
aligned_img: Pre-aligned face image (150x150 pixels)
218
num_jitters: Number of random jitters for robust encoding
219
220
Returns:
221
128-dimensional face descriptor vector
222
"""
223
224
def compute_face_descriptors(
225
self,
226
img,
227
faces: full_object_detections,
228
num_jitters: int = 0,
229
padding: float = 0.25
230
):
231
"""
232
Compute face descriptors for multiple faces in single image.
233
234
Args:
235
img: Input image
236
faces: Multiple facial landmarks
237
num_jitters: Number of random jitters
238
padding: Padding around faces
239
240
Returns:
241
List of 128-dimensional face descriptor vectors
242
"""
243
244
def batch_compute_face_descriptors(
245
self,
246
batch_imgs: list,
247
batch_faces: list,
248
num_jitters: int = 0,
249
padding: float = 0.25
250
):
251
"""
252
Batch processing of face descriptors for multiple images.
253
254
Args:
255
batch_imgs: List of input images
256
batch_faces: List of lists of facial landmarks (one list per image)
257
num_jitters: Number of random jitters
258
padding: Padding around faces
259
260
Returns:
261
List of lists of face descriptor vectors (one list per image)
262
"""
263
264
def batch_compute_face_descriptors_from_aligned_images(
265
self,
266
batch_aligned_imgs: list,
267
num_jitters: int = 0
268
):
269
"""
270
Batch processing of face descriptors from pre-aligned images.
271
272
Args:
273
batch_aligned_imgs: List of pre-aligned face images (150x150 each)
274
num_jitters: Number of random jitters
275
276
Returns:
277
List of 128-dimensional face descriptor vectors
278
"""
279
```
280
281
**Usage Example:**
282
```python
283
import dlib
284
import cv2
285
import numpy as np
286
287
# Initialize models
288
detector = dlib.get_frontal_face_detector()
289
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
290
face_rec = dlib.face_recognition_model_v1("dlib_face_recognition_resnet_model_v1.dat")
291
292
# Load reference image
293
ref_img = cv2.imread("reference_face.jpg")
294
ref_gray = cv2.cvtColor(ref_img, cv2.COLOR_BGR2GRAY)
295
296
# Get reference face encoding
297
ref_faces = detector(ref_gray)
298
if len(ref_faces) > 0:
299
ref_landmarks = predictor(ref_gray, ref_faces[0])
300
ref_encoding = face_rec.compute_face_descriptor(ref_img, ref_landmarks)
301
302
# Load test image
303
test_img = cv2.imread("test_face.jpg")
304
test_gray = cv2.cvtColor(test_img, cv2.COLOR_BGR2GRAY)
305
306
# Get test face encoding
307
test_faces = detector(test_gray)
308
if len(test_faces) > 0:
309
test_landmarks = predictor(test_gray, test_faces[0])
310
test_encoding = face_rec.compute_face_descriptor(test_img, test_landmarks)
311
312
# Compute similarity (Euclidean distance)
313
distance = np.linalg.norm(np.array(ref_encoding) - np.array(test_encoding))
314
315
# Typically, distance < 0.6 indicates same person
316
if distance < 0.6:
317
print(f"Same person (distance: {distance:.3f})")
318
else:
319
print(f"Different person (distance: {distance:.3f})")
320
```
321
322
### Face Clustering
323
324
Algorithms for grouping faces by identity using unsupervised clustering approaches.
325
326
```python { .api }
327
def chinese_whispers_clustering(descriptors: list, threshold: float) -> list:
328
"""
329
Cluster face descriptors using Chinese Whispers algorithm.
330
331
Args:
332
descriptors: List of face descriptor vectors
333
threshold: Distance threshold for clustering
334
335
Returns:
336
List of cluster labels for each descriptor
337
"""
338
339
def chinese_whispers(edges: list) -> list:
340
"""
341
Direct Chinese Whispers clustering on graph edges.
342
343
Args:
344
edges: List of graph edges (node pairs)
345
346
Returns:
347
List of cluster labels
348
"""
349
350
def bottom_up_clustering(
351
descriptors: list,
352
min_num_clusters: int = 1,
353
max_dist: float = 0.6
354
) -> list:
355
"""
356
Hierarchical bottom-up clustering of face descriptors.
357
358
Args:
359
descriptors: List of face descriptor vectors
360
min_num_clusters: Minimum number of clusters
361
max_dist: Maximum distance for merging clusters
362
363
Returns:
364
List of cluster labels for each descriptor
365
"""
366
```
367
368
**Usage Example:**
369
```python
370
import dlib
371
import cv2
372
import numpy as np
373
from glob import glob
374
375
# Initialize models
376
detector = dlib.get_frontal_face_detector()
377
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
378
face_rec = dlib.face_recognition_model_v1("dlib_face_recognition_resnet_model_v1.dat")
379
380
# Process multiple images to get face descriptors
381
descriptors = []
382
image_files = glob("faces/*.jpg")
383
384
for img_path in image_files:
385
img = cv2.imread(img_path)
386
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
387
388
faces = detector(gray)
389
for face in faces:
390
landmarks = predictor(gray, face)
391
descriptor = face_rec.compute_face_descriptor(img, landmarks)
392
descriptors.append(descriptor)
393
394
# Cluster faces
395
print(f"Clustering {len(descriptors)} face descriptors...")
396
397
# Chinese Whispers clustering
398
cw_labels = dlib.chinese_whispers_clustering(descriptors, threshold=0.5)
399
print(f"Chinese Whispers found {len(set(cw_labels))} clusters")
400
401
# Bottom-up clustering
402
bu_labels = dlib.bottom_up_clustering(descriptors, min_num_clusters=2, max_dist=0.6)
403
print(f"Bottom-up clustering found {len(set(bu_labels))} clusters")
404
405
# Group images by cluster
406
for cluster_id in set(cw_labels):
407
cluster_indices = [i for i, label in enumerate(cw_labels) if label == cluster_id]
408
print(f"Cluster {cluster_id}: {len(cluster_indices)} faces")
409
```
410
411
### Face Chip Extraction
412
413
Utilities for extracting and saving aligned face chips for analysis and recognition.
414
415
```python { .api }
416
def save_face_chip(
417
img,
418
face: full_object_detection,
419
filename: str,
420
size: int = 150,
421
padding: float = 0.25
422
):
423
"""
424
Save aligned face chip to file.
425
426
Args:
427
img: Input image
428
face: Facial landmarks
429
filename: Output filename
430
size: Chip size in pixels
431
padding: Padding around face
432
"""
433
434
def save_face_chips(
435
img,
436
faces: full_object_detections,
437
filename_prefix: str,
438
size: int = 150,
439
padding: float = 0.25
440
):
441
"""
442
Save multiple aligned face chips to files.
443
444
Args:
445
img: Input image
446
faces: Multiple facial landmarks
447
filename_prefix: Prefix for output filenames
448
size: Chip size in pixels
449
padding: Padding around faces
450
"""
451
452
def get_face_chip(
453
img,
454
face: full_object_detection,
455
size: int = 150,
456
padding: float = 0.25
457
):
458
"""
459
Extract aligned face chip as image array.
460
461
Args:
462
img: Input image
463
face: Facial landmarks
464
size: Chip size in pixels
465
padding: Padding around face
466
467
Returns:
468
Aligned face chip image
469
"""
470
471
def get_face_chips(
472
img,
473
faces: full_object_detections,
474
size: int = 150,
475
padding: float = 0.25
476
) -> list:
477
"""
478
Extract multiple aligned face chips.
479
480
Args:
481
img: Input image
482
faces: Multiple facial landmarks
483
size: Chip size in pixels
484
padding: Padding around faces
485
486
Returns:
487
List of aligned face chip images
488
"""
489
```
490
491
**Usage Example:**
492
```python
493
import dlib
494
import cv2
495
496
# Initialize models
497
detector = dlib.get_frontal_face_detector()
498
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
499
500
# Load image
501
img = cv2.imread("group_photo.jpg")
502
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
503
504
# Detect faces and landmarks
505
faces = detector(gray)
506
landmarks_list = dlib.full_object_detections()
507
508
for face in faces:
509
landmarks = predictor(gray, face)
510
landmarks_list.extend([landmarks])
511
512
# Save individual face chips
513
for i, landmarks in enumerate(landmarks_list):
514
dlib.save_face_chip(img, landmarks, f"face_chip_{i}.jpg", size=200, padding=0.3)
515
516
# Extract face chips for processing
517
face_chips = dlib.get_face_chips(img, landmarks_list, size=150)
518
519
print(f"Extracted {len(face_chips)} face chips")
520
for i, chip in enumerate(face_chips):
521
cv2.imshow(f"Face Chip {i}", chip)
522
523
cv2.waitKey(0)
524
cv2.destroyAllWindows()
525
```
526
527
### Shape Predictor Training
528
529
Training custom facial landmark detectors for specialized applications.
530
531
```python { .api }
532
class shape_predictor_training_options:
533
"""Training configuration for shape predictors."""
534
535
tree_depth: int # Depth of regression trees
536
num_trees_per_cascade_level: int # Trees per cascade level
537
nu: float # Regularization parameter
538
oversampling_amount: int # Data augmentation factor
539
feature_pool_size: int # Feature pool size
540
lambda_param: float # Lambda regularization
541
num_test_splits: int # Test splits per node
542
feature_pool_region_padding: float # Padding for feature region
543
verbose: bool # Verbose training output
544
545
def train_shape_predictor(
546
dataset_filename: str,
547
predictor_output_filename: str,
548
options: shape_predictor_training_options
549
):
550
"""
551
Train custom shape predictor from XML dataset.
552
553
Args:
554
dataset_filename: Path to XML training dataset
555
predictor_output_filename: Output path for trained model
556
options: Training configuration options
557
"""
558
```
559
560
**Complete Face Recognition Pipeline Example:**
561
```python
562
import dlib
563
import cv2
564
import numpy as np
565
566
def recognize_faces_in_image(image_path, known_encodings, known_names, tolerance=0.6):
567
"""Complete face recognition pipeline."""
568
569
# Initialize models
570
detector = dlib.get_frontal_face_detector()
571
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
572
face_rec = dlib.face_recognition_model_v1("dlib_face_recognition_resnet_model_v1.dat")
573
574
# Load and process image
575
img = cv2.imread(image_path)
576
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
577
578
# Detect faces
579
faces = detector(gray)
580
581
results = []
582
for face in faces:
583
# Get landmarks and encoding
584
landmarks = predictor(gray, face)
585
encoding = face_rec.compute_face_descriptor(img, landmarks)
586
587
# Compare with known faces
588
distances = [np.linalg.norm(np.array(encoding) - np.array(known_enc))
589
for known_enc in known_encodings]
590
591
if min(distances) < tolerance:
592
name = known_names[distances.index(min(distances))]
593
confidence = 1 - min(distances)
594
else:
595
name = "Unknown"
596
confidence = 0
597
598
results.append({
599
'face_rect': face,
600
'landmarks': landmarks,
601
'name': name,
602
'confidence': confidence
603
})
604
605
return results
606
607
# Usage
608
known_encodings = [] # Load your known face encodings
609
known_names = [] # Corresponding names
610
611
results = recognize_faces_in_image("test.jpg", known_encodings, known_names)
612
for result in results:
613
print(f"Found {result['name']} with confidence {result['confidence']:.3f}")
614
```
615
616
### Batch Processing Examples
617
618
Efficient processing of multiple images and faces using batch operations for improved performance.
619
620
**Batch Face Descriptor Computation:**
621
```python
622
import dlib
623
import cv2
624
import numpy as np
625
626
def batch_face_processing_demo():
627
"""Demonstrate efficient batch processing of face descriptors."""
628
629
# Initialize models
630
detector = dlib.get_frontal_face_detector()
631
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
632
face_rec = dlib.face_recognition_model_v1("dlib_face_recognition_resnet_model_v1.dat")
633
634
# Simulate multiple images with faces
635
image_paths = ["photo1.jpg", "photo2.jpg", "photo3.jpg"]
636
batch_images = []
637
batch_faces_list = []
638
639
# Process each image to detect faces and landmarks
640
for img_path in image_paths:
641
img = dlib.load_rgb_image(img_path)
642
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
643
644
# Detect faces
645
faces = detector(gray)
646
if len(faces) > 0:
647
# Get landmarks for all faces in this image
648
landmarks_list = dlib.full_object_detections()
649
for face in faces:
650
landmarks = predictor(gray, face)
651
landmarks_list.extend([landmarks])
652
653
batch_images.append(img)
654
batch_faces_list.append(landmarks_list)
655
656
# Batch compute face descriptors (much more efficient than individual calls)
657
print(f"Computing descriptors for {len(batch_images)} images...")
658
batch_descriptors = face_rec.batch_compute_face_descriptors(
659
batch_images,
660
batch_faces_list,
661
num_jitters=1,
662
padding=0.25
663
)
664
665
# Process results - batch_descriptors[i] contains descriptors for all faces in image i
666
for i, (img_path, descriptors) in enumerate(zip(image_paths, batch_descriptors)):
667
print(f"{img_path}: {len(descriptors)} faces, {len(descriptors[0])}D descriptors")
668
669
return batch_descriptors
670
671
# Usage
672
descriptors = batch_face_processing_demo()
673
```
674
675
**Batch Processing with Pre-aligned Face Chips:**
676
```python
677
import dlib
678
import numpy as np
679
680
def process_aligned_face_chips():
681
"""Process batch of pre-aligned 150x150 face chips."""
682
683
face_rec = dlib.face_recognition_model_v1("dlib_face_recognition_resnet_model_v1.dat")
684
685
# Load pre-aligned face chips (must be 150x150 pixels)
686
aligned_faces = []
687
for i in range(10):
688
try:
689
face_chip = dlib.load_rgb_image(f"aligned_faces/face_{i:03d}.jpg")
690
# Ensure proper size for aligned processing
691
if face_chip.shape[:2] == (150, 150):
692
aligned_faces.append(face_chip)
693
except:
694
continue
695
696
# Batch process aligned images (fastest method for pre-aligned faces)
697
descriptors = face_rec.batch_compute_face_descriptors_from_aligned_images(
698
aligned_faces,
699
num_jitters=2 # Higher jitters for more robust descriptors
700
)
701
702
print(f"Processed {len(aligned_faces)} pre-aligned faces")
703
print(f"Generated {len(descriptors)} descriptors of {len(descriptors[0])} dimensions each")
704
705
# Example: Compute pairwise similarities
706
similarities = []
707
for i in range(len(descriptors)):
708
for j in range(i+1, len(descriptors)):
709
distance = np.linalg.norm(np.array(descriptors[i]) - np.array(descriptors[j]))
710
similarity = 1.0 / (1.0 + distance)
711
similarities.append((i, j, similarity))
712
713
# Find most similar pair
714
most_similar = max(similarities, key=lambda x: x[2])
715
print(f"Most similar faces: {most_similar[0]} and {most_similar[1]} (similarity: {most_similar[2]:.3f})")
716
717
return descriptors
718
719
# Usage
720
aligned_descriptors = process_aligned_face_chips()
721
```