File size: 2,697 Bytes
6ca2490
50386b1
 
 
 
 
 
 
 
 
31ea7d8
50386b1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6ca2490
50386b1
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# inference.py

from ultralytics import YOLO
import os
import cv2
import numpy as np
import re
from fast_plate_ocr import LicensePlateRecognizer

# ── Init ──────────────────────────────────────────────────────────────────────
MODEL_PATH = os.path.join("app", "models", "best.pt")
model = YOLO(MODEL_PATH)
# reader = easyocr.Reader(['en'], gpu=True)

ocr= LicensePlateRecognizer("cct-s-v2-global-model")

CONF_THRESHOLD = 0.255
PLATE_ALLOWLIST = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 '



# ── Main ──────────────────────────────────────────────────────────────────────

def detect_license_plate(image_path: str):
    results = model(image_path)
    image = cv2.imread(image_path)
    h_img, w_img = image.shape[:2]

    detections = []

    for result in results:
        for box in result.boxes:
            x1, y1, x2, y2 = map(int, box.xyxy[0].tolist())
            conf = float(box.conf[0])

            if conf < CONF_THRESHOLD:
                continue

            # Small margin to avoid clipping plate edges
            margin = 4
            cx1 = max(0, x1 - margin)
            cy1 = max(0, y1 - margin)
            cx2 = min(w_img, x2 + margin)
            cy2 = min(h_img, y2 + margin)

            plate_crop = image[cy1:cy2, cx1:cx2]
            # versions = preprocess_plate(plate_crop)
            # plate_text, ocr_conf = run_ocr_on_versions(versions)



            # fast-plate-ocr expects BGR numpy array β€” no preprocessing needed
            result_ocr = ocr.run(plate_crop)

            # run() returns a list of predictions, one per image β€” take first
            plate_text = result_ocr[0].plate if result_ocr else ""
            
            
            # Draw bounding box
            cv2.rectangle(image, (x1, y1), (x2, y2), (255, 218, 105), 2)

            label = f"{plate_text} ({round(conf, 2)})" if plate_text else f"({round(conf, 2)})"
            (lw, lh), baseline = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.55, 2)

         
            detections.append({
                "bbox": {"x1": x1, "y1": y1, "x2": x2, "y2": y2},
                "confidence": round(conf, 3),
                "text": plate_text,
                # "ocr_confidence": round(ocr_conf, 3) if ocr_conf else None,
            })

    name, ext = os.path.splitext(image_path)
    output_path = f"{name}_output{ext}"
    cv2.imwrite(output_path, image)

    return detections, output_path