or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-processing.mdface-analysis.mdfeature-detection.mdindex.mdutilities.mdvideo-processing.md

face-analysis.mddocs/

0

# Face Analysis

1

2

Facial landmark processing tools and face alignment functionality for dlib-based face detection workflows. These utilities bridge dlib's face detection capabilities with OpenCV's image processing functions.

3

4

## Capabilities

5

6

### Face Alignment

7

8

Automatic face alignment based on eye positions, supporting both 68-point and 5-point facial landmark detectors.

9

10

```python { .api }

11

class FaceAligner:

12

def __init__(self, predictor, desiredLeftEye=(0.35, 0.35), desiredFaceWidth=256, desiredFaceHeight=None):

13

"""

14

Face alignment based on eye positions.

15

16

Args:

17

predictor: dlib facial landmark predictor object

18

desiredLeftEye (tuple): Desired left eye position as ratio (x, y) (default: (0.35, 0.35))

19

desiredFaceWidth (int): Desired output face width in pixels (default: 256)

20

desiredFaceHeight (int, optional): Desired output face height in pixels (default: uses desiredFaceWidth)

21

"""

22

23

def align(self, image, gray, rect):

24

"""

25

Align and crop face based on eye positions.

26

27

Args:

28

image (np.ndarray): Color input image

29

gray (np.ndarray): Grayscale version of input image

30

rect: dlib rectangle object representing face bounding box

31

32

Returns:

33

np.ndarray: Aligned and cropped face image

34

35

Note:

36

Automatically detects whether using 68-point or 5-point landmark detector.

37

Calculates rotation angle and scale based on eye positions.

38

Applies affine transformation to align eyes horizontally.

39

"""

40

```

41

42

**Usage Example:**

43

```python

44

import cv2

45

import dlib

46

from imutils.face_utils import FaceAligner

47

48

# Initialize dlib face detector and landmark predictor

49

detector = dlib.get_frontal_face_detector()

50

predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")

51

52

# Initialize face aligner

53

fa = FaceAligner(predictor, desiredFaceWidth=256)

54

55

# Load image

56

image = cv2.imread("face.jpg")

57

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

58

59

# Detect faces

60

faces = detector(gray, 1)

61

62

for face in faces:

63

# Align face

64

aligned_face = fa.align(image, gray, face)

65

cv2.imshow("Aligned Face", aligned_face)

66

cv2.waitKey(0)

67

68

cv2.destroyAllWindows()

69

```

70

71

### Coordinate Conversion Utilities

72

73

Functions for converting between dlib and OpenCV coordinate formats.

74

75

```python { .api }

76

def rect_to_bb(rect):

77

"""

78

Convert dlib rectangle to OpenCV bounding box format.

79

80

Args:

81

rect: dlib rectangle object

82

83

Returns:

84

tuple: (x, y, w, h) bounding box coordinates in OpenCV format

85

"""

86

87

def shape_to_np(shape, dtype="int"):

88

"""

89

Convert dlib shape object to numpy array of coordinates.

90

91

Args:

92

shape: dlib shape object containing facial landmarks

93

dtype (str): NumPy data type (default: "int")

94

95

Returns:

96

np.ndarray: Array of (x, y) coordinates with shape (num_points, 2)

97

"""

98

```

99

100

**Usage Example:**

101

```python

102

import cv2

103

import dlib

104

from imutils.face_utils import rect_to_bb, shape_to_np

105

106

# Initialize detector and predictor

107

detector = dlib.get_frontal_face_detector()

108

predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")

109

110

image = cv2.imread("face.jpg")

111

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

112

113

# Detect faces

114

faces = detector(gray, 1)

115

116

for face in faces:

117

# Convert dlib rectangle to OpenCV bounding box

118

(x, y, w, h) = rect_to_bb(face)

119

cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

120

121

# Get facial landmarks

122

shape = predictor(gray, face)

123

landmarks = shape_to_np(shape)

124

125

# Draw landmarks

126

for (x, y) in landmarks:

127

cv2.circle(image, (x, y), 2, (0, 0, 255), -1)

128

129

cv2.imshow("Face Detection", image)

130

cv2.waitKey(0)

131

cv2.destroyAllWindows()

132

```

133

134

### Facial Landmark Visualization

135

136

Visualization utilities for drawing facial landmark regions on images.

137

138

```python { .api }

139

def visualize_facial_landmarks(image, shape, colors=None, alpha=0.75):

140

"""

141

Draw facial landmark regions on image.

142

143

Args:

144

image (np.ndarray): Input image (OpenCV format)

145

shape (np.ndarray): Array of facial landmark coordinates

146

colors (list, optional): List of BGR color tuples for each region

147

alpha (float): Transparency level for overlay (default: 0.75)

148

149

Returns:

150

np.ndarray: Output image with facial landmarks visualized

151

152

Note:

153

Automatically determines landmark format (68-point or 5-point).

154

Uses predefined colors if colors parameter is not provided.

155

Draws polygons for regions like jaw, eyebrows, eyes, nose, mouth.

156

"""

157

```

158

159

**Usage Example:**

160

```python

161

import cv2

162

import dlib

163

from imutils.face_utils import shape_to_np, visualize_facial_landmarks

164

165

# Initialize detector and predictor

166

detector = dlib.get_frontal_face_detector()

167

predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")

168

169

image = cv2.imread("face.jpg")

170

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

171

172

# Detect faces

173

faces = detector(gray, 1)

174

175

for face in faces:

176

# Get facial landmarks

177

shape = predictor(gray, face)

178

landmarks = shape_to_np(shape)

179

180

# Visualize landmarks

181

output = visualize_facial_landmarks(image, landmarks, alpha=0.6)

182

cv2.imshow("Facial Landmarks", output)

183

cv2.waitKey(0)

184

185

cv2.destroyAllWindows()

186

```

187

188

### Facial Landmark Constants

189

190

Pre-defined mappings for facial landmark regions to array indices.

191

192

```python { .api }

193

# For 68-point facial landmark detector

194

FACIAL_LANDMARKS_68_IDXS = {

195

"mouth": (48, 68),

196

"inner_mouth": (60, 68),

197

"right_eyebrow": (17, 22),

198

"left_eyebrow": (22, 27),

199

"right_eye": (36, 42),

200

"left_eye": (42, 48),

201

"nose": (27, 36),

202

"jaw": (0, 17)

203

}

204

205

# For 5-point facial landmark detector

206

FACIAL_LANDMARKS_5_IDXS = {

207

"right_eye": (0, 1),

208

"left_eye": (1, 2),

209

"nose": (2, 5)

210

}

211

212

# Legacy alias

213

FACIAL_LANDMARKS_IDXS = FACIAL_LANDMARKS_68_IDXS

214

```

215

216

**Usage Example:**

217

```python

218

import cv2

219

import dlib

220

from imutils.face_utils import (shape_to_np, FACIAL_LANDMARKS_68_IDXS,

221

visualize_facial_landmarks)

222

223

# Initialize detector and predictor

224

detector = dlib.get_frontal_face_detector()

225

predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")

226

227

image = cv2.imread("face.jpg")

228

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

229

230

faces = detector(gray, 1)

231

232

for face in faces:

233

shape = predictor(gray, face)

234

landmarks = shape_to_np(shape)

235

236

# Extract specific facial regions

237

(j, k) = FACIAL_LANDMARKS_68_IDXS["left_eye"]

238

left_eye = landmarks[j:k]

239

240

(j, k) = FACIAL_LANDMARKS_68_IDXS["right_eye"]

241

right_eye = landmarks[j:k]

242

243

(j, k) = FACIAL_LANDMARKS_68_IDXS["mouth"]

244

mouth = landmarks[j:k]

245

246

# Draw specific regions

247

for (x, y) in left_eye:

248

cv2.circle(image, (x, y), 2, (0, 255, 0), -1) # Green for left eye

249

250

for (x, y) in right_eye:

251

cv2.circle(image, (x, y), 2, (255, 0, 0), -1) # Blue for right eye

252

253

for (x, y) in mouth:

254

cv2.circle(image, (x, y), 2, (0, 0, 255), -1) # Red for mouth

255

256

cv2.imshow("Facial Regions", image)

257

cv2.waitKey(0)

258

cv2.destroyAllWindows()

259

```

260

261

### Complete Face Processing Pipeline

262

263

Here's a comprehensive example combining face detection, alignment, and landmark visualization:

264

265

```python

266

import cv2

267

import dlib

268

import numpy as np

269

from imutils.face_utils import (FaceAligner, rect_to_bb, shape_to_np,

270

visualize_facial_landmarks, FACIAL_LANDMARKS_68_IDXS)

271

272

def process_faces_in_image(image_path, predictor_path):

273

# Initialize dlib components

274

detector = dlib.get_frontal_face_detector()

275

predictor = dlib.shape_predictor(predictor_path)

276

fa = FaceAligner(predictor, desiredFaceWidth=256)

277

278

# Load image

279

image = cv2.imread(image_path)

280

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

281

original = image.copy()

282

283

# Detect faces

284

faces = detector(gray, 1)

285

print(f"Found {len(faces)} faces")

286

287

aligned_faces = []

288

289

for (i, face) in enumerate(faces):

290

# Convert dlib rectangle to bounding box

291

(x, y, w, h) = rect_to_bb(face)

292

cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

293

cv2.putText(image, f"Face {i+1}", (x - 10, y - 10),

294

cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)

295

296

# Get facial landmarks

297

shape = predictor(gray, face)

298

landmarks = shape_to_np(shape)

299

300

# Visualize landmarks

301

landmark_image = visualize_facial_landmarks(original.copy(), landmarks)

302

303

# Align face

304

aligned_face = fa.align(original, gray, face)

305

aligned_faces.append(aligned_face)

306

307

# Show results for this face

308

cv2.imshow(f"Face {i+1} - Landmarks", landmark_image)

309

cv2.imshow(f"Face {i+1} - Aligned", aligned_face)

310

311

# Show original with bounding boxes

312

cv2.imshow("Face Detection", image)

313

314

# Create montage of aligned faces if multiple faces found

315

if len(aligned_faces) > 1:

316

# Resize all faces to same size

317

aligned_resized = [cv2.resize(face, (256, 256)) for face in aligned_faces]

318

319

# Create horizontal montage

320

montage = np.hstack(aligned_resized)

321

cv2.imshow("Aligned Faces Montage", montage)

322

323

cv2.waitKey(0)

324

cv2.destroyAllWindows()

325

326

return aligned_faces

327

328

# Usage

329

if __name__ == "__main__":

330

aligned_faces = process_faces_in_image(

331

"group_photo.jpg",

332

"shape_predictor_68_face_landmarks.dat"

333

)

334

print(f"Processed and aligned {len(aligned_faces)} faces")

335

```

336

337

### Custom Face Processing

338

339

Example of custom face processing with eye aspect ratio calculation:

340

341

```python

342

import cv2

343

import dlib

344

import numpy as np

345

from imutils.face_utils import shape_to_np, FACIAL_LANDMARKS_68_IDXS

346

347

def eye_aspect_ratio(eye):

348

"""Calculate eye aspect ratio for blink detection."""

349

# Vertical eye landmarks

350

A = np.linalg.norm(eye[1] - eye[5])

351

B = np.linalg.norm(eye[2] - eye[4])

352

353

# Horizontal eye landmark

354

C = np.linalg.norm(eye[0] - eye[3])

355

356

# Eye aspect ratio

357

ear = (A + B) / (2.0 * C)

358

return ear

359

360

def detect_blinks(image_path, predictor_path):

361

detector = dlib.get_frontal_face_detector()

362

predictor = dlib.shape_predictor(predictor_path)

363

364

# Eye aspect ratio threshold

365

EAR_THRESHOLD = 0.3

366

367

image = cv2.imread(image_path)

368

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

369

370

faces = detector(gray, 1)

371

372

for face in faces:

373

landmarks = shape_to_np(predictor(gray, face))

374

375

# Extract eye coordinates

376

(lStart, lEnd) = FACIAL_LANDMARKS_68_IDXS["left_eye"]

377

(rStart, rEnd) = FACIAL_LANDMARKS_68_IDXS["right_eye"]

378

379

leftEye = landmarks[lStart:lEnd]

380

rightEye = landmarks[rStart:rEnd]

381

382

# Calculate eye aspect ratios

383

leftEAR = eye_aspect_ratio(leftEye)

384

rightEAR = eye_aspect_ratio(rightEye)

385

ear = (leftEAR + rightEAR) / 2.0

386

387

# Check for blink

388

if ear < EAR_THRESHOLD:

389

cv2.putText(image, "BLINK DETECTED", (10, 30),

390

cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)

391

392

# Draw eye contours

393

cv2.drawContours(image, [cv2.convexHull(leftEye)], -1, (0, 255, 0), 1)

394

cv2.drawContours(image, [cv2.convexHull(rightEye)], -1, (0, 255, 0), 1)

395

396

# Display EAR value

397

cv2.putText(image, f"EAR: {ear:.2f}", (300, 30),

398

cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2)

399

400

cv2.imshow("Blink Detection", image)

401

cv2.waitKey(0)

402

cv2.destroyAllWindows()

403

404

# Usage

405

detect_blinks("face.jpg", "shape_predictor_68_face_landmarks.dat")

406

```