PrasannaBAImodel/license-plate-keypoint-detection
2122
License Plate Keypoint Detection
A fine-tuned YOLOv8m-Pose model that detects vehicle license plates and precisely localizes their 4 corner keypoints (top-left, top-right, bottom-right, bottom-left). Designed for downstream tasks like logo replacement, plate anonymization, and perspective-corrected OCR.
Model Details
Performance Metrics
Evaluated on the held-out validation set (24 images):
Model fully trained for all 150 epochs, achieving best-in-class performance at the final checkpoint.
Training Details
Dataset
- Source: Roboflow —
license-plate-newdataset (v3) - License: CC BY 4.0
- Train: 19000 images
- Validation: 2400 images
- Test: 2400 images
- Annotation: YOLO Pose format, 4 keypoints per plate (x, y, visibility)
Quick Start
Installation
pip install ultralytics opencv-python numpyBasic Inference
from ultralytics import YOLO
import cv2
# Load model
model = YOLO("license_plate_keypoint.pt")
# Run inference on an image
results = model("car.jpg", conf=0.25)
for result in results:
if result.keypoints is not None:
for kpts in result.keypoints:
# kpts.xy shape: [4, 2] — (x, y) for each of the 4 corners
corners = kpts.xy[0].cpu().numpy()
print("TL:", corners[0])
print("TR:", corners[1])
print("BR:", corners[2])
print("BL:", corners[3])Using the Full Inference Pipeline
from inference import LicensePlateKeypointDetector
detector = LicensePlateKeypointDetector("license_plate_keypoint.pt")
# Detect keypoints only
result = detector.detect("car.jpg")
if result["success"]:
print("Keypoints:", result["keypoints"])
print("Confidence:", result["confidence"])
# Detect and blur the plate
blurred = detector.blur_plate("car.jpg", output_path="blurred.jpg")
# Detect and replace with a logo
replaced = detector.replace_logo("car.jpg", "logo.png", output_path="out.jpg")Batch Processing
from inference import LicensePlateKeypointDetector
from pathlib import Path
detector = LicensePlateKeypointDetector("license_plate_keypoint.pt")
for img_path in Path("input_images").glob("*.jpg"):
result = detector.detect(str(img_path))
if result["success"]:
print(f"{img_path.name}: {result['keypoints']}")Video Processing
from inference import LicensePlateKeypointDetector
detector = LicensePlateKeypointDetector("license_plate_keypoint.pt")
detector.process_video("input.mp4", output_path="output.mp4", blur=True)Keypoint Order
The model outputs 4 keypoints per detected plate in this fixed order:
0: Top-Left (TL)
1: Top-Right (TR)
2: Bottom-Right (BR)
3: Bottom-Left (BL)Each keypoint has (x, y, visibility) values. Visibility > 0.5 means the point is reliably detected.
Use Cases
- Plate Anonymization — Blur or mask license plates for privacy compliance
- Logo Replacement — Replace plates with custom logos using perspective transform
- OCR Pre-processing — Extract and warp plate regions for accurate text recognition
- Dataset Annotation — Auto-annotate corner keypoints for further training
- Traffic Monitoring — Track vehicle plates in video streams
Limitations
- Trained primarily on clear, front-facing license plate images
- Performance may degrade on heavily occluded, night-time, or extreme-angle plates
- Best results at image resolution ≥ 640px
- Optimized for standard rectangular license plates
Files
Citation
If you use this model, please cite:
@misc{prasanna2024licenseplatepose,
title = {License Plate Keypoint Detection using YOLOv8 Pose},
author = {Prasanna B},
year = {2025},
publisher = {Hugging Face},
url = {https://huggingface.co/PrasannaBAImodel/license-plate-keypoint-detection}
}License
This model is released under the Apache 2.0 License. Base model (YOLOv8) is © Ultralytics, released under AGPL-3.0. Training data from Roboflow under CC BY 4.0.
