Back to All Blogs
Computer Vision & Deep Learning

Car License Plate Detection — YOLOv5 & OCR Pipeline

An end-to-end intelligent transportation and surveillance pipeline combining YOLOv5 deep learning object detection with OpenCV morphological processing and Tesseract OCR. Capable of localizing vehicle bounding boxes, isolating license plates under complex lighting conditions, and extracting alphanumeric character sequences with high precision.

YOLOv5 Object Detection
OpenCV Image Filtering
Tesseract OCR Recognition
PyTorch Model Engine

Computer Vision Pipeline Architecture

YOLOv5 Deep Learning Detection

  • Trained on customized vehicle and license plate bounding box annotations.
  • Anchor-based multi-scale feature pyramids detecting plates at varying angles and distances.
  • Non-Maximum Suppression (NMS) eliminating duplicate bounding box proposals.
  • Optimized PyTorch inference running efficiently on GPU or CPU instances.

Image Enhancement & Optical Character Recognition

  • Cropped plate localization converted to grayscale for luminescence normalization.
  • Bilateral and Gaussian filtering removing noise while preserving character edge sharpness.
  • Otsu's adaptive binarization maximizing character-to-background contrast.
  • Tesseract OCR configured with alphanumeric regex whitelisting for license plates.

Detection & Character Extraction Pipeline

# YOLOv5 Detection + OpenCV & Tesseract OCR Pipeline
import cv2
import torch
import pytesseract

# Load trained YOLOv5 weights
model = torch.hub.load('ultralytics/yolov5', 'custom', path='weights/best.pt')

def extract_license_plate(image_path):
    results = model(image_path)
    boxes = results.xyxy[0].cpu().numpy() # [x1, y1, x2, y2, conf, cls]
    
    img = cv2.imread(image_path)
    extracted_text = []
    
    for box in boxes:
        x1, y1, x2, y2 = map(int, box[:4])
        plate_crop = img[y1:y2, x1:x2]
        
        # Preprocessing for OCR
        gray = cv2.cvtColor(plate_crop, cv2.COLOR_BGR2GRAY)
        thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
        
        text = pytesseract.image_to_string(thresh, config='--psm 8 -c tessedit_char_whitelist=ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
        extracted_text.append(text.strip())
        
    return extracted_text