fast-alpr

repository·master·Indexed 20 days ago

https://github.com/ankandrew/fast-alpr

A high-performance Automatic License Plate Recognition (ALPR) system using optimized ONNX models for plate detection and OCR. Version 0.4.0 supports multiple ONNX runtimes including CPU, CUDA, OpenVINO, DirectML, and QNN. It provides the ALPR class for processing images via .predict() and .draw_predictions(), and allows for custom OCR engine integration by extending the BaseOCR class.

Tokens
6.9K
Snippets
24
Records
29
Agent score
70%

What's inside fast-alpr

  1. Overview of FastALPR

    master

    FastALPR is a high-performance, customizable Automatic License Plate Recognition (ALPR) system. It is designed for speed and flexibility, utilizing ONNX models for optimized performance via ONNX Runtime.

    By default, the system uses:

    • License Plate Detection: open-image-models
    • OCR (Optical Character Recognition): fast-plate-ocr

    Users can swap these default models for any custom detection or OCR models they choose.

  2. Understand FastALPR result types

    master

    FastALPR uses several structured types to return data:

    • ALPRResult: The primary output for a single detection. It includes detection (location/confidence) and ocr (text/confidence).
    • DrawPredictionsResult: The output when using drawing methods. It bundles the annotated image with the results list.
    • OcrResult: Contains the text recognized by the OCR engine and its associated confidence score.

    Note: BoundingBox and DetectionResult are external types provided by open-image-models.

  3. Implement a custom OCR engine by extending BaseOCR

    master

    You can replace the default OCR engine by subclassing BaseOCR and implementing the predict method. The predict method receives a cropped_plate as a numpy.ndarray and must return an OcrResult object (containing text and confidence) or None.

    import re
    from statistics import mean
    import numpy as np
    import pytesseract
    from fast_alpr.alpr import ALPR, BaseOCR, OcrResult
    
    class PytesseractOCR(BaseOCR):
        def __init__(self) -> None:
            pass
    
        def predict(self, cropped_plate: np.ndarray) -> OcrResult | None:
            if cropped_plate is None:
                return None
            # Example using pytesseract
            data = pytesseract.image_to_data(
                cropped_plate,
                lang="eng",
                config="--oem 3 --psm 6",
                output_type=pytesseract.Output.DICT,
            )
            plate_text = " ".join(data["text"]).strip()
            plate_text = re.sub(r"[^A-Za-z0-9]", "", plate_text)
            avg_confidence = mean(conf for conf in data["conf"] if conf > 0) / 100.0
            return OcrResult(text=plate_text, confidence=avg_confidence)
    
    # Usage with custom OCR
    alpr = ALPR(detector_model="yolo-v9-t-384-license-plate-end2end", ocr=PytesseractOCR())
    results = alpr.predict("assets/test_image.png")
  4. Get predictions with ALPR.predict()

    master

    To perform Automatic License Plate Recognition (ALPR), initialize the ALPR class and call the .predict() method. You can pass a file path to an image or a NumPy array containing a cropped plate image. The ALPR constructor allows you to specify custom detector_model and ocr_model strings to customize the detection and recognition behavior.

    from fast_alpr import ALPR
    
    # Initialize with specific models
    alpr = ALPR(
        detector_model="yolo-v9-t-384-license-plate-end2end",
        ocr_model="cct-xs-v2-global-model",
    )
    
    # Predict using an image path or a NumPy array
    alpr_results = alpr.predict("assets/test_image.png")
    print(alpr_results)
  5. Install fast-alpr for inference

    master

    To use fast-alpr for inference, you must install the package along with an ONNX runtime extra. By default, no ONNX runtime is installed. Choose the extra that matches your hardware:

    • CPU (cross-platform): Use onnx.
    • NVIDIA GPU (CUDA): Use onnx-gpu.
    • Intel CPU / VPU: Use onnx-openvino.
    • Windows (DirectML): Use onnx-directml.
    • Qualcomm mobile chips: Use onnx-qnn.
    pip install fast-alpr[onnx-gpu]
  6. Import FastALPR components

    master

    To use FastALPR, import the main ALPR class and the result types for type hinting or processing.

    from fast_alpr import ALPR, ALPRResult, DrawPredictionsResult, OcrResult
    from fast_alpr import ALPR, ALPRResult, DrawPredictionsResult, OcrResult
  7. Draw predictions on an image with ALPR.draw_predictions()

    master

    If you need to visualize the detection results, use the .draw_predictions() method. This method accepts a NumPy array (typically loaded via OpenCV) and returns an object containing both the annotated image and the raw results.

    Access the annotated image via the .image attribute and the detection data via the .results attribute of the returned object.

    import cv2
    from fast_alpr import ALPR
    
    # Initialize the ALPR
    alpr = ALPR(
        detector_model="yolo-v9-t-384-license-plate-end2end",
        ocr_model="cct-xs-v2-global-model",
    )
    
    # Load the image using OpenCV
    image_path = "assets/test_image.png"
    frame = cv2.imread(image_path)
    
    # Draw predictions on the image
    drawn = alpr.draw_predictions(frame)
    
    # Extract the annotated image and the results
    annotated_frame = drawn.image
    results = drawn.results
  8. Install FastALPR with ONNX runtimes

    master

    FastALPR requires an ONNX backend to perform inference. By default, no ONNX runtime is installed. Choose the installation command based on your hardware and platform:

    Platform/Use CaseInstall Command
    CPU (default)pip install fast-alpr[onnx]
    NVIDIA GPU (CUDA)pip install fast-alpr[onnx-gpu]
    Intel (OpenVINO)pip install fast-alpr[onnx-openvino]
    Windows (DirectML)pip install fast-alpr[onnx-directml]
    Qualcomm (QNN)pip install fast-alpr[onnx-qnn]
    pip install fast-alpr[onnx-gpu]
  9. Integrate custom OCR engines using BaseOCR

    master

    FastALPR allows you to replace the default OCR engine by implementing a custom class that inherits from BaseOCR. To integrate a new engine (like Tesseract or EasyOCR), you must implement the predict method, which accepts a np.ndarray representing the cropped license plate and returns an OcrResult object or None.

    import numpy as np
    import pytesseract
    import re
    from statistics import mean
    from fast_alpr.alpr import ALPR, BaseOCR, OcrResult
    
    class PytesseractOCR(BaseOCR):
        def __init__(self) -> None:
            pass
    
        def predict(self, cropped_plate: np.ndarray) -> OcrResult | None:
            if cropped_plate is None:
                return None
            
            # Example implementation using pytesseract
            data = pytesseract.image_to_data(
                cropped_plate,
                lang="eng",
                config="--oem 3 --psm 6",
                output_type=pytesseract.Output.DICT,
            )
            
            plate_text = " ".join(data["text"]).strip()
            plate_text = re.sub(r"[^A-Za-z0-9]", "", plate_text)
            avg_confidence = mean(conf for conf in data["conf"] if conf > 0) / 100.0
            
            return OcrResult(text=plate_text, confidence=avg_confidence)
    
    # Initialize ALPR with the custom OCR
    alpr = ALPR(detector_model="yolo-v9-t-384-license-plate-end2end", ocr=PytesseractOCR())
    
    alpr_results = alpr.predict("assets/test_image.png")
    print(alpr_results)
  10. Implement PytesseractOCR for Tesseract integration

    master

    To use Tesseract OCR within FastALPR, create a PytesseractOCR class inheriting from BaseOCR. In the predict method, use pytesseract.image_to_data to extract text and confidence scores. Ensure you clean the resulting text (e.g., removing non-alphanumeric characters) and return an OcrResult containing the cleaned text and the calculated confidence.

    class PytesseractOCR(BaseOCR):
        def __init__(self) -> None:
            """
            Init PytesseractOCR.
            """
    
        def predict(self, cropped_plate: np.ndarray) -> OcrResult | None:
            if cropped_plate is None:
                return None
            # You can change 'eng' to the appropriate language code as needed
            data = pytesseract.image_to_data(
                cropped_plate,
                lang="eng",
                config="--oem 3 --psm 6",
                output_type=pytesseract.Output.DICT,
            )
            plate_text = " ".join(data["text"]).strip()
            plate_text = re.sub(r"[^A-Za-z0-9]", "", plate_text)
            avg_confidence = mean(conf for conf in data["conf"] if conf > 0) / 100.0
            return OcrResult(text=plate_text, confidence=avg_confidence)
  11. Use the ALPR class for license plate recognition

    master

    The ALPR class is the primary entry point. You can initialize it with default models or specify custom detector_model and ocr_model names. Use the .predict() method to process an image file and receive recognition results.

    from fast_alpr import ALPR
    
    alpr = ALPR(
        detector_model="yolo-v9-t-384-license-plate-end2end",
        ocr_model="cct-xs-v2-global-model",
    )
    
    alpr_results = alpr.predict("assets/test_image.png")
    print(alpr_results)
  12. Annotate images with ALPR.draw_predictions()

    master

    Use ALPR.draw_predictions() to obtain an image with bounding boxes and text overlays drawn on it, alongside the structured data.

    Inputs:

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

    Returns:

    • A DrawPredictionsResult object containing:
      • image: The annotated NumPy image.
      • results: The list[ALPRResult] used for the drawing.
    # Example usage (conceptual)
    alpr = ALPR()
    draw_result = alpr.draw_predictions("path/to/image.png")
    # draw_result.image contains the annotated image
    # draw_result.results contains the ALPR data