Skip to content

Latest commit

 

History

History
136 lines (97 loc) · 4.85 KB

File metadata and controls

136 lines (97 loc) · 4.85 KB

Age & Gender Detection

Estimates age and gender from any face in a photo, or from a live camera capture. Full-stack: a Python vision backend, and a plain HTML/CSS/JS frontend.

Python · Flask · OpenCV · TensorFlow · JavaScript


How it works

Three stages, in order:

1 · DetectYuNet locates every face in the frame and returns five landmarks for each (eyes, nose, mouth corners). It ships inside OpenCV, weighs 340 KB, and runs in single-digit milliseconds on CPU.

2 · Align — each face is rotated so the eye axis is horizontal, then cropped with a 20% margin and resized to 224×224. Aligning first means a tilted head doesn't look like a different kind of image to the classifier.

3 · Classify — a MobileNetV2 backbone, fine-tuned on UTKFace, with two output heads: one regressing age as a number, one classifying gender.

Why YuNet and not RetinaFace or MTCNN

RetinaFace is more accurate on hard cases — small, occluded, or extreme-angle faces — but runs at roughly one frame per second on CPU, which rules out live capture. MTCNN is slower than YuNet and less accurate. YuNet lands within a few points of RetinaFace-MobileNet on standard benchmarks while running around 100× faster, needs no extra dependency, and is small enough to commit to the repository.

For faces roughly facing a camera — the entire use case here — the accuracy difference does not show. Accuracy you cannot run in real time is not accuracy you have.

Train and inference crops must match

The training set is re-cropped with the same detector the app uses at inference, with the same margin. UTKFace ships pre-cropped, but by a different detector with different framing — training on those and predicting on YuNet crops would mean the model sees one distribution while learning and another in production. Accuracy drops, and nothing errors, so it is easy to miss.


Running it

git clone https://github.com/Charan1845/Age-and-Gender-Recognition.git
cd Age-and-Gender-Recognition

python -m venv .venv
.venv\Scripts\activate        # Windows
# source .venv/bin/activate   # macOS / Linux

pip install -r requirements.txt
python backend/app.py

Then open http://127.0.0.1:5000.

Requires Python 3.10–3.12 (TensorFlow has no build for 3.13+ yet).

The YuNet detector downloads itself on first run. The trained classifier is not committed — see below. Without it the app still runs and boxes faces, showing a banner to say classification is unavailable.

Training the classifier

Open notebooks/train_age_gender.ipynb in Google Colab, set the runtime to a T4 GPU, and run it top to bottom. It pulls UTKFace from Kaggle, re-crops every face with YuNet, fine-tunes MobileNetV2 in two stages, and exports the model.

Put the downloaded age_gender_model.keras in models/ and restart the server. No code changes — the backend looks for it on start-up.

Training is two-stage on purpose: the backbone is frozen while the new heads learn, then the top 40 layers are unfrozen at a 100× lower learning rate. Fine-tuning everything at full rate from the start destroys the pretrained ImageNet features.


Structure

backend/
  app.py       Flask routes, request handling, JSON responses
  model.py     detection, alignment, cropping, classification
frontend/
  index.html   markup only
  css/
  js/
    api.js     the only file that talks HTTP
    camera.js  getUserMedia, capture, permission errors
    ui.js      DOM rendering
    main.js    wiring
notebooks/
  train_age_gender.ipynb
models/        YuNet + trained classifier (gitignored)
data/          UTKFace (gitignored)

API

Method Route Purpose
GET / the app
GET /api/health whether a classifier is loaded
POST /api/predict image in — faces, predictions, annotated image out

/api/predict accepts either a multipart file upload or JSON with a base64 data URI, so the upload and camera paths share one endpoint.


Notes and limitations

The camera is read in the browser, not on the server. cv2.VideoCapture(0) reads the machine running the code — fine on a laptop, useless once hosted, since a server has no webcam. getUserMedia works in both.

Older faces are under-predicted. UTKFace skews young, so the regression head hedges toward the middle of the distribution: a 60-year-old may come back as mid-forties. Predictions are also clamped to 0–100, since a linear output head can otherwise return negative ages for faces unlike anything it trained on.

Infants are the weakest case for gender, which is expected — the features the model relies on are not developed yet.


Built with

Python · Flask · OpenCV · TensorFlow · MobileNetV2 · YuNet · UTKFace