# LPR Data Classes

## Overview

License plate data in `degirum-vehicle` is represented by two related classes:

* **`PlateOCRResult`** - Contains OCR data (plate number, confidence)
* **`LPRResult`** - Includes all `PlateOCRResult` properties plus detection metadata (bounding box, detection score)

## PlateOCRResult

Contains license plate OCR data without detection-specific information. Used primarily for tracking workflows.

### Properties

| Property       | Type        | Description                   |
| -------------- | ----------- | ----------------------------- |
| `plate_number` | str or None | Recognized license plate text |
| `ocr_score`    | float       | OCR confidence score 0.0-1.0  |

### When It's Used

`find_plates_in_file()` and `find_plates_in_clip()` return `Dict[int, PlateOCRResult]` - a mapping of track IDs to plate data. Each `PlateOCRResult` object contains:

* **Aggregated plate text** - Fused across frames using Bayesian text aggregation
* **Confidence score** - Final OCR confidence after multi-frame fusion
* This accumulated data across frames provides robust plate recognition results

### Usage Example

```python
# Analyze video to extract license plates
plates = tracker.find_plates_in_file("parking_lot.mp4")

# plates is Dict[int, PlateOCRResult] - maps track_id to plate data
for track_id, plate in plates.items():
    print(f"Track {track_id}:")
    print(f"  Plate: {plate.plate_number}")
    print(f"  OCR Score: {plate.ocr_score:.3f}")
```

## LPRResult

Subclasses `PlateOCRResult` to add detection-specific metadata. Used for real-time recognition results.

### Properties

Inherits all `PlateOCRResult` properties (`plate_number`, `ocr_score`) plus:

| Property          | Type          | Description                        |
| ----------------- | ------------- | ---------------------------------- |
| `bbox`            | list          | Bounding box `[x1, y1, x2, y2]`    |
| `detection_score` | float or None | Plate detection confidence 0.0-1.0 |

**Important notes:**

* When using LicensePlateTracker, `track_id` is in `InferenceResults.results`, not as a property. Access via `result.results[i].get("track_id")`

### When It's Used

* Contained in `InferenceResults.license_plates` from `predict()` and `predict_batch()`

### Usage Examples

**Access detection properties:**

```python
result = recognizer.predict("car.jpg")

for plate in result.license_plates:
    if plate.plate_number:
        print(f"Plate: {plate.plate_number} (OCR: {plate.ocr_score:.2f})")
    else:
        print(f"Unreadable plate (detection: {plate.detection_score:.2f})")
    
    # Access bounding box
    x1, y1, x2, y2 = plate.bbox
    print(f"Plate location: ({x1}, {y1}) to ({x2}, {y2})")
```

**LicensePlateTracker - Access tracking data:**

```python
for result in tracker.predict_batch(video_source):
    # result.license_plates and result.results correspond at the same index
    for i in range(len(result.license_plates)):
        track_id = result.results[i].get("track_id")
        plate = result.license_plates[i]
        print(f"Track {track_id}: {plate.plate_number} (OCR: {plate.ocr_score:.2f})")
```

**String representation:**

```python
for result in lpr.predict_batch(["car1.jpg", "car2.jpg"]):
    for plate in result.license_plates:
        # Pretty print using __str__
        print(plate)
```

**Output:**

```
Plate Number    : ABC1234
OCR Score       : 0.987
Detection Score : 0.952
Bounding box    : [123, 456, 789, 234]
```

## Return Types by Method

### LicensePlateRecognizer

| Method            | Return Type                                                                |
| ----------------- | -------------------------------------------------------------------------- |
| `predict()`       | `InferenceResults` (`.license_plates` property yields `LPRResult` objects) |
| `predict_batch()` | Iterator of `InferenceResults`                                             |

### LicensePlateTracker

| Method                  | Return Type                                                                            |
| ----------------------- | -------------------------------------------------------------------------------------- |
| `predict_batch()`       | Iterator of `InferenceResults` (`.license_plates` property yields `LPRResult` objects) |
| `find_plates_in_file()` | `Dict[int, PlateOCRResult]`                                                            |
| `find_plates_in_clip()` | `Dict[int, PlateOCRResult]`                                                            |
