File size: 2,275 Bytes
1c0c94d | 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 78 79 | """Plate normalisation + attachment to the vehicle it sits inside."""
from __future__ import annotations
from core.graph import attach_plates
from core.plates import ChainPlateRecognizer, _as_conf, normalize_plate
from core.schemas import BBox, EvidenceGraph, Plate, Vehicle
def _car(vid: str, box: tuple[float, float, float, float]) -> Vehicle:
return Vehicle(
id=vid,
type="car",
bbox=BBox(x1=box[0], y1=box[1], x2=box[2], y2=box[3]),
confidence=0.9,
)
def test_normalize_valid_indian_plate() -> None:
assert normalize_plate("up 32 ab 1234") == ("UP32AB1234", True)
def test_normalize_rejects_garbage() -> None:
cleaned, ok = normalize_plate("!!??")
assert ok is False
assert cleaned == ""
def test_plate_attaches_to_enclosing_vehicle() -> None:
g = EvidenceGraph(image_id="i", vehicles=[_car("v1", (0, 0, 100, 100))])
plate = Plate(
text="UP32AB1234",
regex_ok=True,
confidence=0.8,
bbox=BBox(x1=40, y1=70, x2=70, y2=85),
)
attach_plates(g, [plate])
got = g.plate_of("v1")
assert got is not None
assert got.text == "UP32AB1234"
def test_plate_outside_vehicle_is_not_attached() -> None:
g = EvidenceGraph(image_id="i", vehicles=[_car("v1", (0, 0, 50, 50))])
plate = Plate(
text="UP32AB1234",
regex_ok=True,
confidence=0.8,
bbox=BBox(x1=200, y1=200, x2=230, y2=215),
)
attach_plates(g, [plate])
assert g.plate_of("v1") is None
def test_as_conf_collapses_list_to_mean() -> None:
assert _as_conf([0.8, 0.6]) == 0.7
assert _as_conf(0.5) == 0.5
assert _as_conf(None) == 0.0
class _Fixed:
def __init__(self, plates: list[Plate]) -> None:
self._plates = plates
def read_all(self, image_path: str) -> list[Plate]:
return self._plates
def test_chain_uses_primary_when_it_reads_a_plate() -> None:
chain = ChainPlateRecognizer(
_Fixed([Plate(text="UP32AB1234")]), _Fixed([Plate(text="ZZ")])
)
assert chain.read_all("x")[0].text == "UP32AB1234"
def test_chain_falls_back_when_primary_is_empty() -> None:
chain = ChainPlateRecognizer(_Fixed([]), _Fixed([Plate(text="MH01AA1111")]))
assert chain.read_all("x")[0].text == "MH01AA1111"
|