1use std::collections::BTreeMap;
3
4use serde::{Deserialize, Serialize};
5
6use braid_types::{CamNum, TrackingParams};
7
8#[derive(Debug, Serialize, Deserialize, Clone)]
9pub struct BraidMetadata {
10 pub schema: u16, pub git_revision: String,
13 pub original_recording_time: Option<chrono::DateTime<chrono::Local>>,
14 pub save_empty_data2d: bool,
15 #[serde(default = "default_saving_program_name")]
20 pub saving_program_name: String,
21}
22
23fn default_saving_program_name() -> String {
24 "".to_string()
25}
26
27#[derive(Debug, Serialize, Deserialize, Clone)]
34pub struct BraidzSummary {
35 pub filename: String,
37 pub filesize: u64,
39 pub metadata: BraidMetadata,
40 pub cam_info: CamInfo,
41 pub expected_fps: f64,
42 pub calibration_info: Option<CalibrationSummary>,
43 pub data2d_summary: Option<Data2dSummary>,
44 pub kalman_estimates_summary: Option<KalmanEstimatesSummary>,
45 pub reconstruct_latency_usec_summary: Option<HistogramSummary>,
46 pub reprojection_distance_100x_pixels_summary: Option<HistogramSummary>,
47}
48
49#[derive(Debug, Serialize, Deserialize, Clone)]
51pub struct CalibrationSummary {
52 pub water: Option<f64>,
54 pub cameras: Vec<CameraSummary>,
56}
57
58impl From<CalibrationInfo> for CalibrationSummary {
59 fn from(orig: CalibrationInfo) -> Self {
60 Self {
61 water: orig.water,
62 cameras: orig
63 .cameras
64 .cams_by_name()
65 .iter()
66 .map(|(name, cam)| CameraSummary::new(name, cam))
67 .collect(),
68 }
69 }
70}
71
72#[derive(Debug, Serialize, Deserialize, Clone)]
74pub struct CameraSummary {
75 pub name: String,
76 pub camera_center: (f64, f64, f64),
77 pub fx: f64,
78 pub fy: f64,
79 pub distortion: Option<Vec<f64>>,
80}
81
82impl CameraSummary {
83 pub fn new(name: &str, cam: &braid_mvg::Camera<f64>) -> Self {
84 let cc = cam.extrinsics().camcenter();
85 let fx = cam.intrinsics().fx();
86 let fy = cam.intrinsics().fy();
87 let d = &cam.intrinsics().distortion;
88 let distortion = if d.is_linear() {
89 None
90 } else {
91 Some(d.opencv_vec().iter().map(Clone::clone).collect())
92 };
93 Self {
94 name: name.into(),
95 camera_center: (cc[0], cc[1], cc[2]),
96 distortion,
97 fx,
98 fy,
99 }
100 }
101}
102
103#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
104pub struct CamInfo {
105 pub camn2camid: BTreeMap<CamNum, String>,
106 pub camid2camn: BTreeMap<String, CamNum>,
107}
108
109#[derive(Debug, Serialize, Deserialize, Clone)]
110pub struct HistogramSummary {
111 pub len: u64,
113 pub mean: f64,
114 pub min: u64,
115 pub max: u64,
116}
117
118#[derive(Debug, Serialize, Deserialize, Clone)]
119pub struct CalibrationInfo {
120 pub water: Option<f64>,
122 pub cameras: braid_mvg::MultiCameraSystem<f64>,
124}
125
126#[derive(Debug, Serialize, Deserialize, Clone)]
127pub struct Data2dSummary {
128 pub num_cameras_with_data: u16,
129 pub num_rows: u64,
130 pub frame_limits: [u64; 2],
131 pub time_limits: [chrono::DateTime<chrono::Utc>; 2],
132}
133
134#[derive(Debug, Serialize, Deserialize, Clone)]
135pub struct KalmanEstimatesSummary {
136 pub num_trajectories: u32,
137 pub x_limits: [f64; 2],
138 pub y_limits: [f64; 2],
139 pub z_limits: [f64; 2],
140 pub num_rows: u64,
141 pub tracking_parameters: TrackingParams,
142 pub total_distance: f64,
144}
145
146pub fn camera_name_from_filename<P: AsRef<std::path::Path>>(
147 full_path: P,
148) -> (String, Option<String>) {
149 let filename = full_path
150 .as_ref()
151 .file_name()
152 .unwrap()
153 .to_os_string()
154 .to_str()
155 .unwrap()
156 .to_string();
157
158 const MOVIE_REGEXP: &str = r"^movie\d{8}_\d{6}(?:.?\d*)_(.*).(?:mp4|mkv|fmf|h264|fmf\.gz)$";
159 let movie_re = regex::Regex::new(MOVIE_REGEXP).unwrap();
160 let cam_from_filename = movie_re.captures(&filename).map(|caps| {
161 caps.get(1).unwrap().as_str().to_string()
163 });
164 (filename, cam_from_filename)
165}
166
167#[test]
168fn test_cam_from_filename() {
169 let fname1 = "dir1/movie20211108_084523_Basler-22445994.mp4";
171 let (_, cam) = camera_name_from_filename(fname1);
172 assert_eq!(cam, Some("Basler-22445994".to_string()));
173
174 let fname2 = "movie20240302_144852.000002145_Basler-40454395.mp4";
176 let (_, cam) = camera_name_from_filename(fname2);
177 assert_eq!(cam, Some("Basler-40454395".to_string()));
178}