Saturday, March 21, 2026

Automatic License Plate Recognition

Detecting a car license plate (number plate) and then reading its text is a classic computer vision task called Automatic License Plate Recognition (ALPR / ANPR / LPR).

In 2025–2026 the most practical, accurate and widely used open-source approach in Python combines:

  1. Object detection → find the location of the plate in the image/video
  2. OCR (Optical Character Recognition) → read the characters from the cropped plate region

Modern Recommended Pipeline (2025–2026)

The current best open-source combo for most people is:

  • Plate detectionYOLOv8 or YOLOv11 (Ultralytics)
  • OCREasyOCR (very easy) or PaddleOCR (usually more accurate, especially on difficult plates)

Other strong options:

  • YOLO + PaddleOCR (frequently wins in recent benchmarks for accuracy)
  • YOLO + custom lightweight OCR models (e.g. fast-plate-ocr)

Step-by-step: How It Works

StepTaskTypical Tool/Library (2025–2026)Why it's used
1Capture image or video frameOpenCV (cv2.VideoCapture or cv2.imread)Read camera / file
2(Optional) Detect vehicle firstYOLOv8 / YOLOv11 (pre-trained on COCO)Helps when plates are small / far away
3Detect license plateFine-tuned YOLOv8/YOLOv11 on plate datasetGives bounding box (x,y,w,h)
4Crop the plate regionOpenCV slicingIsolate only the plate
5Pre-process crop (optional)Grayscale, sharpen, threshold, deskewImprove OCR accuracy
6Read text (OCR)EasyOCR or PaddleOCRExtract letters & numbers
7Post-process textRegex, rules (remove spaces, fix common errors)Clean up result (e.g. "O" → "0")
8(Optional) Track across framesSORT / ByteTrack / BoT-SORTStable reading on video

Quick Start Code Example (YOLOv8 + EasyOCR)

This is one of the most popular and easiest setups right now.

Python
# pip install ultralytics easyocr opencv-python

import cv2
from ultralytics import YOLO
import easyocr
import numpy as np

# 1. Load models
plate_model = YOLO("best.pt")           # ← your fine-tuned plate detection model
reader = easyocr.Reader(['en'], gpu=True)   # 'en' = English-like plates

# 2. Open video or image
cap = cv2.VideoCapture(0)   # 0 = webcam    or   "video.mp4"

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break

    # 3. Detect plates
    results = plate_model(frame, conf=0.5)

    for result in results:
        boxes = result.boxes.xyxy.cpu().numpy()     # bounding boxes

        for box in boxes:
            x1, y1, x2, y2 = map(int, box[:4])

            # 4. Crop plate
            plate_crop = frame[y1:y2, x1:x2]

            # 5. Optional pre-processing
            gray = cv2.cvtColor(plate_crop, cv2.COLOR_BGR2GRAY)
            # sharpen, threshold, etc. if needed

            # 6. OCR
            ocr_result = reader.readtext(gray)

            if ocr_result:
                text = ocr_result[0][-2].upper().replace(" ", "")
                print("Plate:", text)

                # Draw on frame
                cv2.rectangle(frame, (x1,y1), (x2,y2), (0,255,0), 2)
                cv2.putText(frame, text, (x1, y1-10),
                            cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0,255,0), 2)

    cv2.imshow("ANPR", frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

Where to Get a Plate Detection Model

You almost never train from scratch today.

Popular ready-to-use / fine-tune options (2025–2026):

SourceModel TypeLink / DatasetNotes
Roboflow UniverseYOLOv8/YOLOv11https://universe.roboflow.com/search?q=license%20plateThousands of free plate datasets + export to YOLO format
Ultralytics communityYOLOv8Search GitHub "yolov8 license plate"Many ready .pt files
computervisionengYOLOv8https://github.com/computervisioneng/automatic-number-plate-recognition-python-yolov8Very popular tutorial + model
Muhammad-Zeerak-KhanYOLOv8https://github.com/Muhammad-Zeerak-Khan/Automatic-License-Plate-Recognition-using-YOLOv8Simple & good

EasyOCR vs PaddleOCR – Quick Comparison (2025–2026)

FeatureEasyOCRPaddleOCRWinner for most parking projects
Ease of useExtremely easy (2–3 lines)More setup, but still simpleEasyOCR
Accuracy (plates)GoodUsually better (especially Arabic/ non-Latin)PaddleOCR
SpeedFast on CPU/GPUFaster on GPU, good CPU fallbackPaddleOCR (GPU)
Languages~80100+ (better multilingual)PaddleOCR
GPU needed?OptionalMuch better with GPU

→ For Egyptian / Arabic plates → try PaddleOCR first (better support for Arabic script).

Tips for Parked Cars (perpendicular to road)

  • Use a slightly tilted downward camera (20–35°) → better view of front plates
  • Crop tighter → helps OCR a lot
  • Add pre-processing:
    Python
    # Example sharpen + threshold
    kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
    sharpened = cv2.filter2D(plate_crop, -1, kernel)
    thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                                   cv2.THRESH_BINARY_INV, 11, 2)

For PaddleOCR, you typically need a two-stage pipeline: one model to detect the plate (Detection) and another to read the characters (Recognition).

1. Basic Code for PaddleOCR

To get started, install the library and its dependencies:

Bash
pip install paddlepaddle-gpu # or paddlepaddle if no GPU
pip install paddleocr

Here is a simple inference script:

Python
from paddleocr import PaddleOCR, draw_ocr
from PIL import Image

# Initialize PaddleOCR (lang='ar' for Arabic/Egyptian plates)
ocr = PaddleOCR(use_angle_cls=True, lang='ar') 

img_path = 'egypt_plate.jpg'
result = ocr.ocr(img_path, cls=True)

# Print results
for idx in range(len(result)):
    res = result[idx]
    for line in res:
        print(f"Text: {line[1][0]} | Confidence: {line[1][1]}")

# Optional: Visualize results
image = Image.open(img_path).convert('RGB')
boxes = [line[0] for line in result[0]]
txts = [line[1][0] for line in result[0]]
scores = [line[1][1] for line in result[0]]
im_show = draw_ocr(image, boxes, txts, scores, font_path='/path/to/arabic_font.ttf')
im_show = Image.fromarray(im_show)
im_show.save('result.jpg')

2. Egyptian Plate Datasets

Finding high-quality, annotated Egyptian data is the hardest part. Here are the best currently available resources:

  • EALPR (Egyptian Automatic License Plate Recognition): * Contains ~2,000+ images with 10,000+ annotated characters.

  • Kaggle - Egyptian Cars Plates:

    • There are multiple community uploads. Look for "Egyptian Car Plate Dataset with Annotated Bounding Boxes" by users like MahmoudKhater99 or alyalsayed.

  • Motorcycle Specific:

No comments: