mirror of
https://github.com/blakeblackshear/frigate.git
synced 2025-08-08 13:51:01 +02:00
LPR tweaks (#17783)
* clarify docs * improve debugging messages * don't run any lpr postprocessing * wording
This commit is contained in:
parent
19aaa64fe9
commit
14a32a6472
@ -184,7 +184,7 @@ cameras:
|
|||||||
ffmpeg: ... # add your streams
|
ffmpeg: ... # add your streams
|
||||||
detect:
|
detect:
|
||||||
enabled: True
|
enabled: True
|
||||||
fps: 5 # increase to 10 if vehicles move quickly across your frame. Higher than 10 is unnecessary and is not recommended.
|
fps: 5 # increase to 10 if vehicles move quickly across your frame. Higher than 15 is unnecessary and is not recommended.
|
||||||
min_initialized: 2
|
min_initialized: 2
|
||||||
width: 1920
|
width: 1920
|
||||||
height: 1080
|
height: 1080
|
||||||
@ -267,7 +267,7 @@ With this setup:
|
|||||||
- Review items will always be classified as a `detection`.
|
- Review items will always be classified as a `detection`.
|
||||||
- Snapshots will always be saved.
|
- Snapshots will always be saved.
|
||||||
- Zones and object masks are **not** used.
|
- Zones and object masks are **not** used.
|
||||||
- The `frigate/events` MQTT topic will **not** publish tracked object updates, though `frigate/reviews` will if recordings are enabled.
|
- The `frigate/events` MQTT topic will **not** publish tracked object updates with the license plate bounding box and score, though `frigate/reviews` will publish if recordings are enabled. If a plate is recognized as a known plate, publishing will occur with an updated `sub_label` field. If characters are recognized, publishing will occur with an updated `recognized_license_plate` field.
|
||||||
- License plate snapshots are saved at the highest-scoring moment and appear in Explore.
|
- License plate snapshots are saved at the highest-scoring moment and appear in Explore.
|
||||||
- Debug view will not show `license_plate` bounding boxes.
|
- Debug view will not show `license_plate` bounding boxes.
|
||||||
|
|
||||||
@ -280,7 +280,7 @@ With this setup:
|
|||||||
| Object Detection | Standard Frigate+ detection applies | Bypasses standard object detection |
|
| Object Detection | Standard Frigate+ detection applies | Bypasses standard object detection |
|
||||||
| Zones & Object Masks | Supported | Not supported |
|
| Zones & Object Masks | Supported | Not supported |
|
||||||
| Debug View | May show `license_plate` bounding boxes | May **not** show `license_plate` bounding boxes |
|
| Debug View | May show `license_plate` bounding boxes | May **not** show `license_plate` bounding boxes |
|
||||||
| MQTT `frigate/events` | Publishes tracked object updates | Does **not** publish tracked object updates |
|
| MQTT `frigate/events` | Publishes tracked object updates | Publishes limited updates |
|
||||||
| Explore | Recognized plates available in More Filters | Recognized plates available in More Filters |
|
| Explore | Recognized plates available in More Filters | Recognized plates available in More Filters |
|
||||||
|
|
||||||
By selecting the appropriate configuration, users can optimize their dedicated LPR cameras based on whether they are using a Frigate+ model or the secondary LPR pipeline.
|
By selecting the appropriate configuration, users can optimize their dedicated LPR cameras based on whether they are using a Frigate+ model or the secondary LPR pipeline.
|
||||||
|
@ -513,10 +513,14 @@ class FrigateConfig(FrigateBaseModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Warn if detect fps > 10
|
# Warn if detect fps > 10
|
||||||
if camera_config.detect.fps > 10:
|
if camera_config.detect.fps > 10 and camera_config.type != "lpr":
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f"{camera_config.name} detect fps is set to {camera_config.detect.fps}. This does NOT need to match your camera's frame rate. High values could lead to reduced performance. Recommended value is 5."
|
f"{camera_config.name} detect fps is set to {camera_config.detect.fps}. This does NOT need to match your camera's frame rate. High values could lead to reduced performance. Recommended value is 5."
|
||||||
)
|
)
|
||||||
|
if camera_config.detect.fps > 15 and camera_config.type == "lpr":
|
||||||
|
logger.warning(
|
||||||
|
f"{camera_config.name} detect fps is set to {camera_config.detect.fps}. This does NOT need to match your camera's frame rate. High values could lead to reduced performance. Recommended value for LPR cameras are between 5-15."
|
||||||
|
)
|
||||||
|
|
||||||
# Default min_initialized configuration
|
# Default min_initialized configuration
|
||||||
min_initialized = int(camera_config.detect.fps / 2)
|
min_initialized = int(camera_config.detect.fps / 2)
|
||||||
|
@ -490,10 +490,6 @@ class LicensePlateProcessingMixin:
|
|||||||
merged_boxes.append(current_box)
|
merged_boxes.append(current_box)
|
||||||
current_box = next_box
|
current_box = next_box
|
||||||
|
|
||||||
logger.debug(
|
|
||||||
f"Provided plate_width: {plate_width}, max_gap: {max_gap}, horizontal_gap: {horizontal_gap}"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Add the last box
|
# Add the last box
|
||||||
merged_boxes.append(current_box)
|
merged_boxes.append(current_box)
|
||||||
|
|
||||||
@ -1133,7 +1129,7 @@ class LicensePlateProcessingMixin:
|
|||||||
# 4. Log the comparison
|
# 4. Log the comparison
|
||||||
logger.debug(
|
logger.debug(
|
||||||
f"Plate comparison - Current: {top_plate} (score: {curr_score:.3f}, min_conf: {curr_min_conf:.2f}) vs "
|
f"Plate comparison - Current: {top_plate} (score: {curr_score:.3f}, min_conf: {curr_min_conf:.2f}) vs "
|
||||||
f"Previous: {prev_plate} (score: {prev_score:.3f}, min_conf: {prev_min_conf:.2f})\n"
|
f"Previous: {prev_plate} (score: {prev_score:.3f}, min_conf: {prev_min_conf:.2f}) "
|
||||||
f"Metrics - Length: {len(top_plate)} vs {len(prev_plate)} (scores: {curr_length_score:.2f} vs {prev_length_score:.2f}), "
|
f"Metrics - Length: {len(top_plate)} vs {len(prev_plate)} (scores: {curr_length_score:.2f} vs {prev_length_score:.2f}), "
|
||||||
f"Area: {top_area} vs {prev_area}, "
|
f"Area: {top_area} vs {prev_area}, "
|
||||||
f"Avg Conf: {avg_confidence:.2f} vs {prev_avg_confidence:.2f}, "
|
f"Avg Conf: {avg_confidence:.2f} vs {prev_avg_confidence:.2f}, "
|
||||||
@ -1263,6 +1259,15 @@ class LicensePlateProcessingMixin:
|
|||||||
)
|
)
|
||||||
return
|
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
|
||||||
|
|
||||||
license_plate: Optional[dict[str, any]] = None
|
license_plate: Optional[dict[str, any]] = None
|
||||||
|
|
||||||
if "license_plate" not in self.config.cameras[camera].objects.track:
|
if "license_plate" not in self.config.cameras[camera].objects.track:
|
||||||
@ -1401,6 +1406,8 @@ class LicensePlateProcessingMixin:
|
|||||||
license_plate_frame,
|
license_plate_frame,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
logger.debug(f"{camera}: Running plate recognition.")
|
||||||
|
|
||||||
# run detection, returns results sorted by confidence, best first
|
# run detection, returns results sorted by confidence, best first
|
||||||
start = datetime.datetime.now().timestamp()
|
start = datetime.datetime.now().timestamp()
|
||||||
license_plates, confidences, areas = self._process_license_plate(
|
license_plates, confidences, areas = self._process_license_plate(
|
||||||
|
@ -54,6 +54,9 @@ class LicensePlatePostProcessor(LicensePlateProcessingMixin, PostProcessorApi):
|
|||||||
Returns:
|
Returns:
|
||||||
None.
|
None.
|
||||||
"""
|
"""
|
||||||
|
# don't run LPR post processing for now
|
||||||
|
return
|
||||||
|
|
||||||
event_id = data["event_id"]
|
event_id = data["event_id"]
|
||||||
camera_name = data["camera"]
|
camera_name = data["camera"]
|
||||||
|
|
||||||
|
@ -138,11 +138,13 @@ class TrackedObject:
|
|||||||
|
|
||||||
if not self.false_positive and has_valid_frame:
|
if not self.false_positive and has_valid_frame:
|
||||||
# determine if this frame is a better thumbnail
|
# determine if this frame is a better thumbnail
|
||||||
if self.thumbnail_data is None or is_better_thumbnail(
|
if self.thumbnail_data is None or (
|
||||||
self.obj_data["label"],
|
better_thumb := is_better_thumbnail(
|
||||||
self.thumbnail_data,
|
self.obj_data["label"],
|
||||||
obj_data,
|
self.thumbnail_data,
|
||||||
self.camera_config.frame_shape,
|
obj_data,
|
||||||
|
self.camera_config.frame_shape,
|
||||||
|
)
|
||||||
):
|
):
|
||||||
# use the current frame time if the object's frame time isn't in the frame cache
|
# use the current frame time if the object's frame time isn't in the frame cache
|
||||||
selected_frame_time = (
|
selected_frame_time = (
|
||||||
@ -150,6 +152,13 @@ class TrackedObject:
|
|||||||
if obj_data["frame_time"] not in self.frame_cache.keys()
|
if obj_data["frame_time"] not in self.frame_cache.keys()
|
||||||
else obj_data["frame_time"]
|
else obj_data["frame_time"]
|
||||||
)
|
)
|
||||||
|
if (
|
||||||
|
obj_data["frame_time"] not in self.frame_cache.keys()
|
||||||
|
and not better_thumb
|
||||||
|
):
|
||||||
|
logger.warning(
|
||||||
|
f"Frame time {obj_data['frame_time']} not in frame cache, using current frame time {selected_frame_time}"
|
||||||
|
)
|
||||||
self.thumbnail_data = {
|
self.thumbnail_data = {
|
||||||
"frame_time": selected_frame_time,
|
"frame_time": selected_frame_time,
|
||||||
"box": obj_data["box"],
|
"box": obj_data["box"],
|
||||||
|
Loading…
Reference in New Issue
Block a user