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