///|
/// Performance metrics for live video processing.
pub(all) struct PerformanceStats {
fps : Double
frame_latency_ms : Double
threshold_time_ms : Double
contour_time_ms : Double
decode_time_ms : Double
pose_time_ms : Double
num_markers_detected : Int
} derive(Debug, Eq)
///|
/// Creates a new PerformanceStats record.
pub fn PerformanceStats::new(
fps : Double,
frame_latency_ms : Double,
threshold_time_ms : Double,
contour_time_ms : Double,
decode_time_ms : Double,
pose_time_ms : Double,
num_markers_detected : Int,
) -> PerformanceStats {
{
fps,
frame_latency_ms,
threshold_time_ms,
contour_time_ms,
decode_time_ms,
pose_time_ms,
num_markers_detected,
}
}
///|
/// Formats a complete visual terminal status dashboard for real-time video analytics.
pub fn render_terminal_dashboard(
stats : PerformanceStats,
active_tracks : Array[MarkerTrack],
) -> String {
let buf = StringBuilder()
buf.write_string(
"┌────────────────────────────────────────────────────────────────────────┐\n",
)
buf.write_string(
"│ MoonBit Fiducial Marker Real-Time Analytics Dashboard │\n",
)
buf.write_string(
"├────────────────────────────────────┬───────────────────────────────────┤\n",
)
buf.write_string(
"│ Performance & Latency Metrics │ Multi-Target Tracking Status │\n",
)
buf.write_string(
"├────────────────────────────────────┼───────────────────────────────────┤\n",
)
buf.write_string(
"│ FPS: \{stats.fps.to_int()} FPS │ Active Tracks: \{active_tracks.length()} tracks │\n",
)
buf.write_string(
"│ Total Latency: \{stats.frame_latency_ms} ms │ Markers Detected: \{stats.num_markers_detected} markers │\n",
)
buf.write_string(
"│ - Threshold: \{stats.threshold_time_ms} ms │ │\n",
)
buf.write_string(
"│ - Contours: \{stats.contour_time_ms} ms │ │\n",
)
buf.write_string(
"│ - Bit Decoding: \{stats.decode_time_ms} ms │ │\n",
)
buf.write_string(
"│ - 6DOF Pose: \{stats.pose_time_ms} ms │ │\n",
)
buf.write_string(
"├────────────────────────────────────┴───────────────────────────────────┤\n",
)
buf.write_string(
"│ Tracked Targets List: │\n",
)
if active_tracks.length() == 0 {
buf.write_string(
"│ (No active marker tracks currently visible) │\n",
)
} else {
for t in active_tracks {
let p = t.filter.pose()
buf.write_string(
"│ Track #\{t.track_id} (Marker ID: \{t.marker_id}) -> Pos: [X: \{p.tvec.x}, Y: \{p.tvec.y}, Z: \{p.tvec.z}] m │\n",
)
}
}
buf.write_string(
"└────────────────────────────────────────────────────────────────────────┘\n",
)
buf.to_string()
}