Skip to content

Reference

This page shows the public API of FastALPR.

At a Glance

  • Use ALPR.predict() to get structured ALPR results
  • Use ALPR.draw_predictions() to get an annotated image and the same ALPR results
  • BoundingBox and DetectionResult come from open-image-models

Imports

from fast_alpr import ALPR, ALPRResult, DrawPredictionsResult, OcrResult

Common Inputs

  • A NumPy image in BGR format
  • A string path to an image file

Common Returns

  • ALPR.predict(...) returns list[ALPRResult]
  • ALPR.draw_predictions(...) returns DrawPredictionsResult

ALPRResult contains:

  • detection: box, label, and detection confidence
  • ocr: recognized text and OCR confidence, or None

DrawPredictionsResult contains:

  • image: the image with boxes and text drawn on it
  • results: the same ALPR results used for drawing

Available Models

See the available detection models in open-image-models and OCR models in fast-plate-ocr.

Main Class

ALPR

ALPR(
    detector: BaseDetector | None = None,
    ocr: BaseOCR | None = None,
    detector_model: PlateDetectorModel = "yolo-v9-t-384-license-plate-end2end",
    detector_conf_thresh: float = 0.4,
    detector_providers: Sequence[str | tuple[str, dict]]
    | None = None,
    detector_sess_options: SessionOptions = None,
    ocr_model: OcrModel | None = "cct-xs-v2-global-model",
    ocr_device: Literal["cuda", "cpu", "auto"] = "auto",
    ocr_providers: Sequence[str | tuple[str, dict]]
    | None = None,
    ocr_sess_options: SessionOptions | None = None,
    ocr_model_path: str | PathLike | None = None,
    ocr_config_path: str | PathLike | None = None,
    ocr_force_download: bool = False,
)

Automatic License Plate Recognition (ALPR) system class.

This class combines a detector and an OCR model to recognize license plates in images.

Parameters:

Name Type Description Default
detector BaseDetector | None

An instance of BaseDetector. If None, the DefaultDetector is used.

None
ocr BaseOCR | None

An instance of BaseOCR. If None, the DefaultOCR is used.

None
detector_model PlateDetectorModel

The name of the detector model or a PlateDetectorModel enum instance. Defaults to "yolo-v9-t-384-license-plate-end2end".

'yolo-v9-t-384-license-plate-end2end'
detector_conf_thresh float

Confidence threshold for the detector.

0.4
detector_providers Sequence[str | tuple[str, dict]] | None

Execution providers for the detector.

None
detector_sess_options SessionOptions

Session options for the detector.

None
ocr_model OcrModel | None

The name of the OCR model from the model hub. This can be none and ocr_model_path and ocr_config_path parameters are expected to pass them to fast-plate-ocr library.

'cct-xs-v2-global-model'
ocr_device Literal['cuda', 'cpu', 'auto']

The device to run the OCR model on ("cuda", "cpu", or "auto").

'auto'
ocr_providers Sequence[str | tuple[str, dict]] | None

Execution providers for the OCR. If None, the default providers are used.

None
ocr_sess_options SessionOptions | None

Session options for the OCR. If None, default session options are used.

None
ocr_model_path str | PathLike | None

Custom model path for the OCR. If None, the model is downloaded from the hub or cache.

None
ocr_config_path str | PathLike | None

Custom config path for the OCR. If None, the default configuration is used.

None
ocr_force_download bool

Whether to force download the OCR model.

False
Source code in fast_alpr/alpr.py
def __init__(
    self,
    detector: BaseDetector | None = None,
    ocr: BaseOCR | None = None,
    detector_model: PlateDetectorModel = "yolo-v9-t-384-license-plate-end2end",
    detector_conf_thresh: float = 0.4,
    detector_providers: Sequence[str | tuple[str, dict]] | None = None,
    detector_sess_options: ort.SessionOptions = None,
    ocr_model: OcrModel | None = "cct-xs-v2-global-model",
    ocr_device: Literal["cuda", "cpu", "auto"] = "auto",
    ocr_providers: Sequence[str | tuple[str, dict]] | None = None,
    ocr_sess_options: ort.SessionOptions | None = None,
    ocr_model_path: str | os.PathLike | None = None,
    ocr_config_path: str | os.PathLike | None = None,
    ocr_force_download: bool = False,
) -> None:
    """
    Initialize the ALPR system.

    Parameters:
        detector: An instance of BaseDetector. If None, the DefaultDetector is used.
        ocr: An instance of BaseOCR. If None, the DefaultOCR is used.
        detector_model: The name of the detector model or a PlateDetectorModel enum instance.
            Defaults to "yolo-v9-t-384-license-plate-end2end".
        detector_conf_thresh: Confidence threshold for the detector.
        detector_providers: Execution providers for the detector.
        detector_sess_options: Session options for the detector.
        ocr_model: The name of the OCR model from the model hub. This can be none and
            `ocr_model_path` and `ocr_config_path` parameters are expected to pass them to
            `fast-plate-ocr` library.
        ocr_device: The device to run the OCR model on ("cuda", "cpu", or "auto").
        ocr_providers: Execution providers for the OCR. If None, the default providers are used.
        ocr_sess_options: Session options for the OCR. If None, default session options are
            used.
        ocr_model_path: Custom model path for the OCR. If None, the model is downloaded from the
            hub or cache.
        ocr_config_path: Custom config path for the OCR. If None, the default configuration is
            used.
        ocr_force_download: Whether to force download the OCR model.
    """
    # Initialize the detector
    self.detector = detector or DefaultDetector(
        model_name=detector_model,
        conf_thresh=detector_conf_thresh,
        providers=detector_providers,
        sess_options=detector_sess_options,
    )

    # Initialize the OCR
    self.ocr = ocr or DefaultOCR(
        hub_ocr_model=ocr_model,
        device=ocr_device,
        providers=ocr_providers,
        sess_options=ocr_sess_options,
        model_path=ocr_model_path,
        config_path=ocr_config_path,
        force_download=ocr_force_download,
    )

Functions

predict

predict(frame: ndarray | str) -> list[ALPRResult]

Run plate detection and OCR on an image.

Parameters:

Name Type Description Default
frame ndarray | str

Unprocessed frame (Colors in order: BGR) or image path.

required

Returns:

Type Description
list[ALPRResult]

A list of ALPRResult objects, one for each detected plate.

Source code in fast_alpr/alpr.py
def predict(self, frame: np.ndarray | str) -> list[ALPRResult]:
    """
    Run plate detection and OCR on an image.

    Parameters:
        frame: Unprocessed frame (Colors in order: BGR) or image path.

    Returns:
        A list of ALPRResult objects, one for each detected plate.
    """
    if isinstance(frame, str):
        img_path = frame
        img = cv2.imread(img_path)
        if img is None:
            raise ValueError(f"Failed to load image from path: {img_path}")
    else:
        img = frame

    plate_detections = self.detector.predict(img)
    alpr_results: list[ALPRResult] = []
    for detection in plate_detections:
        bbox = detection.bounding_box
        x1, y1 = max(bbox.x1, 0), max(bbox.y1, 0)
        x2, y2 = min(bbox.x2, img.shape[1]), min(bbox.y2, img.shape[0])
        cropped_plate = img[y1:y2, x1:x2]
        ocr_result = self.ocr.predict(cropped_plate)
        alpr_result = ALPRResult(detection=detection, ocr=ocr_result)
        alpr_results.append(alpr_result)
    return alpr_results

draw_predictions

draw_predictions(
    frame: ndarray | str,
) -> DrawPredictionsResult

Draw detections and OCR results on an image.

Parameters:

Name Type Description Default
frame ndarray | str

The original frame or image path.

required

Returns:

Type Description
DrawPredictionsResult

A DrawPredictionsResult with the annotated image and the ALPR results.

Source code in fast_alpr/alpr.py
def draw_predictions(self, frame: np.ndarray | str) -> DrawPredictionsResult:
    """
    Draw detections and OCR results on an image.

    Parameters:
        frame: The original frame or image path.

    Returns:
        A DrawPredictionsResult with the annotated image and the ALPR results.
    """
    # If frame is a string, assume it's an image path and load it
    if isinstance(frame, str):
        img_path = frame
        img = cv2.imread(img_path)
        if img is None:
            raise ValueError(f"Failed to load image from path: {img_path}")
    else:
        img = frame

    # Get ALPR results using the ndarray
    alpr_results = self.predict(img)

    for result in alpr_results:
        detection = result.detection
        ocr_result = result.ocr
        bbox = detection.bounding_box
        x1, y1, x2, y2 = bbox.x1, bbox.y1, bbox.x2, bbox.y2
        # Draw the bounding box
        cv2.rectangle(img, (x1, y1), (x2, y2), (36, 255, 12), 2)
        if ocr_result is None or not ocr_result.text or not ocr_result.confidence:
            continue
        confidence: float = (
            statistics.mean(ocr_result.confidence)
            if isinstance(ocr_result.confidence, list)
            else ocr_result.confidence
        )
        font_scale = min(1.25, max(0.4, img.shape[1] / 1000))
        text_thickness = 1 if font_scale < 0.75 else 2
        outline_thickness = text_thickness + max(3, round(font_scale * 3))
        display_lines = [f"{ocr_result.text} {confidence * 100:.0f}%"]
        if ocr_result.region:
            region_text = ocr_result.region
            if ocr_result.region_confidence is not None:
                region_text = f"{region_text} {ocr_result.region_confidence * 100:.0f}%"
            display_lines.insert(0, region_text)

        _, text_height = cv2.getTextSize(
            display_lines[0], cv2.FONT_HERSHEY_SIMPLEX, font_scale, text_thickness
        )[0]
        line_gap = max(14, round(text_height * 0.6))
        line_height = text_height + line_gap
        text_y = y1 - 10 - ((len(display_lines) - 1) * line_height)
        if text_y - text_height < 0:
            text_y = y2 + text_height + 10

        for idx, line in enumerate(display_lines):
            text_width, current_text_height = cv2.getTextSize(
                line, cv2.FONT_HERSHEY_SIMPLEX, font_scale, text_thickness
            )[0]
            text_x = min(max(x1, 5), max(5, img.shape[1] - text_width - 5))
            current_y = min(
                max(text_y + (idx * line_height), current_text_height + 5),
                img.shape[0] - 5,
            )
            # Draw black background for better readability
            cv2.putText(
                img=img,
                text=line,
                org=(text_x, current_y),
                fontFace=cv2.FONT_HERSHEY_SIMPLEX,
                fontScale=font_scale,
                color=(0, 0, 0),
                thickness=outline_thickness,
                lineType=cv2.LINE_AA,
            )
            # Draw white text
            cv2.putText(
                img=img,
                text=line,
                org=(text_x, current_y),
                fontFace=cv2.FONT_HERSHEY_SIMPLEX,
                fontScale=font_scale,
                color=(255, 255, 255),
                thickness=text_thickness,
                lineType=cv2.LINE_AA,
            )

    return DrawPredictionsResult(image=img, results=alpr_results)

Result Types

ALPRResult dataclass

ALPRResult(
    detection: DetectionResult, ocr: OcrResult | None
)

Detection and OCR output for one license plate.

Attributes:

Name Type Description
detection DetectionResult

Detector output for the plate.

ocr OcrResult | None

OCR output for the plate, or None if OCR does not return a result.

DrawPredictionsResult dataclass

DrawPredictionsResult(
    image: ndarray, results: list[ALPRResult]
)

Return value from draw_predictions.

Attributes:

Name Type Description
image ndarray

The input image with boxes and text drawn on it.

results list[ALPRResult]

The ALPR results used to draw the annotations.

OcrResult dataclass

OcrResult(
    text: str,
    confidence: float | list[float],
    region: str | None = None,
    region_confidence: float | None = None,
)

OCR output for one cropped plate image.

Attributes:

Name Type Description
text str

Recognized plate text.

confidence float | list[float]

OCR confidence as one value or one value per character.

region str | None

Optional region or country prediction.

region_confidence float | None

Confidence for the region prediction.

Interfaces

BaseDetector

Bases: ABC

Functions

predict abstractmethod

predict(frame: ndarray) -> list[DetectionResult]

Perform detection on the input frame and return a list of detections.

Source code in fast_alpr/base.py
@abstractmethod
def predict(self, frame: np.ndarray) -> list[DetectionResult]:
    """Perform detection on the input frame and return a list of detections."""

BaseOCR

Bases: ABC

Functions

predict abstractmethod

predict(cropped_plate: ndarray) -> OcrResult | None

Perform OCR on the cropped plate image and return the recognized text and character probabilities.

Source code in fast_alpr/base.py
@abstractmethod
def predict(self, cropped_plate: np.ndarray) -> OcrResult | None:
    """Perform OCR on the cropped plate image and return the recognized text and character
    probabilities."""

External Types

See BoundingBox and DetectionResult.