Crop Bounding Box ( part deux! ) for License Plate

License Plate Detection (8 Part Series)

1 OpenCV in Python for End-to-end License Plate Detection
2 Camera and Computer Setup
4 more parts…
3 Capturing Images from DSLR to RPi
4 Model for Detecting Cars
5 Crop Bounding Box + Rotate
6 Model for Detecting License Plates in Cropped Image
7 Crop Bounding Box ( part deux! ) for License Plate
8 Read license plate with OCR

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

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

<span>from</span> <span>ultralytics</span> <span>import</span> <span>YOLO</span>
<span>import</span> <span>cv2</span>
<span>import</span> <span>imutils</span>
<span>import</span> <span>numpy</span> <span>as</span> <span>np</span>
<span>from</span> <span>os</span> <span>import</span> <span>path</span>
<span>baseDir</span> <span>=</span> <span>'</span><span>/</span><span>Users</span><span>/</span><span>japollock</span><span>/</span><span>Projects</span><span>/</span><span>TrainHighwayCarDetector</span><span>/</span><span>'</span>
<span>inputFilePath</span> <span>=</span> <span>baseDir</span> <span>+</span> <span>'</span><span>photos</span><span>/</span><span>yolo_licensePlates</span><span>/</span><span>licensePlates</span><span>/</span><span>IMG_4554_0002</span><span>.</span><span>jpg</span><span>'</span>
<span>inputFileName</span> <span>=</span> <span>path</span><span>.</span><span>basename</span><span>(</span><span>inputFilePath</span><span>)</span>
<span>outputPhotosDir</span> <span>=</span> <span>baseDir</span> <span>+</span> <span>'</span><span>photos</span><span>/</span><span>yolo_licensePlates</span><span>/</span><span>croppedPlates</span><span>/</span><span>'</span>
<span>model</span> <span>=</span> <span>YOLO</span><span>(</span><span>baseDir</span> <span>+</span> <span>'</span><span>src</span><span>/</span><span>runs</span><span>/</span><span>detect</span><span>/</span><span>yolov8n_100_16_LP_v27</span><span>/</span><span>weights</span><span>/</span><span>best</span><span>.</span><span>pt</span><span>'</span><span>)</span>
<span>imageOriginal</span> <span>=</span> <span>cv2</span><span>.</span><span>imread</span><span>(</span><span>inputFilePath</span><span>)</span>
<span>imageScaled</span> <span>=</span> <span>imutils</span><span>.</span><span>resize</span><span>(</span><span>imageOriginal</span><span>,</span> <span>width</span><span>=</span><span>1280</span><span>)</span>
<span>imgRatio</span> <span>=</span> <span>imageOriginal</span><span>.</span><span>shape</span><span>[</span><span>1</span><span>]</span> <span>/</span> <span>imageScaled</span><span>.</span><span>shape</span><span>[</span><span>1</span><span>]</span>
<span>results</span> <span>=</span> <span>model</span><span>.</span><span>predict</span><span>(</span><span>source</span><span>=</span><span>imageScaled</span><span>,</span> <span>imgsz</span><span>=</span><span>1280</span><span>)</span>
<span>if</span> <span>results</span> <span>is</span> <span>not</span> <span>None</span> <span>and</span> <span>len</span><span>(</span><span>results</span><span>)</span> <span>></span> <span>0</span> <span>and</span> <span>results</span><span>[</span><span>0</span><span>].</span><span>boxes</span> <span>is</span> <span>not</span> <span>None</span> <span>and</span> <span>len</span><span>(</span><span>results</span><span>[</span><span>0</span><span>].</span><span>boxes</span><span>)</span> <span>></span> <span>0</span><span>:</span>
<span>box</span> <span>=</span> <span>results</span><span>[</span><span>0</span><span>].</span><span>boxes</span><span>[</span><span>0</span><span>]</span>
<span># bounding box in scaled-down image </span> <span>x1Float</span> <span>=</span> <span>box</span><span>.</span><span>xyxy</span><span>[</span><span>0</span><span>][</span><span>0</span><span>].</span><span>item</span><span>()</span>
<span>x2Float</span> <span>=</span> <span>box</span><span>.</span><span>xyxy</span><span>[</span><span>0</span><span>][</span><span>2</span><span>].</span><span>item</span><span>()</span>
<span>y1Float</span> <span>=</span> <span>box</span><span>.</span><span>xyxy</span><span>[</span><span>0</span><span>][</span><span>1</span><span>].</span><span>item</span><span>()</span>
<span>y2Float</span> <span>=</span> <span>box</span><span>.</span><span>xyxy</span><span>[</span><span>0</span><span>][</span><span>3</span><span>].</span><span>item</span><span>()</span>
<span># calc bounding box in original (scaled-up) image </span> <span>x1</span> <span>=</span> <span>int</span><span>(</span><span>imgRatio</span> <span>*</span> <span>x1Float</span><span>)</span>
<span>y1</span> <span>=</span> <span>int</span><span>(</span><span>imgRatio</span> <span>*</span> <span>y1Float</span><span>)</span>
<span>x2</span> <span>=</span> <span>int</span><span>(</span><span>imgRatio</span> <span>*</span> <span>x2Float</span><span>)</span>
<span>y2</span> <span>=</span> <span>int</span><span>(</span><span>imgRatio</span> <span>*</span> <span>y2Float</span><span>)</span>
<span># cropped </span> <span>imageCropped</span> <span>=</span> <span>imageOriginal</span><span>[</span><span>y1</span><span>:</span><span>y2</span><span>,</span><span>x1</span><span>:</span><span>x2</span><span>]</span>
<span>outputFilePath</span> <span>=</span> <span>outputPhotosDir</span> <span>+</span> <span>inputFileName</span><span>[</span><span>0</span><span>:</span><span>(</span><span>len</span><span>(</span><span>inputFileName</span><span>)</span><span>-</span><span>4</span><span>)]</span> <span>+</span> <span>'</span><span>.</span><span>jpg</span><span>'</span>
<span>cv2</span><span>.</span><span>imwrite</span><span>(</span><span>outputFilePath</span><span>,</span> <span>imageCropped</span><span>)</span>
<span>print</span><span>(</span><span>'</span><span>Wrote</span> <span>'</span> <span>+</span> <span>outputFilePath</span><span>)</span>
<span>from</span> <span>ultralytics</span> <span>import</span> <span>YOLO</span>
<span>import</span> <span>cv2</span> 
<span>import</span> <span>imutils</span>
<span>import</span> <span>numpy</span> <span>as</span> <span>np</span>
<span>from</span> <span>os</span> <span>import</span> <span>path</span>

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

<span>imageOriginal</span> <span>=</span> <span>cv2</span><span>.</span><span>imread</span><span>(</span><span>inputFilePath</span><span>)</span>
<span>imageScaled</span> <span>=</span> <span>imutils</span><span>.</span><span>resize</span><span>(</span><span>imageOriginal</span><span>,</span> <span>width</span><span>=</span><span>1280</span><span>)</span>

<span>imgRatio</span> <span>=</span> <span>imageOriginal</span><span>.</span><span>shape</span><span>[</span><span>1</span><span>]</span> <span>/</span> <span>imageScaled</span><span>.</span><span>shape</span><span>[</span><span>1</span><span>]</span>

<span>results</span> <span>=</span> <span>model</span><span>.</span><span>predict</span><span>(</span><span>source</span><span>=</span><span>imageScaled</span><span>,</span> <span>imgsz</span><span>=</span><span>1280</span><span>)</span>

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

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

    <span># cropped </span>    <span>imageCropped</span> <span>=</span> <span>imageOriginal</span><span>[</span><span>y1</span><span>:</span><span>y2</span><span>,</span><span>x1</span><span>:</span><span>x2</span><span>]</span>

    <span>outputFilePath</span> <span>=</span> <span>outputPhotosDir</span> <span>+</span> <span>inputFileName</span><span>[</span><span>0</span><span>:</span><span>(</span><span>len</span><span>(</span><span>inputFileName</span><span>)</span><span>-</span><span>4</span><span>)]</span> <span>+</span> <span>'</span><span>.</span><span>jpg</span><span>'</span>
    <span>cv2</span><span>.</span><span>imwrite</span><span>(</span><span>outputFilePath</span><span>,</span> <span>imageCropped</span><span>)</span>
    <span>print</span><span>(</span><span>'</span><span>Wrote</span> <span>'</span> <span>+</span> <span>outputFilePath</span><span>)</span>
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:

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

Next Link: Read license plate with OCR

License Plate Detection (8 Part Series)

1 OpenCV in Python for End-to-end License Plate Detection
2 Camera and Computer Setup
4 more parts…
3 Capturing Images from DSLR to RPi
4 Model for Detecting Cars
5 Crop Bounding Box + Rotate
6 Model for Detecting License Plates in Cropped Image
7 Crop Bounding Box ( part deux! ) for License Plate
8 Read license plate with OCR

原文链接:Crop Bounding Box ( part deux! ) for License Plate

© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享
I try to give up the dream just a dream.
努力了才叫梦想
评论 抢沙发

请登录后发表评论

    暂无评论内容