Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ def generate_radar_json(
return {
"radar_points": radar_points,
"radar_size": [radar_w, radar_h],
"detection_count": len(radar_points),
}


Expand Down Expand Up @@ -287,6 +288,7 @@ def radar_json_with_annotated_frame(
return {
"radar_points": radar_points,
"radar_size": [radar_w, radar_h],
"detection_count": len(radar_points),
"radar_base64": _encode_radar_to_base64(radar_image),
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@
},
"outputs": {
"frames": "array",
"total_frames": "integer"
"total_frames": "integer",
"summary": "object"
}
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ def on_unload(self) -> None: # pragma: no cover # noqa: B027
from forgesyte_yolo_tracker.inference.radar import radar_json_with_annotated_frame
from forgesyte_yolo_tracker.configs import load_model_config
from forgesyte_yolo_tracker.utils.json_sanitize import sanitize_json
from forgesyte_yolo_tracker.utils.summary import compute_video_summary

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -310,12 +311,14 @@ def _run_video_tool(
logger.info(f"Completed: {frame_index} frames")

# v0.10.0: Sanitize output for JSON serialization
sanitized = sanitize_json({
"total_frames": frame_index,
"frames": frame_results,
})
sanitized["summary"] = compute_video_summary(sanitized["frames"])
return {
"success": True,
"result": sanitize_json({
"total_frames": frame_index,
"frames": frame_results,
})
"result": sanitized,
}


Expand Down Expand Up @@ -486,10 +489,12 @@ def _tool_video_player_tracking(
frame_index += 1

# v0.10.0: Sanitize output for JSON serialization
return sanitize_json({
sanitized = sanitize_json({
"total_frames": frame_index,
"frames": frame_results,
})
sanitized["summary"] = compute_video_summary(sanitized["frames"])
return sanitized


class Plugin(BasePlugin): # type: ignore[misc]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
Custom forgeSYTE modules:
- ball.py - Ball tracking (not annotating)
- soccer_pitch.py - Soccer pitch drawing utilities
- summary.py - Video summary computation utilities
"""

from . import ball, soccer_pitch
from .summary import compute_video_summary

# Lazy import to avoid torch/transformers at module load time
def __getattr__(name: str):
Expand All @@ -33,6 +35,8 @@ def __getattr__(name: str):
"create_batches",
"TeamClassifier",
"ViewTransformer",
# Video summary
"compute_video_summary",
# Custom forgeSYTE modules
"ball",
"soccer_pitch",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
"""Video summary computation utilities.

Provides functions to compute aggregated metadata from video tool results.
"""

import logging
from typing import Any, Dict, List

logger = logging.getLogger(__name__)


# Registry pattern for detection extraction (avoid elif chains)
_DETECTION_FIELD_MAP: Dict[str, str] = {
"detections": "detections",
"tracked_objects": "tracked_objects",
"radar_points": "radar_points",
}


def _get_detections_from_frame(frame: Dict[str, Any]) -> List[Dict[str, Any]]:
"""Extract detections list from frame using registry lookup.

Args:
frame: Frame result dictionary

Returns:
List of detection dicts, or empty list if not found
"""
for field_name in _DETECTION_FIELD_MAP.values():
if field_name in frame:
return frame[field_name]
return []


def compute_video_summary(frames: List[Dict[str, Any]]) -> Dict[str, int]:
"""Compute aggregated summary metadata from video tool frames.

Args:
frames: List of frame results from video processing

Returns:
Dictionary with:
- detection_count: Total detections across all frames
- frame_count: Number of frames processed
"""
total_detection_count = 0

for frame in frames:
detections = _get_detections_from_frame(frame)
total_detection_count += len(detections)

logger.info(
f"Video summary: {total_detection_count} detections across {len(frames)} frames"
)

return {
"detection_count": total_detection_count,
"frame_count": len(frames),
}
Loading