Optionally show tracked object paths in debug view (#19025)

This commit is contained in:
Josh Hawkins 2025-07-07 09:33:19 -05:00 committed by GitHub
parent 57bb0cc397
commit d97b451d12
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 62 additions and 0 deletions

View File

@ -18,6 +18,7 @@ class MediaLatestFrameQueryParams(BaseModel):
zones: Optional[int] = None
mask: Optional[int] = None
motion: Optional[int] = None
paths: Optional[int] = None
regions: Optional[int] = None
quality: Optional[int] = 70
height: Optional[int] = None

View File

@ -141,6 +141,7 @@ def latest_frame(
"zones": params.zones,
"mask": params.mask,
"motion_boxes": params.motion,
"paths": params.paths,
"regions": params.regions,
}
quality = params.quality

View File

@ -228,6 +228,45 @@ class CameraState:
position=self.camera_config.timestamp_style.position,
)
if draw_options.get("paths"):
for obj in tracked_objects.values():
if obj["frame_time"] == frame_time and obj["path_data"]:
color = self.config.model.colormap.get(
obj["label"], (255, 255, 255)
)
path_points = [
(
int(point[0][0] * self.camera_config.detect.width),
int(point[0][1] * self.camera_config.detect.height),
)
for point in obj["path_data"]
]
for point in path_points:
cv2.circle(frame_copy, point, 5, color, -1)
for i in range(1, len(path_points)):
cv2.line(
frame_copy,
path_points[i - 1],
path_points[i],
color,
2,
)
bottom_center = (
int((obj["box"][0] + obj["box"][2]) / 2),
int(obj["box"][3]),
)
cv2.line(
frame_copy,
path_points[-1],
bottom_center,
color,
2,
)
return frame_copy
def finished(self, obj_id):

View File

@ -439,6 +439,11 @@
"desc": "Show a box of the region of interest sent to the object detector",
"tips": "<p><strong>Region Boxes</strong></p><br><p>Bright green boxes will be overlaid on areas of interest in the frame that are being sent to the object detector.</p>"
},
"paths": {
"title": "Paths",
"desc": "Show significant points of the tracked object's path",
"tips": "<p><strong>Paths</strong></p><br><p>Lines and circles will indicate significant points the tracked object has moved during its lifecycle.</p>"
},
"objectShapeFilterDrawing": {
"title": "Object Shape Filter Drawing",
"desc": "Draw a rectangle on the image to view area and ratio details",

View File

@ -158,6 +158,16 @@ function DebugSettings({ handleSetOption, options }: DebugSettingsProps) {
/>
<Label htmlFor="regions">{t("debug.regions")}</Label>
</div>
<div className="flex items-center space-x-2">
<Switch
id="paths"
checked={options["paths"]}
onCheckedChange={(isChecked) => {
handleSetOption("paths", isChecked);
}}
/>
<Label htmlFor="paths">{t("debug.paths")}</Label>
</div>
</div>
);
}

View File

@ -89,6 +89,12 @@ export default function ObjectSettingsView({
description: t("debug.regions.desc"),
info: <Trans ns="views/settings">debug.regions.tips</Trans>,
},
{
param: "paths",
title: t("debug.paths.title"),
description: t("debug.paths.desc"),
info: <Trans ns="views/settings">debug.paths.tips</Trans>,
},
];
const [options, setOptions, optionsLoaded] = usePersistence<Options>(