mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-18 00:54:27 +03:00
add average speed
This commit is contained in:
parent
03db156c20
commit
d3ce58cbf4
@ -153,7 +153,7 @@ ui:
|
||||
unit_system: metric
|
||||
```
|
||||
|
||||
The maximum speed during the object's lifetime is saved in Frigate's database and can be seen in the UI in the Tracked Object Details pane in Explore. Current estimated speed can also be seen on the debug view as the third value in the object label. Current estimated speed, max estimated speed, and velocity angle (the angle of the direction the object is moving relative to the frame) of tracked objects is also sent through the `events` MQTT topic. See the [MQTT docs](../integrations/mqtt.md#frigateevents).
|
||||
The average and maximum speed during the object's lifetime is saved in Frigate's database and can be seen in the UI in the Tracked Object Details pane in Explore. Current estimated speed can also be seen on the debug view as the third value in the object label. Current estimated speed, average estimated speed, max estimated speed, and velocity angle (the angle of the direction the object is moving relative to the frame) of tracked objects is also sent through the `events` MQTT topic. See the [MQTT docs](../integrations/mqtt.md#frigateevents).
|
||||
|
||||
#### Best practices and caveats
|
||||
|
||||
|
||||
@ -322,6 +322,7 @@ def events_explore(limit: int = 10):
|
||||
"top_score",
|
||||
"description",
|
||||
"sub_label_score",
|
||||
"average_estimated_speed",
|
||||
"max_estimated_speed",
|
||||
]
|
||||
},
|
||||
@ -595,6 +596,7 @@ def events_search(request: Request, params: EventsSearchQueryParams = Depends())
|
||||
"top_score",
|
||||
"description",
|
||||
"sub_label_score",
|
||||
"average_estimated_speed",
|
||||
"max_estimated_speed",
|
||||
]
|
||||
}
|
||||
|
||||
@ -25,6 +25,8 @@ def should_update_db(prev_event: Event, current_event: Event) -> bool:
|
||||
or prev_event["entered_zones"] != current_event["entered_zones"]
|
||||
or prev_event["thumbnail"] != current_event["thumbnail"]
|
||||
or prev_event["end_time"] != current_event["end_time"]
|
||||
or prev_event["average_estimated_speed"]
|
||||
!= current_event["average_estimated_speed"]
|
||||
or prev_event["max_estimated_speed"] != current_event["max_estimated_speed"]
|
||||
):
|
||||
return True
|
||||
@ -210,6 +212,7 @@ class EventProcessor(threading.Thread):
|
||||
"score": score,
|
||||
"top_score": event_data["top_score"],
|
||||
"attributes": attributes,
|
||||
"average_estimated_speed": event_data["average_estimated_speed"],
|
||||
"max_estimated_speed": event_data["max_estimated_speed"],
|
||||
"type": "object",
|
||||
"max_severity": event_data.get("max_severity"),
|
||||
|
||||
@ -62,7 +62,9 @@ class TrackedObject:
|
||||
self.frame = None
|
||||
self.active = True
|
||||
self.pending_loitering = False
|
||||
self.estimated_speed = 0
|
||||
self.speed_history = []
|
||||
self.current_estimated_speed = 0
|
||||
self.average_estimated_speed = 0
|
||||
self.max_estimated_speed = 0
|
||||
self.velocity_angle = 0
|
||||
self.previous = self.to_dict()
|
||||
@ -197,16 +199,22 @@ class TrackedObject:
|
||||
)
|
||||
if self.ui_config.unit_system == "metric":
|
||||
# Convert m/s to km/h
|
||||
self.estimated_speed = speed_magnitude * 3.6
|
||||
self.current_estimated_speed = speed_magnitude * 3.6
|
||||
elif self.ui_config.unit_system == "imperial":
|
||||
# Convert ft/s to mph
|
||||
self.estimated_speed = speed_magnitude * 0.681818
|
||||
self.current_estimated_speed = speed_magnitude * 0.681818
|
||||
|
||||
logger.debug(
|
||||
f"Camera: {self.camera_config.name}, zone: {name}, tracked object ID: {self.obj_data['id']}, pixel velocity: {str(tuple(np.round(self.obj_data['estimate_velocity']).flatten().astype(int)))} estimated speed: {self.estimated_speed:.1f}"
|
||||
f"Camera: {self.camera_config.name}, zone: {name}, tracked object ID: {self.obj_data['id']}, pixel velocity: {str(tuple(np.round(self.obj_data['estimate_velocity']).flatten().astype(int)))} estimated speed: {self.current_estimated_speed:.1f}"
|
||||
)
|
||||
|
||||
if self.estimated_speed > self.max_estimated_speed:
|
||||
self.max_estimated_speed = self.estimated_speed
|
||||
self.speed_history.append(self.current_estimated_speed)
|
||||
self.average_estimated_speed = sum(self.speed_history) / len(
|
||||
self.speed_history
|
||||
)
|
||||
|
||||
if self.current_estimated_speed > self.max_estimated_speed:
|
||||
self.max_estimated_speed = self.current_estimated_speed
|
||||
|
||||
# update loitering status
|
||||
self.pending_loitering = in_loitering_zone
|
||||
@ -289,7 +297,8 @@ class TrackedObject:
|
||||
"current_attributes": self.obj_data["attributes"],
|
||||
"pending_loitering": self.pending_loitering,
|
||||
"max_severity": self.max_severity,
|
||||
"estimated_speed": self.estimated_speed,
|
||||
"current_estimated_speed": self.current_estimated_speed,
|
||||
"average_estimated_speed": self.average_estimated_speed,
|
||||
"max_estimated_speed": self.max_estimated_speed,
|
||||
"velocity_angle": self.velocity_angle,
|
||||
}
|
||||
|
||||
@ -316,6 +316,18 @@ function ObjectDetailsTab({
|
||||
}
|
||||
}, [search]);
|
||||
|
||||
const averageEstimatedSpeed = useMemo(() => {
|
||||
if (!search || !search.data?.average_estimated_speed) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (search.data?.average_estimated_speed != 0) {
|
||||
return search.data?.average_estimated_speed.toFixed(1);
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}, [search]);
|
||||
|
||||
const maxEstimatedSpeed = useMemo(() => {
|
||||
if (!search || !search.data?.max_estimated_speed) {
|
||||
return undefined;
|
||||
@ -439,12 +451,24 @@ function ObjectDetailsTab({
|
||||
{score}%{subLabelScore && ` (${subLabelScore}%)`}
|
||||
</div>
|
||||
</div>
|
||||
{maxEstimatedSpeed && (
|
||||
{(averageEstimatedSpeed || maxEstimatedSpeed) && (
|
||||
<div className="flex flex-col gap-1.5">
|
||||
<div className="text-sm text-primary/40">Max Estimated Speed</div>
|
||||
<div className="text-sm">
|
||||
{maxEstimatedSpeed}{" "}
|
||||
{config?.ui.unit_system == "imperial" ? "mph" : "kph"}
|
||||
<div className="text-sm text-primary/40">Estimated Speeds</div>
|
||||
<div className="flex flex-col space-y-0.5 text-sm">
|
||||
{averageEstimatedSpeed && (
|
||||
<div>
|
||||
{averageEstimatedSpeed}{" "}
|
||||
{config?.ui.unit_system == "imperial" ? "mph" : "kph"}{" "}
|
||||
<span className="text-primary/40">(average)</span>
|
||||
</div>
|
||||
)}
|
||||
{maxEstimatedSpeed && (
|
||||
<div>
|
||||
{maxEstimatedSpeed}{" "}
|
||||
{config?.ui.unit_system == "imperial" ? "mph" : "kph"}{" "}
|
||||
<span className="text-primary/40">(maximum)</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@ -55,6 +55,7 @@ export type SearchResult = {
|
||||
ratio: number;
|
||||
type: "object" | "audio" | "manual";
|
||||
description?: string;
|
||||
average_estimated_speed: number;
|
||||
max_estimated_speed: number;
|
||||
};
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user