forked from Github/frigate
Compare commits
3 Commits
v0.10.0-be
...
v0.10.0-be
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5714f5fbc | ||
|
|
3be0b915ad | ||
|
|
304ffa86e8 |
@@ -159,11 +159,23 @@ detect:
|
|||||||
enabled: True
|
enabled: True
|
||||||
# Optional: Number of frames without a detection before frigate considers an object to be gone. (default: 5x the frame rate)
|
# Optional: Number of frames without a detection before frigate considers an object to be gone. (default: 5x the frame rate)
|
||||||
max_disappeared: 25
|
max_disappeared: 25
|
||||||
# Optional: Frequency for running detection on stationary objects (default: shown below)
|
# Optional: Configuration for stationary object tracking
|
||||||
# When set to 0, object detection will never be run on stationary objects. If set to 10, it will be run on every 10th frame.
|
stationary:
|
||||||
stationary_interval: 0
|
# Optional: Frequency for running detection on stationary objects (default: shown below)
|
||||||
# Optional: Number of frames without a position change for an object to be considered stationary (default: 10x the frame rate or 10s)
|
# When set to 0, object detection will never be run on stationary objects. If set to 10, it will be run on every 10th frame.
|
||||||
stationary_threshold: 50
|
interval: 0
|
||||||
|
# Optional: Number of frames without a position change for an object to be considered stationary (default: 10x the frame rate or 10s)
|
||||||
|
threshold: 50
|
||||||
|
# Optional: Define a maximum number of frames for tracking a stationary object (default: not set, track forever)
|
||||||
|
# This can help with false positives for objects that should only be stationary for a limited amount of time.
|
||||||
|
# It can also be used to disable stationary object tracking. For example, you may want to set a value for person, but leave
|
||||||
|
# car at the default.
|
||||||
|
max_frames:
|
||||||
|
# Optional: Default for all object types (default: not set, track forever)
|
||||||
|
default: 3000
|
||||||
|
# Optional: Object specific values
|
||||||
|
objects:
|
||||||
|
person: 1000
|
||||||
|
|
||||||
# Optional: Object configuration
|
# Optional: Object configuration
|
||||||
# NOTE: Can be overridden at the camera level
|
# NOTE: Can be overridden at the camera level
|
||||||
|
|||||||
@@ -162,6 +162,29 @@ class RuntimeMotionConfig(MotionConfig):
|
|||||||
extra = Extra.ignore
|
extra = Extra.ignore
|
||||||
|
|
||||||
|
|
||||||
|
class StationaryMaxFramesConfig(FrigateBaseModel):
|
||||||
|
default: Optional[int] = Field(title="Default max frames.", ge=1)
|
||||||
|
objects: Dict[str, int] = Field(
|
||||||
|
default_factory=dict, title="Object specific max frames."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class StationaryConfig(FrigateBaseModel):
|
||||||
|
interval: Optional[int] = Field(
|
||||||
|
default=0,
|
||||||
|
title="Frame interval for checking stationary objects.",
|
||||||
|
ge=0,
|
||||||
|
)
|
||||||
|
threshold: Optional[int] = Field(
|
||||||
|
title="Number of frames without a position change for an object to be considered stationary",
|
||||||
|
ge=1,
|
||||||
|
)
|
||||||
|
max_frames: StationaryMaxFramesConfig = Field(
|
||||||
|
default_factory=StationaryMaxFramesConfig,
|
||||||
|
title="Max frames for stationary objects.",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class DetectConfig(FrigateBaseModel):
|
class DetectConfig(FrigateBaseModel):
|
||||||
height: int = Field(default=720, title="Height of the stream for the detect role.")
|
height: int = Field(default=720, title="Height of the stream for the detect role.")
|
||||||
width: int = Field(default=1280, title="Width of the stream for the detect role.")
|
width: int = Field(default=1280, title="Width of the stream for the detect role.")
|
||||||
@@ -172,14 +195,9 @@ class DetectConfig(FrigateBaseModel):
|
|||||||
max_disappeared: Optional[int] = Field(
|
max_disappeared: Optional[int] = Field(
|
||||||
title="Maximum number of frames the object can dissapear before detection ends."
|
title="Maximum number of frames the object can dissapear before detection ends."
|
||||||
)
|
)
|
||||||
stationary_interval: Optional[int] = Field(
|
stationary: StationaryConfig = Field(
|
||||||
default=0,
|
default_factory=StationaryConfig,
|
||||||
title="Frame interval for checking stationary objects.",
|
title="Stationary objects config.",
|
||||||
ge=0,
|
|
||||||
)
|
|
||||||
stationary_threshold: Optional[int] = Field(
|
|
||||||
title="Number of frames without a position change for an object to be considered stationary",
|
|
||||||
ge=1,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -772,8 +790,8 @@ class FrigateConfig(FrigateBaseModel):
|
|||||||
|
|
||||||
# Default stationary_threshold configuration
|
# Default stationary_threshold configuration
|
||||||
stationary_threshold = camera_config.detect.fps * 10
|
stationary_threshold = camera_config.detect.fps * 10
|
||||||
if camera_config.detect.stationary_threshold is None:
|
if camera_config.detect.stationary.threshold is None:
|
||||||
camera_config.detect.stationary_threshold = stationary_threshold
|
camera_config.detect.stationary.threshold = stationary_threshold
|
||||||
|
|
||||||
# FFMPEG input substitution
|
# FFMPEG input substitution
|
||||||
for input in camera_config.ffmpeg.inputs:
|
for input in camera_config.ffmpeg.inputs:
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ class TrackedObject:
|
|||||||
# if the motionless_count reaches the stationary threshold
|
# if the motionless_count reaches the stationary threshold
|
||||||
if (
|
if (
|
||||||
self.obj_data["motionless_count"]
|
self.obj_data["motionless_count"]
|
||||||
== self.camera_config.detect.stationary_threshold
|
== self.camera_config.detect.stationary.threshold
|
||||||
):
|
):
|
||||||
significant_change = True
|
significant_change = True
|
||||||
|
|
||||||
@@ -194,7 +194,7 @@ class TrackedObject:
|
|||||||
"area": self.obj_data["area"],
|
"area": self.obj_data["area"],
|
||||||
"region": self.obj_data["region"],
|
"region": self.obj_data["region"],
|
||||||
"stationary": self.obj_data["motionless_count"]
|
"stationary": self.obj_data["motionless_count"]
|
||||||
> self.camera_config.detect.stationary_threshold,
|
> self.camera_config.detect.stationary.threshold,
|
||||||
"motionless_count": self.obj_data["motionless_count"],
|
"motionless_count": self.obj_data["motionless_count"],
|
||||||
"position_changes": self.obj_data["position_changes"],
|
"position_changes": self.obj_data["position_changes"],
|
||||||
"current_zones": self.current_zones.copy(),
|
"current_zones": self.current_zones.copy(),
|
||||||
|
|||||||
@@ -93,18 +93,40 @@ class ObjectTracker:
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def is_expired(self, id):
|
||||||
|
obj = self.tracked_objects[id]
|
||||||
|
# get the max frames for this label type or the default
|
||||||
|
max_frames = self.detect_config.stationary.max_frames.objects.get(
|
||||||
|
obj["label"], self.detect_config.stationary.max_frames.default
|
||||||
|
)
|
||||||
|
|
||||||
|
# if there is no max_frames for this label type, continue
|
||||||
|
if max_frames is None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# if the object has exceeded the max_frames setting, deregister
|
||||||
|
if (
|
||||||
|
obj["motionless_count"] - self.detect_config.stationary.threshold
|
||||||
|
> max_frames
|
||||||
|
):
|
||||||
|
print(f"expired: {obj['motionless_count']}")
|
||||||
|
return True
|
||||||
|
|
||||||
def update(self, id, new_obj):
|
def update(self, id, new_obj):
|
||||||
self.disappeared[id] = 0
|
self.disappeared[id] = 0
|
||||||
# update the motionless count if the object has not moved to a new position
|
# update the motionless count if the object has not moved to a new position
|
||||||
if self.update_position(id, new_obj["box"]):
|
if self.update_position(id, new_obj["box"]):
|
||||||
self.tracked_objects[id]["motionless_count"] += 1
|
self.tracked_objects[id]["motionless_count"] += 1
|
||||||
|
if self.is_expired(id):
|
||||||
|
self.deregister(id)
|
||||||
|
return
|
||||||
else:
|
else:
|
||||||
# register the first position change and then only increment if
|
# register the first position change and then only increment if
|
||||||
# the object was previously stationary
|
# the object was previously stationary
|
||||||
if (
|
if (
|
||||||
self.tracked_objects[id]["position_changes"] == 0
|
self.tracked_objects[id]["position_changes"] == 0
|
||||||
or self.tracked_objects[id]["motionless_count"]
|
or self.tracked_objects[id]["motionless_count"]
|
||||||
>= self.detect_config.stationary_threshold
|
>= self.detect_config.stationary.threshold
|
||||||
):
|
):
|
||||||
self.tracked_objects[id]["position_changes"] += 1
|
self.tracked_objects[id]["position_changes"] += 1
|
||||||
self.tracked_objects[id]["motionless_count"] = 0
|
self.tracked_objects[id]["motionless_count"] = 0
|
||||||
@@ -112,9 +134,11 @@ class ObjectTracker:
|
|||||||
self.tracked_objects[id].update(new_obj)
|
self.tracked_objects[id].update(new_obj)
|
||||||
|
|
||||||
def update_frame_times(self, frame_time):
|
def update_frame_times(self, frame_time):
|
||||||
for id in self.tracked_objects.keys():
|
for id in list(self.tracked_objects.keys()):
|
||||||
self.tracked_objects[id]["frame_time"] = frame_time
|
self.tracked_objects[id]["frame_time"] = frame_time
|
||||||
self.tracked_objects[id]["motionless_count"] += 1
|
self.tracked_objects[id]["motionless_count"] += 1
|
||||||
|
if self.is_expired(id):
|
||||||
|
self.deregister(id)
|
||||||
|
|
||||||
def match_and_update(self, frame_time, new_objects):
|
def match_and_update(self, frame_time, new_objects):
|
||||||
# group by name
|
# group by name
|
||||||
|
|||||||
@@ -511,8 +511,8 @@ def process_frames(
|
|||||||
if obj["motionless_count"] >= 10
|
if obj["motionless_count"] >= 10
|
||||||
# and it isn't due for a periodic check
|
# and it isn't due for a periodic check
|
||||||
and (
|
and (
|
||||||
detect_config.stationary_interval == 0
|
detect_config.stationary.interval == 0
|
||||||
or obj["motionless_count"] % detect_config.stationary_interval != 0
|
or obj["motionless_count"] % detect_config.stationary.interval != 0
|
||||||
)
|
)
|
||||||
# and it hasn't disappeared
|
# and it hasn't disappeared
|
||||||
and object_tracker.disappeared[obj["id"]] == 0
|
and object_tracker.disappeared[obj["id"]] == 0
|
||||||
|
|||||||
Reference in New Issue
Block a user