DEV Community

Jeremy
Jeremy

Posted on • Edited on

Crop Bounding Box ( part deux! ) for License Plate

Abstract

We are pre-processing photos to ultimately enable OCR. Prior step we found the bounding box for license plates. Let’s crop down images to only license plates themselves for OCR next.

Step-by-Step

License plate detection workflow visualized

Recipe

The over-arching goal is to read license plate numbers from images. On that journey, we detected cars in highway image captures, cropped to just cars, and detected license plates on car images. Now we crop to just license plates. And those zoomed-in license plate images are inputs to OCR, which will read license plate numbers into database.

Unlike prior cropping step, we can safely assume one license plate per image. It’s not 1:[0,n) it’s 1:[0,1].

Thus, simple step: if we found a license plate (ie have a bounding box), then crop license plate

from ultralytics import YOLO
import cv2 
import imutils
import numpy as np
from os import path

baseDir = '/Users/japollock/Projects/TrainHighwayCarDetector/'
inputFilePath = baseDir + 'photos/yolo_licensePlates/licensePlates/IMG_4554_0002.jpg'
inputFileName = path.basename(inputFilePath)
outputPhotosDir = baseDir + 'photos/yolo_licensePlates/croppedPlates/'
model = YOLO(baseDir + 'src/runs/detect/yolov8n_100_16_LP_v27/weights/best.pt')

imageOriginal = cv2.imread(inputFilePath)
imageScaled = imutils.resize(imageOriginal, width=1280)

imgRatio = imageOriginal.shape[1] / imageScaled.shape[1]

results = model.predict(source=imageScaled, imgsz=1280)

if results is not None and len(results) > 0 and results[0].boxes is not None and len(results[0].boxes) > 0:
    box = results[0].boxes[0]
    # bounding box in scaled-down image
    x1Float = box.xyxy[0][0].item()
    x2Float = box.xyxy[0][2].item()
    y1Float = box.xyxy[0][1].item()
    y2Float = box.xyxy[0][3].item()

    # calc bounding box in original (scaled-up) image
    x1 = int(imgRatio * x1Float)
    y1 = int(imgRatio * y1Float)
    x2 = int(imgRatio * x2Float)
    y2 = int(imgRatio * y2Float)

    # cropped
    imageCropped = imageOriginal[y1:y2,x1:x2]

    outputFilePath = outputPhotosDir + inputFileName[0:(len(inputFileName)-4)] + '.jpg'
    cv2.imwrite(outputFilePath, imageCropped)
    print('Wrote ' + outputFilePath)
Enter fullscreen mode Exit fullscreen mode

At this point we’re enabling from highway to car to license plate, such as the following:

Highway view

Cropped car, and cropped license plate

Almost there! From highway-view image capture, to car, to license plate. Next up: OCR!

Next Link: Read license plate with OCR

Top comments (0)