Back to projects

Case study / 07

Focal

Training a face detector from raw webcam data to real-time localization.

Focal builds face detection end to end: collecting and annotating webcam images, augmenting a small dataset, training a shared CNN backbone to jointly predict face presence and bounding-box coordinates, then running real-time inference through OpenCV.

  • TensorFlow
  • VGG16
  • OpenCV
  • Albumentations
  • LabelMe
  • Bounding Boxes
Custom datasetDual-head modelOpenCV inference

Custom data

Collect and annotate the training set instead of wrapping a packaged face detector.

Shared backbone

One VGG16 feature extractor supports classification and localization heads.

Joint objectives

Classification and bounding-box regression are optimized in one training step.

Real-time inference

One forward pass returns face presence and normalized box coordinates.

Pipeline

Detection pipelineOwned end to end, from raw frame to rendered box
01Webcam captureOpenCV frames
02LabelMemanual boxes
03Train / test / valmanual split
04Albumentations60× expansion
05TF data pipelineimages + labels
06
ImageNet-pretrained VGG16shared feature backbone
07AClassification headface present?
07BBBox regression headx1 · y1 · x2 · y2
08Custom joint losslocalization + 0.5 × classification
09OpenCV inferencethreshold-gated render

Engineering decisions

DecisionWhyTradeoff
Shared backbone with separate headsClassification and localization can reuse the same learned image features.Both objectives influence one shared representation.
Normalized bounding-box coordinatesRegression stays independent of image resolution and composes with bbox-aware augmentation.Coordinates must return to pixel space at inference.
Custom training loopThe model explicitly combines localization and classification losses and controls each update.More code and responsibility than default Keras multi-output training.

Under the hood

Data / annotation

  • Approximately 90 custom webcam captures
  • LabelMe bounding-box JSON
  • Manual train / test / validation split
  • 60 augmented variants per source image

Model

  • ImageNet-pretrained VGG16 backbone
  • Sigmoid face classifier
  • Four-value sigmoid box regressor
  • Coordinates normalized to [0, 1]

Training / inference

  • Custom train_step and test_step
  • Localization + 0.5 × classification loss
  • OpenCV webcam input
  • 0.5 threshold gates box rendering

Technical deep dives

Deep dive A

One forward pass. Two outputs.

The VGG16 backbone computes one shared feature representation. Independent dense heads then answer two different questions: whether a face is present and where its normalized bounds lie.

Shared features, independently shaped outputs

Deep dive B

Data becomes a detector

Bounding-box aware transforms keep labels aligned with altered images. If a crop removes the face, the pipeline writes a class-0 example and a zero box. The notebook saves a model locally; that generated artifact is not committed.

*Generated locally during the notebook run

Verified notebook behavior

10 epochs · total loss 0.35 → 0.002

Training and validation loss converge in the included run, with a transient validation spike around epoch 7. The repository does not report general detection accuracy.

Reproducibility + evaluation limits

  • Small, single-subject dataset from one environment.
  • Exactly one box output creates a one-face assumption.
  • No IoU or mAP evaluation against held-out ground truth.
  • Annotation and train/test/validation splitting are manual.
  • VGG16 is relatively heavy for real-time inference.
  • The trained model and original live video are no longer available in the repository.