A full-stack AI application that detects and reads vehicle number plates from images. Upload a photo through the web interface and get the plate text back in seconds.
Image Upload → YOLOv8 plate detection → EasyOCR text extraction → Result + DB storage
- YOLOv8 (
best.pt) detects the license plate and returns a tight bounding box - EasyOCR reads the text from the cropped plate region using multi-variant preprocessing
- Positional correction fixes common OCR misreads based on Indian plate format (
SS DD LL DDDD) - Results are saved to SQLite and returned to the frontend
| Layer | Technology |
|---|---|
| Backend | Python, FastAPI, Uvicorn |
| AI / CV | YOLOv8 (Ultralytics), EasyOCR, OpenCV |
| Database | SQLite, SQLAlchemy |
| Frontend | Next.js 16, React 19, Tailwind CSS v4, TypeScript |
ANPR/
├── backend/
│ ├── api.py # FastAPI routes (/scan-plate, /history)
│ ├── core/
│ │ ├── detector.py # YOLOv8 plate detection
│ │ ├── ocr.py # EasyOCR + preprocessing + correction
│ │ └── pipeline.py # Orchestrates detection → OCR
│ ├── database.py # SQLAlchemy engine + session
│ ├── models.py # ScanResult DB model
│ └── requirements.txt
├── frontend/
│ └── src/app/
│ ├── page.tsx # Main UI (upload, results, history)
│ └── layout.tsx
├── images/ # Sample test images
├── outputs/ # CLI output images with bounding boxes
├── uploads/ # Saved uploaded images
├── main.py # CLI test script
├── best.pt # Fine-tuned YOLOv8 plate detection model
├── yolov8n.pt # Base YOLOv8n weights (used for retraining)
├── haarcascade_russian_plate_number.xml
└── anpr_data.db # SQLite database
- Python 3.10+
- Node.js 18+
- Tesseract OCR (Windows): Download installer — install to
C:\Program Files\Tesseract-OCR\
# Create and activate virtual environment (recommended)
python -m venv venv
venv\Scripts\activate # Windows
source venv/bin/activate # macOS/Linux
# Install dependencies
pip install -r backend/requirements.txt
# Start the API server
uvicorn backend.api:app --reloadAPI runs at http://127.0.0.1:8000
Swagger docs at http://127.0.0.1:8000/docs
cd frontend
npm install
npm run devOpen http://localhost:3000
python main.pyProcesses images/car.jpg and saves the annotated result to outputs/predicted_result.jpg.
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/v1/scan-plate |
Upload an image, returns detected plate text |
GET |
/api/v1/history |
Returns last 20 scan records |
GET |
/ |
Health check |
{
"success": true,
"processing_time_ms": 4200.5,
"plates_detected": 1,
"results": [
{
"text": "HR26DK8337",
"confidence": 0.87,
"warning": null,
"box": { "x": 120, "y": 310, "w": 390, "h": 100 }
}
]
}- Tilted or angled plates — perspective distortion reduces OCR accuracy. Plates at more than ~15° angle may produce incorrect characters. Perspective correction (deskewing) is not yet implemented.
- Partially visible plates — if characters are obscured, out of frame, or covered, the result will be incomplete. The API returns a warning when fewer than 6 characters are detected.
- Low confidence reads — results below 50% confidence are flagged with a warning in the UI. These should be treated as unreliable.
- Indian plate format assumed — the positional character correction (letter/digit mapping) is tuned for the Indian
SS DD LL DDDDformat. International plates may get incorrectly corrected. - CPU speed — EasyOCR runs 3 preprocessing variants per plate on CPU, taking 15–30 seconds per image. A CUDA GPU reduces this to under 3 seconds.
best.ptmodel — trained on ~1100 Indian plate images. Accuracy may vary on plates from other regions, heavily stylized plates, or very low resolution images.
The best.pt model was trained on Google Colab using a Roboflow dataset. To retrain or improve it:
- Get a labeled plate dataset from Roboflow Universe in YOLOv8 format
- Run on Google Colab (free T4 GPU):
from ultralytics import YOLO
model = YOLO("yolov8n.pt")
model.train(data="data.yaml", epochs=50, imgsz=640, batch=16, device=0)- Download
runs/detect/train/weights/best.ptand replace the existingbest.ptin the project root
| Variable | Default | Description |
|---|---|---|
TESSERACT_CMD |
C:\Program Files\Tesseract-OCR\tesseract.exe |
Override Tesseract path |
NEXT_PUBLIC_API_URL |
http://127.0.0.1:8000 |
Backend URL for the frontend |
Set NEXT_PUBLIC_API_URL in frontend/.env.local if your backend runs on a different port.
This project is open-source.