lab-camera-optimizer 1.0.2__tar.gz → 1.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. {lab_camera_optimizer-1.0.2/lab_camera_optimizer.egg-info → lab_camera_optimizer-1.1.0}/PKG-INFO +23 -4
  2. {lab_camera_optimizer-1.0.2 → lab_camera_optimizer-1.1.0}/README.md +22 -3
  3. lab_camera_optimizer-1.1.0/configs/ISM_fast.yaml +108 -0
  4. lab_camera_optimizer-1.1.0/configs/evaluate_labo_CHU.yaml +212 -0
  5. lab_camera_optimizer-1.1.0/configs/example_evaluation_CHU.yaml +66 -0
  6. lab_camera_optimizer-1.1.0/configs/labo_CHU_10ZED_3iPad.yaml +136 -0
  7. lab_camera_optimizer-1.1.0/configs/labo_CHU_bis.yaml +190 -0
  8. {lab_camera_optimizer-1.0.2 → lab_camera_optimizer-1.1.0}/core/candidates.py +42 -18
  9. lab_camera_optimizer-1.1.0/core/combo_worker.py +171 -0
  10. {lab_camera_optimizer-1.0.2 → lab_camera_optimizer-1.1.0}/core/config_loader.py +175 -3
  11. lab_camera_optimizer-1.1.0/core/greedy.py +536 -0
  12. lab_camera_optimizer-1.1.0/core/reporting.py +82 -0
  13. {lab_camera_optimizer-1.0.2 → lab_camera_optimizer-1.1.0}/core/room.py +40 -8
  14. lab_camera_optimizer-1.1.0/core/scoring.py +433 -0
  15. {lab_camera_optimizer-1.0.2 → lab_camera_optimizer-1.1.0}/core/visualize.py +81 -50
  16. lab_camera_optimizer-1.1.0/evaluate.py +167 -0
  17. {lab_camera_optimizer-1.0.2 → lab_camera_optimizer-1.1.0}/init_project.py +23 -12
  18. lab_camera_optimizer-1.1.0/lab_camera_optimizer/__init__.py +3 -0
  19. lab_camera_optimizer-1.1.0/lab_camera_optimizer/configs/T_zone_direction_change.yaml +200 -0
  20. lab_camera_optimizer-1.1.0/lab_camera_optimizer/configs/evaluate_labo_CHU.yaml +212 -0
  21. lab_camera_optimizer-1.1.0/lab_camera_optimizer/configs/example_evaluation_CHU.yaml +66 -0
  22. lab_camera_optimizer-1.1.0/lab_camera_optimizer/configs/example_real_world.yaml +270 -0
  23. lab_camera_optimizer-1.1.0/lab_camera_optimizer/configs/example_simple.yaml +180 -0
  24. lab_camera_optimizer-1.1.0/lab_camera_optimizer/configs/labo_CHU.yaml +268 -0
  25. lab_camera_optimizer-1.1.0/lab_camera_optimizer/configs/labo_CHU_bis.yaml +190 -0
  26. {lab_camera_optimizer-1.0.2 → lab_camera_optimizer-1.1.0/lab_camera_optimizer.egg-info}/PKG-INFO +23 -4
  27. lab_camera_optimizer-1.1.0/lab_camera_optimizer.egg-info/SOURCES.txt +44 -0
  28. {lab_camera_optimizer-1.0.2 → lab_camera_optimizer-1.1.0}/lab_camera_optimizer.egg-info/entry_points.txt +1 -0
  29. {lab_camera_optimizer-1.0.2 → lab_camera_optimizer-1.1.0}/lab_camera_optimizer.egg-info/top_level.txt +2 -0
  30. {lab_camera_optimizer-1.0.2 → lab_camera_optimizer-1.1.0}/optimize.py +260 -216
  31. {lab_camera_optimizer-1.0.2 → lab_camera_optimizer-1.1.0}/pyproject.toml +5 -4
  32. lab_camera_optimizer-1.1.0/tests/test_candidates.py +67 -0
  33. lab_camera_optimizer-1.1.0/tests/test_config_loader.py +291 -0
  34. lab_camera_optimizer-1.1.0/tests/test_room.py +272 -0
  35. lab_camera_optimizer-1.1.0/tests/test_scoring.py +199 -0
  36. lab_camera_optimizer-1.0.2/core/greedy.py +0 -470
  37. lab_camera_optimizer-1.0.2/core/scoring.py +0 -248
  38. lab_camera_optimizer-1.0.2/lab_camera_optimizer.egg-info/SOURCES.txt +0 -24
  39. {lab_camera_optimizer-1.0.2 → lab_camera_optimizer-1.1.0}/LICENSE +0 -0
  40. {lab_camera_optimizer-1.0.2 → lab_camera_optimizer-1.1.0}/MANIFEST.in +0 -0
  41. {lab_camera_optimizer-1.0.2 → lab_camera_optimizer-1.1.0}/configs/T_zone_direction_change.yaml +0 -0
  42. {lab_camera_optimizer-1.0.2 → lab_camera_optimizer-1.1.0}/configs/example_real_world.yaml +0 -0
  43. {lab_camera_optimizer-1.0.2 → lab_camera_optimizer-1.1.0}/configs/example_simple.yaml +0 -0
  44. {lab_camera_optimizer-1.0.2 → lab_camera_optimizer-1.1.0}/configs/labo_CHU.yaml +0 -0
  45. {lab_camera_optimizer-1.0.2 → lab_camera_optimizer-1.1.0}/core/__init__.py +0 -0
  46. {lab_camera_optimizer-1.0.2 → lab_camera_optimizer-1.1.0}/lab_camera_optimizer.egg-info/dependency_links.txt +0 -0
  47. {lab_camera_optimizer-1.0.2 → lab_camera_optimizer-1.1.0}/lab_camera_optimizer.egg-info/requires.txt +0 -0
  48. {lab_camera_optimizer-1.0.2 → lab_camera_optimizer-1.1.0}/preview_room.py +0 -0
  49. {lab_camera_optimizer-1.0.2 → lab_camera_optimizer-1.1.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lab-camera-optimizer
3
- Version: 1.0.2
3
+ Version: 1.1.0
4
4
  Summary: Automated camera placement optimiser for markerless biomechanics motion capture labs
5
5
  Author: Florian Delaplace
6
6
  License-Expression: MIT
@@ -41,7 +41,8 @@ all evaluation points, with optional bilateral coverage constraints.
41
41
 
42
42
  - **Any room shape** — define any polygon floor plan (L-shaped, rectangular, etc.)
43
43
  - **Obstacles & walls** — pillars, partial-height furniture, irregular wall segments
44
- - **Multiple camera sets** — wall-mounted cameras + optional tripod cameras
44
+ - **Multiple camera sets** — wall-mounted cameras + tripod cameras, both placed by the same zone-wide optimiser
45
+ - **Camera budget** — fix an exact count per set, *or* give a total and let the optimiser choose the wall/tripod split (`total_cameras` + per-set `count_min`/`count_max`)
45
46
  - **Per-camera height variation** — each camera in the same configuration can be at a different height
46
47
  - **3D visibility** — checks both horizontal FOV and vertical body coverage (0 → subject height)
47
48
  - **Line-of-sight** — occlusion by walls and floor-to-ceiling obstacles
@@ -207,12 +208,25 @@ camera_sets:
207
208
  height_options: [2.0, 2.2] # tested heights (metres)
208
209
  max_range: 10.0
209
210
  min_range: 0.5
210
- max_count: 8
211
+ count_max: 8 # max cameras of this set (alias: max_count)
212
+ count_min: 0 # min cameras of this set (free mode only)
211
213
  min_spacing: 1.2
212
- score_weight: 1.0
214
+ score_weight: 1.0 # weight of this set in the score
215
+ score_factor: 1.0 # extra per-set multiplier (e.g. 0.5 to down-weight)
213
216
  color: "#1f77b4"
214
217
  ```
215
218
 
219
+ #### Camera budget — fixed vs free allocation
220
+
221
+ ```yaml
222
+ optimization:
223
+ # total_cameras absent → FIXED: each set places exactly its count_max
224
+ # (wall-only: tripod count_max 0; "5 wall + 3 tripod": set each count_max)
225
+ # total_cameras present → FREE: the optimiser splits the total across sets
226
+ # within each set's [count_min, count_max] to maximise the score.
227
+ total_cameras: 8
228
+ ```
229
+
216
230
  #### `capture_zones` — where coverage matters
217
231
 
218
232
  **Corridor-based** (walking path):
@@ -266,6 +280,7 @@ optimization:
266
280
  bilateral_weight: 0.8 # 0 = disabled, 1 = fully enforced
267
281
  vertical_coverage_threshold: 0.9
268
282
  restarts_per_combo: 15
283
+ total_cameras: null # null = fixed mode; an int = free allocation
269
284
  algo: "greedy_1opt" # greedy | greedy_1opt
270
285
  early_stop: 5 # stop after N restarts with no improvement
271
286
  graph_mode: "best_per_combo" # all | records_only | best_per_combo
@@ -275,6 +290,10 @@ optimization:
275
290
  distance_quality_factor: 0.001
276
291
  ```
277
292
 
293
+ > **Note:** the `point` (STS) capture zone is **optional**. With no `point` zone
294
+ > declared, cameras simply optimise coverage of the corridor / analysis /
295
+ > polygon zones — useful for tripod-only or pure zone-wide setups.
296
+
278
297
  ### Step 3 — Preview, then run
279
298
 
280
299
  ```bash
@@ -14,7 +14,8 @@ all evaluation points, with optional bilateral coverage constraints.
14
14
 
15
15
  - **Any room shape** — define any polygon floor plan (L-shaped, rectangular, etc.)
16
16
  - **Obstacles & walls** — pillars, partial-height furniture, irregular wall segments
17
- - **Multiple camera sets** — wall-mounted cameras + optional tripod cameras
17
+ - **Multiple camera sets** — wall-mounted cameras + tripod cameras, both placed by the same zone-wide optimiser
18
+ - **Camera budget** — fix an exact count per set, *or* give a total and let the optimiser choose the wall/tripod split (`total_cameras` + per-set `count_min`/`count_max`)
18
19
  - **Per-camera height variation** — each camera in the same configuration can be at a different height
19
20
  - **3D visibility** — checks both horizontal FOV and vertical body coverage (0 → subject height)
20
21
  - **Line-of-sight** — occlusion by walls and floor-to-ceiling obstacles
@@ -180,12 +181,25 @@ camera_sets:
180
181
  height_options: [2.0, 2.2] # tested heights (metres)
181
182
  max_range: 10.0
182
183
  min_range: 0.5
183
- max_count: 8
184
+ count_max: 8 # max cameras of this set (alias: max_count)
185
+ count_min: 0 # min cameras of this set (free mode only)
184
186
  min_spacing: 1.2
185
- score_weight: 1.0
187
+ score_weight: 1.0 # weight of this set in the score
188
+ score_factor: 1.0 # extra per-set multiplier (e.g. 0.5 to down-weight)
186
189
  color: "#1f77b4"
187
190
  ```
188
191
 
192
+ #### Camera budget — fixed vs free allocation
193
+
194
+ ```yaml
195
+ optimization:
196
+ # total_cameras absent → FIXED: each set places exactly its count_max
197
+ # (wall-only: tripod count_max 0; "5 wall + 3 tripod": set each count_max)
198
+ # total_cameras present → FREE: the optimiser splits the total across sets
199
+ # within each set's [count_min, count_max] to maximise the score.
200
+ total_cameras: 8
201
+ ```
202
+
189
203
  #### `capture_zones` — where coverage matters
190
204
 
191
205
  **Corridor-based** (walking path):
@@ -239,6 +253,7 @@ optimization:
239
253
  bilateral_weight: 0.8 # 0 = disabled, 1 = fully enforced
240
254
  vertical_coverage_threshold: 0.9
241
255
  restarts_per_combo: 15
256
+ total_cameras: null # null = fixed mode; an int = free allocation
242
257
  algo: "greedy_1opt" # greedy | greedy_1opt
243
258
  early_stop: 5 # stop after N restarts with no improvement
244
259
  graph_mode: "best_per_combo" # all | records_only | best_per_combo
@@ -248,6 +263,10 @@ optimization:
248
263
  distance_quality_factor: 0.001
249
264
  ```
250
265
 
266
+ > **Note:** the `point` (STS) capture zone is **optional**. With no `point` zone
267
+ > declared, cameras simply optimise coverage of the corridor / analysis /
268
+ > polygon zones — useful for tripod-only or pure zone-wide setups.
269
+
251
270
  ### Step 3 — Preview, then run
252
271
 
253
272
  ```bash
@@ -0,0 +1,108 @@
1
+ # =============================================================
2
+ # ISM lab — FAST preview config (tripod-only)
3
+ # Same room / cameras / zones as example_real_world_ISM, but with
4
+ # coarser candidate grids and fewer restarts for a quick first look.
5
+ # Increase grid resolution + restarts once the layout looks right.
6
+ # =============================================================
7
+
8
+ room:
9
+ corners:
10
+ - [0, 0 ]
11
+ - [0.87, 0 ]
12
+ - [0.87, -0.4]
13
+ - [3.48, -0.4]
14
+ - [3.48, 0]
15
+ - [17.55, 0]
16
+ - [17.55, 8.19]
17
+ - [0, 8.19]
18
+ height: 6.44
19
+
20
+ obstacles:
21
+ - type: rect
22
+ bounds: [7.6, 5.7, 10, 7.2]
23
+ height: 1.5
24
+ label: "Table"
25
+ can_mount_camera: false
26
+
27
+ - type: polygon
28
+ vertices:
29
+ - [5.2, 6.89]
30
+ - [4.7, 7.69]
31
+ - [5.1, 8]
32
+ - [5.65, 7.14]
33
+ height: 1.05
34
+ label: "Console"
35
+ can_mount_camera: false
36
+
37
+ subject:
38
+ height: 2.3
39
+ foot_z: 0.0
40
+
41
+ camera_sets:
42
+ - id: "cam_B"
43
+ name: "tripod setup"
44
+ mounting: "tripod"
45
+ optional: false
46
+ fov_h_landscape: 54.0
47
+ fov_v_landscape: 42.0
48
+ fov_h_portrait: 42.0
49
+ fov_v_portrait: 54.0
50
+ max_range: 9.0
51
+ min_range: 2.0
52
+ height_options: [0.65, 3.0]
53
+ count_max: 18
54
+ min_spacing: 0.5
55
+ walk_axis_margin: 2.0
56
+ score_weight: 1.0
57
+ color: "#1f77b4"
58
+
59
+ - id: "cam_A"
60
+ name: "Wall camera"
61
+ mounting: "wall"
62
+ optional: false
63
+ fov_h_landscape: 110.0
64
+ fov_v_landscape: 70.0
65
+ fov_h_portrait: 70.0
66
+ fov_v_portrait: 110.0
67
+ max_range: 12.0
68
+ min_range: 0.5
69
+ height_options: [2.0, 2.2]
70
+ count_max: 0
71
+ min_spacing: 1.2
72
+ score_weight: 1.0
73
+ color: "#d62728"
74
+
75
+ capture_zones:
76
+ - id: "platform_zone"
77
+ type: "polygon"
78
+ priority: 1
79
+ grid_step: 0.40 # coarser (was 0.20) → fewer eval points
80
+ vertices:
81
+ - [0.0, 0.0]
82
+ - [6.0, 1.0]
83
+ - [6.0, 2.8]
84
+ - [0.0, 1.8]
85
+ placement:
86
+ x_offsets: [3.0]
87
+ y_offsets: [1.5]
88
+
89
+ - id: "treadmill_zone"
90
+ type: "corridor"
91
+ priority: 1
92
+ length: 1.8
93
+ width: 1.0
94
+ placement:
95
+ x_start_options: [1.75]
96
+ y_options: [4.6]
97
+
98
+ optimization:
99
+ target_coverage: 3
100
+ bilateral_weight: 0.9
101
+ vertical_coverage_threshold: 0.85 # slightly relaxed (was 0.90) — the 42° vertical
102
+ # FOV on a 2.3 m subject is geometrically tight
103
+ restarts_per_combo: 4 # fewer (was 10) for a fast first look
104
+ wall_step: 0.35
105
+ tripod_grid_step: 1.10 # coarser (was 0.70) → far fewer tripod candidates
106
+ distance_quality_factor: 0.001
107
+ algo: "greedy_1opt"
108
+ graph_mode: "best_per_combo" # one figure per combo (was "all")
@@ -0,0 +1,212 @@
1
+ # =============================================================
2
+ # Lab Camera Optimizer — Configuration file (EVALUATION MODE)
3
+ # Project : CHU Biomechanics Lab — L-shaped room
4
+ # =============================================================
5
+ # Units : metres for all distances, degrees for all angles.
6
+ # Angles follow the standard mathematical convention:
7
+ # 0° = East (+X), 90° = North (+Y), 180°/-180° = West (-X)
8
+ # =============================================================
9
+
10
+ # ─────────────────────────────────────────────────────────────
11
+ # 1. ROOM GEOMETRY
12
+ # ─────────────────────────────────────────────────────────────
13
+ room:
14
+ corners:
15
+ - [0, 0 ]
16
+ - [13, 0 ]
17
+ - [13, 3.0]
18
+ - [8, 3.0]
19
+ - [8, 4.7]
20
+ - [0, 4.7]
21
+ height: 3.0
22
+
23
+
24
+ # ─────────────────────────────────────────────────────────────
25
+ # 2. OBSTACLES
26
+ # ─────────────────────────────────────────────────────────────
27
+ obstacles:
28
+ - type: rect
29
+ bounds: [1.70, 0.00, 2.04, 0.34]
30
+ height: 3.0
31
+ label: "Stub 1"
32
+ can_mount_camera: true
33
+
34
+ - type: rect
35
+ bounds: [5.39, 0.00, 5.59, 0.42]
36
+ height: 3.0
37
+ label: "Stub 2"
38
+ can_mount_camera: true
39
+
40
+ - type: rect
41
+ bounds: [8.94, 0.00, 9.14, 0.42]
42
+ height: 3.0
43
+ label: "Stub 3"
44
+ can_mount_camera: true
45
+
46
+ - type: rect
47
+ bounds: [5.65, 3.85, 5.85, 4.25]
48
+ height: 3.0
49
+ label: "Stub 4"
50
+ can_mount_camera: true
51
+
52
+ - type: rect
53
+ bounds: [5.65, 2.85, 6.35, 3.55]
54
+ height: 1.4
55
+ label: "Object 1"
56
+ can_mount_camera: false # partial-height object, no camera mount
57
+
58
+ - type: polygon
59
+ vertices:
60
+ - [1.47, 4.70]
61
+ - [1.47, 4.38]
62
+ - [1.71, 4.38]
63
+ - [1.71, 3.88]
64
+ - [2.04, 3.88]
65
+ - [2.04, 4.27]
66
+ - [3.02, 4.27]
67
+ - [3.02, 4.70]
68
+ height: 3.0
69
+ label: "Wall N"
70
+ can_mount_camera: true
71
+
72
+
73
+ # ─────────────────────────────────────────────────────────────
74
+ # 3. SUBJECT (person being recorded)
75
+ # ─────────────────────────────────────────────────────────────
76
+ subject:
77
+ height: 1.9 # total height feet-to-head (metres)
78
+ foot_z: 0.0 # height of feet above floor (metres, usually 0)
79
+
80
+
81
+ # ─────────────────────────────────────────────────────────────
82
+ # 4. CAMERA SETS
83
+ # ─────────────────────────────────────────────────────────────
84
+ camera_sets:
85
+
86
+ - id: "cam_A"
87
+ name: "ZED2i"
88
+ mounting: "wall"
89
+ optional: false
90
+
91
+ fov_h_landscape: 110.0
92
+ fov_v_landscape: 70.0
93
+ fov_h_portrait: 70.0
94
+ fov_v_portrait: 110.0
95
+
96
+ max_range: 15.0
97
+ min_range: 0.5
98
+
99
+ height_options: [2.0, 2.2]
100
+
101
+ max_count: 7
102
+ min_spacing: 1.5
103
+
104
+ score_weight: 1.0
105
+ color: "#1f77b4"
106
+
107
+
108
+ - id: "cam_B"
109
+ name: "iPad"
110
+ mounting: "tripod"
111
+ optional: true
112
+
113
+ fov_h_landscape: 80.0
114
+ fov_v_landscape: 58.0
115
+ fov_h_portrait: 58.0
116
+ fov_v_portrait: 80.0
117
+
118
+ max_range: 10.0
119
+ min_range: 0.5
120
+
121
+ height_options: [1.5]
122
+
123
+ max_count: 2
124
+ min_spacing: 1.5
125
+ walk_axis_margin: 0.7
126
+
127
+ score_weight: 0.6
128
+ color: "#d62728"
129
+
130
+
131
+ # ─────────────────────────────────────────────────────────────
132
+ # 5. CAPTURE ZONES
133
+ # ─────────────────────────────────────────────────────────────
134
+ capture_zones:
135
+
136
+ - id: "full_corridor"
137
+ type: "corridor"
138
+ priority: 0.5
139
+
140
+ length: 8.0
141
+ width: 1.0
142
+
143
+ placement:
144
+ x_start_options: [2.0]
145
+ y_options: [1.70]
146
+
147
+ - id: "analysis_zone"
148
+ type: "sub_zone"
149
+ priority: 1.0
150
+
151
+ length: 6.0
152
+ contained_in: "full_corridor"
153
+ offset_options: [1.0] # Laisse 1m de run-up et 1m de decelération dans le couloir de 8m
154
+
155
+ - id: "sts_point"
156
+ type: "point"
157
+ priority: 2.0
158
+
159
+ radius: 0.6
160
+ contained_in: "analysis_zone"
161
+ auto_optimize: true
162
+
163
+
164
+ # ─────────────────────────────────────────────────────────────
165
+ # 6. OPTIMISATION PARAMETERS
166
+ # ─────────────────────────────────────────────────────────────
167
+ optimization:
168
+ target_coverage: 6
169
+ bilateral_weight: 0.8
170
+ vertical_coverage_threshold: 0.9
171
+ restarts_per_combo: 50
172
+
173
+ wall_step: 0.35
174
+ angle_steps: 24
175
+ tripod_grid_step: 0.70
176
+ distance_quality_factor: 0.015
177
+
178
+ algo: "greedy_1opt"
179
+ graph_mode: "all"
180
+
181
+
182
+ # ─────────────────────────────────────────────────────────────
183
+ # 7. EVALUATION SETUP (NEW SECTION)
184
+ # ─────────────────────────────────────────────────────────────
185
+ # This section defines the exact fixed camera setup to evaluate.
186
+ # It completely bypasses the optimization process.
187
+ #
188
+ # Run with: python evaluate.py --config configs/evaluate_labo_CHU.yaml
189
+ #
190
+ # Note: The 'tilt' angle is still automatically calculated by the engine
191
+ # to point optimally towards the corridor height.
192
+ # ─────────────────────────────────────────────────────────────
193
+ evaluation_setup:
194
+ fixed_cameras:
195
+ # Cam 1 : Mur Sud
196
+ - { set_id: "cam_A", x: 5.30, y: 0.00, z: 2.3, angle: 120, orientation: "L" }
197
+ # Cam 2 : Mur Sud
198
+ - { set_id: "cam_A", x: 7.25, y: 0.00, z: 2.3, angle: 120, orientation: "L" }
199
+ # Cam 3 : Mur Sud
200
+ - { set_id: "cam_A", x: 11.50, y: 0.00, z: 2.3, angle: 120, orientation: "L" }
201
+ # Cam 4 : Mur Est
202
+ - { set_id: "cam_A", x: 13.00, y: 1.70, z: 2.3, angle: 180, orientation: "L" }
203
+ # Cam 5 : Renfoncement (Mur orienté Sud)
204
+ - { set_id: "cam_A", x: 8.10, y: 3.00, z: 2.3, angle: 300, orientation: "L" }
205
+ # Cam 6 : Sur le Stub 4 (Pilier orienté Sud)
206
+ - { set_id: "cam_A", x: 5.70, y: 3.85, z: 2.3, angle: 290, orientation: "L" }
207
+ # Cam 7 : Sur le Polygone (Mur orienté Sud)
208
+ - { set_id: "cam_A", x: 2.50, y: 4.27, z: 2.3, angle: 310, orientation: "L" }
209
+ # iPad 1 : Avant le couloir, regarde le long de l'axe (vers l'Est)
210
+ - { set_id: "cam_B", x: 1.50, y: 1.70, z: 1.5, angle: 0, orientation: "L" }
211
+ # iPad 2 : Au Nord du couloir, regarde vers la zone de marche (vers le Sud)
212
+ - { set_id: "cam_B", x: 4.70, y: 3.40, z: 1.5, angle: 290, orientation: "L" }
@@ -0,0 +1,66 @@
1
+ # ==============================================================================
2
+ # EXAMPLE CONFIG: EVALUATION MODE
3
+ # ==============================================================================
4
+ # This file demonstrates the "Evaluation Mode". Instead of optimizing camera
5
+ # positions, it evaluates a predefined setup from the `evaluation_setup`
6
+ # section below.
7
+ #
8
+ # To run:
9
+ # python evaluate.py --config configs/example_evaluation_CHU.yaml
10
+ #
11
+ # ==============================================================================
12
+
13
+ room:
14
+ corners: [[0,0], [13,0], [13,5], [10,5], [10,3], [0,3]] # L-shaped room
15
+ height: 3.0
16
+
17
+ obstacles:
18
+ - type: polygon
19
+ vertices: [[1.0,0.0],[1.2,0.0],[1.2,0.5],[1.0,0.5]]
20
+ height: 3.0
21
+ label: "Pillar A"
22
+ can_mount_camera: false
23
+
24
+ subject:
25
+ height: 1.8
26
+ foot_z: 0.0
27
+
28
+ camera_sets:
29
+ - id: "wall_cams"
30
+ name: "Wall-mounted Vicon"
31
+ mounting: "wall"
32
+ fov_h_landscape: 80.0
33
+ fov_v_landscape: 50.0
34
+ fov_h_portrait: 50.0
35
+ fov_v_portrait: 80.0
36
+ height_options: [2.0, 2.2, 2.4]
37
+ max_range: 12.0
38
+ min_range: 0.5
39
+ max_count: 8
40
+ min_spacing: 1.5
41
+ score_weight: 1.0
42
+ color: "#1f77b4"
43
+
44
+ capture_zones:
45
+ - id: "analysis_zone"
46
+ type: "corridor"
47
+ priority: 1.0
48
+ length: 6.0
49
+ width: 1.2
50
+ placement:
51
+ x_start_options: [3.0]
52
+ y_options: [1.5]
53
+
54
+ optimization:
55
+ target_coverage: 4
56
+ bilateral_weight: 0.8
57
+ vertical_coverage_threshold: 0.9
58
+
59
+ evaluation_setup:
60
+ fixed_cameras:
61
+ - { set_id: "wall_cams", x: 0.1, y: 0.1, z: 2.2, angle: 45, orientation: "L" }
62
+ - { set_id: "wall_cams", x: 5.0, y: 0.1, z: 2.2, angle: 90, orientation: "P" }
63
+ - { set_id: "wall_cams", x: 12.9, y: 0.1, z: 2.4, angle: 135, orientation: "L" }
64
+ - { set_id: "wall_cams", x: 12.9, y: 4.9, z: 2.4, angle: 225, orientation: "L" }
65
+ - { set_id: "wall_cams", x: 10.1, y: 4.9, z: 2.2, angle: 270, orientation: "P" }
66
+ - { set_id: "wall_cams", x: 0.1, y: 2.9, z: 2.2, angle: 315, orientation: "L" }
@@ -0,0 +1,136 @@
1
+ # =============================================================
2
+ # Lab Camera Optimizer — CHU Biomechanics Lab
3
+ # Run config: 10 ZED (wall) + 3 iPad (tripod), walking corridor + STS point.
4
+ # Derived from labo_CHU.yaml (iPad count 2→3, graph_mode → best_per_combo).
5
+ # =============================================================
6
+
7
+ room:
8
+ corners:
9
+ - [0, 0 ]
10
+ - [13, 0 ]
11
+ - [13, 3.0]
12
+ - [8, 3.0]
13
+ - [8, 4.7]
14
+ - [0, 4.7]
15
+ height: 3.0
16
+
17
+ obstacles:
18
+ - type: rect
19
+ bounds: [1.70, 0.00, 2.04, 0.34]
20
+ height: 3.0
21
+ label: "Stub 1"
22
+ can_mount_camera: true
23
+
24
+ - type: rect
25
+ bounds: [5.39, 0.00, 5.59, 0.42]
26
+ height: 3.0
27
+ label: "Stub 2"
28
+ can_mount_camera: true
29
+
30
+ - type: rect
31
+ bounds: [8.94, 0.00, 9.14, 0.42]
32
+ height: 3.0
33
+ label: "Stub 3"
34
+ can_mount_camera: true
35
+
36
+ - type: rect
37
+ bounds: [5.65, 3.85, 5.85, 4.25]
38
+ height: 3.0
39
+ label: "Stub 4"
40
+ can_mount_camera: true
41
+
42
+ - type: rect
43
+ bounds: [5.65, 2.85, 6.35, 3.55]
44
+ height: 1.4
45
+ label: "Object 1"
46
+ can_mount_camera: false
47
+
48
+ - type: polygon
49
+ vertices:
50
+ - [1.47, 4.70]
51
+ - [1.47, 4.38]
52
+ - [1.71, 4.38]
53
+ - [1.71, 3.88]
54
+ - [2.04, 3.88]
55
+ - [2.04, 4.27]
56
+ - [3.02, 4.27]
57
+ - [3.02, 4.70]
58
+ height: 3.0
59
+ label: "Wall N"
60
+ can_mount_camera: true
61
+
62
+ subject:
63
+ height: 1.9
64
+ foot_z: 0.0
65
+
66
+ camera_sets:
67
+
68
+ - id: "cam_A"
69
+ name: "ZED2i"
70
+ mounting: "wall"
71
+ optional: false
72
+ fov_h_landscape: 110.0
73
+ fov_v_landscape: 70.0
74
+ fov_h_portrait: 70.0
75
+ fov_v_portrait: 110.0
76
+ max_range: 15.0
77
+ min_range: 0.5
78
+ height_options: [1.8, 2.0, 2.2, 2.5] # wall mount heights to test (1.8 → 2.5 m)
79
+ max_count: 10 # 10 ZED on the walls
80
+ min_spacing: 1.5
81
+ score_weight: 1.0
82
+ color: "#1f77b4"
83
+
84
+ - id: "cam_B"
85
+ name: "iPad"
86
+ mounting: "tripod"
87
+ optional: false
88
+ fov_h_landscape: 80.0
89
+ fov_v_landscape: 58.0
90
+ fov_h_portrait: 58.0
91
+ fov_v_portrait: 80.0
92
+ max_range: 10.0
93
+ min_range: 0.5
94
+ height_options: [1.5]
95
+ max_count: 3 # 3 iPad on tripods
96
+ min_spacing: 1.5
97
+ walk_axis_margin: 0.7
98
+ score_weight: 0.6
99
+ color: "#d62728"
100
+
101
+ capture_zones:
102
+
103
+ - id: "full_corridor"
104
+ type: "corridor"
105
+ priority: 0.5
106
+ length: 10.0
107
+ width: 1.0
108
+ placement:
109
+ x_start_options: [1.0, 2.0]
110
+ y_options: [1.0, 1.4, 1.8]
111
+
112
+ - id: "analysis_zone"
113
+ type: "sub_zone"
114
+ priority: 1.0
115
+ length: 6.0
116
+ contained_in: "full_corridor"
117
+ offset_options: [1.0, 2.0, 3.0]
118
+
119
+ - id: "sts_point"
120
+ type: "point"
121
+ priority: 2.0
122
+ radius: 0.6
123
+ contained_in: "analysis_zone"
124
+ auto_optimize: true
125
+
126
+ optimization:
127
+ target_coverage: 6
128
+ bilateral_weight: 0.9
129
+ vertical_coverage_threshold: 0.9
130
+ restarts_per_combo: 35 # Maximale
131
+ wall_step: 0.25 # finer wall candidate spacing
132
+ angle_steps: 24
133
+ tripod_grid_step: 0.50 # finer tripod grid
134
+ distance_quality_factor: 0.001
135
+ algo: "greedy_1opt"
136
+ graph_mode: "best_per_combo"