Skip to content
All projects

Year

2025

Role

System design, API and database layer, deployment

Stack

  • YOLOv5
  • OCR
  • FastAPI
  • PostgreSQL
  • React
  • Docker

Applied computer vision

License Plate Recognition System

A fine-tuned YOLOv5 detector coupled with OCR, wrapped in a FastAPI service and a React frontend so citizens can look up their own traffic violations. Runs at ~12 FPS.

  • Developed a real-time license plate recognition system by integrating a fine-tuned YOLOv5 model with OCR for text extraction.
  • Focused on system development: designed the pipeline, built REST APIs with FastAPI, managed data in PostgreSQL, and created a ReactJS-based frontend. Deployed the system with Docker for scalability and ease of integration.
  • Achieved real-time processing at ~12 FPS with reliable recognition accuracy.
  • Enhanced traffic management efficiency and enabled citizens to conveniently check their traffic violation records online.
Explain this for
Throughput
~12 FPS
end-to-end
Pipeline stages
4
detect

The problem

Vietnam's traffic enforcement runs on phạt nguội — violations recorded by camera and mailed out later. The gap is that a driver has no convenient way to find out whether a violation exists against their plate until the notice arrives. The lookup exists; the interface does not.

Pipeline

The system is four stages, each one a place where the previous stage's errors compound:

  1. Detection — a YOLOv5 model fine-tuned on Vietnamese plates, which differ enough from the Western plates in public datasets (two-line motorcycle plates, distinct fonts and aspect ratios) that an off-the-shelf detector underperforms badly.
  2. Crop and rectify — plates are photographed at an angle far more often than head-on.
  3. OCR — text extraction from the rectified crop.
  4. Lookup — normalise the string and query PostgreSQL for violation records.

My part: making it a system

The modelling was the smaller half. What I owned was turning a notebook into something deployable:

  • FastAPI for the inference service, so detection and OCR sit behind one typed HTTP contract rather than being called from a script.
  • PostgreSQL for the violation records, with the plate string normalised on write so that lookup is an index hit and not a fuzzy scan.
  • React frontend — the public-facing half; a citizen types or photographs a plate and gets an answer.
  • Docker for the whole thing, which is what makes it reproducible on a machine that is not mine.

Performance

The pipeline sustains ~12 FPS end to end, detection and OCR included. That is the number that matters for the use case: fast enough to run against a live camera feed rather than only against uploaded stills, which is the difference between a demo and a deployment.

What I took from it

The accuracy of the detector was never the bottleneck for usefulness — the interface was. A model at 95% behind a REST API that a frontend can call beats a model at 98% that lives in a notebook. Most of the engineering effort went into the boring layers, and that is where the value was.