Skip to content

Commit 921908f

Browse files
authored
LPR device selection (#17592)
* config changes * use device * docs * docs * reset state * remove auto * use device * docs
1 parent cb27bdb commit 921908f

File tree

5 files changed

+27
-7
lines changed

5 files changed

+27
-7
lines changed

docs/docs/configuration/license_plate_recognition.md

+8-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ When a plate is recognized, the recognized name is:
1919

2020
Users running a Frigate+ model (or any custom model that natively detects license plates) should ensure that `license_plate` is added to the [list of objects to track](https://docs.frigate.video/plus/#available-label-types) either globally or for a specific camera. This will improve the accuracy and performance of the LPR model.
2121

22-
Users without a model that detects license plates can still run LPR. Frigate uses a lightweight YOLOv9 license plate detection model that runs on your CPU or GPU. In this case, you should _not_ define `license_plate` in your list of objects to track.
22+
Users without a model that detects license plates can still run LPR. Frigate uses a lightweight YOLOv9 license plate detection model that can be configured to run on your CPU or GPU. In this case, you should _not_ define `license_plate` in your list of objects to track.
2323

2424
:::note
2525

@@ -29,7 +29,7 @@ In the default mode, Frigate's LPR needs to first detect a `car` before it can r
2929

3030
## Minimum System Requirements
3131

32-
License plate recognition works by running AI models locally on your system. The models are relatively lightweight and will be auto-selected to run on your CPU. At least 4GB of RAM is required.
32+
License plate recognition works by running AI models locally on your system. The models are relatively lightweight and can run on your CPU or GPU, depending on your configuration. At least 4GB of RAM is required.
3333

3434
## Configuration
3535

@@ -66,6 +66,9 @@ Fine-tune the LPR feature using these optional parameters:
6666
- **`min_area`**: Defines the minimum area (in pixels) a license plate must be before recognition runs.
6767
- Default: `1000` pixels. Note: this is intentionally set very low as it is an _area_ measurement (length x width). For reference, 1000 pixels represents a ~32x32 pixel square in your camera image.
6868
- Depending on the resolution of your camera's `detect` stream, you can increase this value to ignore small or distant plates.
69+
- **`device`**: Device to use to run license plate recognition models.
70+
- Default: `CPU`
71+
- This can be `CPU` or `GPU`. For users without a model that detects license plates natively, using a GPU may increase performance of the models, especially the YOLOv9 license plate detector model.
6972

7073
### Recognition
7174

@@ -167,6 +170,7 @@ An example configuration for a dedicated LPR camera using a Frigate+ model:
167170
# LPR global configuration
168171
lpr:
169172
enabled: True
173+
device: CPU # can also be GPU if available
170174
171175
# Dedicated LPR camera configuration
172176
cameras:
@@ -218,6 +222,7 @@ An example configuration for a dedicated LPR camera using the secondary pipeline
218222
# LPR global configuration
219223
lpr:
220224
enabled: True
225+
device: CPU # can also be GPU if available
221226
detection_threshold: 0.7 # change if necessary
222227
223228
# Dedicated LPR camera configuration
@@ -280,7 +285,7 @@ By selecting the appropriate configuration, users can optimize their dedicated L
280285
- Disable the `improve_contrast` motion setting, especially if you are running LPR at night and the frame is mostly dark. This will prevent small pixel changes and smaller areas of motion from triggering license plate detection.
281286
- Ensure your camera's timestamp is covered with a motion mask so that it's not incorrectly detected as a license plate.
282287
- For non-Frigate+ users, you may need to change your camera settings for a clearer image or decrease your global `recognition_threshold` config if your plates are not being accurately recognized at night.
283-
- The secondary pipeline mode runs a local AI model on your CPU or GPU (auto-selected) to detect plates. Increasing detect `fps` will increase resource usage proportionally.
288+
- The secondary pipeline mode runs a local AI model on your CPU or GPU (depending on how `device` is configured) to detect plates. Increasing detect `fps` will increase resource usage proportionally.
284289

285290
## FAQ
286291

frigate/config/classification.py

+9
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ class SemanticSearchModelEnum(str, Enum):
1919
jinav2 = "jinav2"
2020

2121

22+
class LPRDeviceEnum(str, Enum):
23+
GPU = "GPU"
24+
CPU = "CPU"
25+
26+
2227
class BirdClassificationConfig(FrigateBaseModel):
2328
enabled: bool = Field(default=False, title="Enable bird classification.")
2429
threshold: float = Field(
@@ -94,6 +99,10 @@ class CameraFaceRecognitionConfig(FrigateBaseModel):
9499

95100
class LicensePlateRecognitionConfig(FrigateBaseModel):
96101
enabled: bool = Field(default=False, title="Enable license plate recognition.")
102+
device: Optional[LPRDeviceEnum] = Field(
103+
default=LPRDeviceEnum.CPU,
104+
title="The device used for license plate recognition.",
105+
)
97106
detection_threshold: float = Field(
98107
default=0.7,
99108
title="License plate object confidence score required to begin running recognition.",

frigate/data_processing/common/license_plate/model.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ class LicensePlateModelRunner(DataProcessorModelRunner):
1212
def __init__(self, requestor, device: str = "CPU", model_size: str = "large"):
1313
super().__init__(requestor, device, model_size)
1414
self.detection_model = PaddleOCRDetection(
15-
model_size=model_size, requestor=requestor, device="CPU"
15+
model_size=model_size, requestor=requestor, device=device
1616
)
1717
self.classification_model = PaddleOCRClassification(
18-
model_size=model_size, requestor=requestor, device="CPU"
18+
model_size=model_size, requestor=requestor, device=device
1919
)
2020
self.recognition_model = PaddleOCRRecognition(
21-
model_size=model_size, requestor=requestor, device="CPU"
21+
model_size=model_size, requestor=requestor, device=device
2222
)
2323
self.yolov9_detection_model = LicensePlateDetector(
2424
model_size=model_size, requestor=requestor, device=device

frigate/embeddings/maintainer.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,9 @@ def __init__(
108108

109109
# model runners to share between realtime and post processors
110110
if self.config.lpr.enabled:
111-
lpr_model_runner = LicensePlateModelRunner(self.requestor, device="AUTO")
111+
lpr_model_runner = LicensePlateModelRunner(
112+
self.requestor, device=self.config.lpr.device
113+
)
112114

113115
# realtime processors
114116
self.realtime_processors: list[RealTimeProcessorApi] = []

frigate/embeddings/onnx/runner.py

+4
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ def run(self, input: dict[str, Any]) -> Any:
9494
if self.type == "ov":
9595
infer_request = self.interpreter.create_infer_request()
9696

97+
# This ensures the model starts with a clean state for each sequence
98+
# Important for RNN models like PaddleOCR recognition
99+
infer_request.reset_state()
100+
97101
outputs = infer_request.infer(input)
98102

99103
return outputs

0 commit comments

Comments
 (0)