Add stationary scan duration for LPR (#20444)

This commit is contained in:
Josh Hawkins
2025-10-12 06:20:14 -06:00
committed by GitHub
parent 78d487045b
commit a2ad77c36e
2 changed files with 34 additions and 13 deletions
@@ -48,6 +48,9 @@ class LicensePlateProcessingMixin:
MODEL_CACHE_DIR, "paddleocr-onnx", "ppocr_keys_v1.txt"
)
)
# process plates that are stationary and have no position changes for 5 seconds
self.stationary_scan_duration = 5
self.batch_size = 6
# Object config
@@ -1269,21 +1272,39 @@ class LicensePlateProcessingMixin:
)
return
# don't run for stationary car objects
if obj_data.get("stationary") == True:
# don't run for non-stationary objects with no position changes to avoid processing uncertain moving objects
# zero position_changes is the initial state after registering a new tracked object
# LPR will run 2 frames after detect.min_initialized is reached
if obj_data.get("position_changes", 0) == 0 and not obj_data.get(
"stationary", False
):
logger.debug(
f"{camera}: Not a processing license plate for a stationary car/motorcycle object."
f"{camera}: Skipping LPR for non-stationary {obj_data['label']} object {id} with no position changes. (Detected in {self.config.cameras[camera].detect.min_initialized + 1} concurrent frames, threshold to run is {self.config.cameras[camera].detect.min_initialized + 2} frames)"
)
return
# don't run for objects with no position changes
# this is the initial state after registering a new tracked object
# LPR will run 2 frames after detect.min_initialized is reached
if obj_data.get("position_changes", 0) == 0:
logger.debug(
f"{camera}: Plate detected in {self.config.cameras[camera].detect.min_initialized + 1} concurrent frames, LPR frame threshold ({self.config.cameras[camera].detect.min_initialized + 2})"
)
return
# run for stationary objects for a limited time after they become stationary
if obj_data.get("stationary") == True:
threshold = self.config.cameras[camera].detect.stationary.threshold
if obj_data.get("motionless_count", 0) >= threshold:
frames_since_stationary = (
obj_data.get("motionless_count", 0) - threshold
)
fps = self.config.cameras[camera].detect.fps
time_since_stationary = frames_since_stationary / fps
# only print this log for a short time to avoid log spam
if (
self.stationary_scan_duration
< time_since_stationary
<= self.stationary_scan_duration + 1
):
logger.debug(
f"{camera}: {obj_data.get('label', 'An')} object {id} has been stationary for > {self.stationary_scan_duration} seconds, skipping LPR."
)
if time_since_stationary > self.stationary_scan_duration:
return
license_plate: Optional[dict[str, Any]] = None
@@ -1424,7 +1445,7 @@ class LicensePlateProcessingMixin:
license_plate_frame,
)
logger.debug(f"{camera}: Running plate recognition.")
logger.debug(f"{camera}: Running plate recognition for id: {id}.")
# run detection, returns results sorted by confidence, best first
start = datetime.datetime.now().timestamp()