lab-camera-optimizer 1.0.0__py3-none-any.whl
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.
- core/__init__.py +2 -0
- core/candidates.py +511 -0
- core/config_loader.py +305 -0
- core/greedy.py +470 -0
- core/room.py +447 -0
- core/scoring.py +248 -0
- core/visualize.py +517 -0
- lab_camera_optimizer-1.0.0.dist-info/METADATA +416 -0
- lab_camera_optimizer-1.0.0.dist-info/RECORD +13 -0
- lab_camera_optimizer-1.0.0.dist-info/WHEEL +5 -0
- lab_camera_optimizer-1.0.0.dist-info/entry_points.txt +3 -0
- lab_camera_optimizer-1.0.0.dist-info/licenses/LICENSE +22 -0
- lab_camera_optimizer-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: lab-camera-optimizer
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Automated camera placement optimiser for markerless biomechanics motion capture labs
|
|
5
|
+
Author: Florian Delaplace
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 Florian Delaplace
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
Project-URL: Homepage, https://github.com/flodelaplace/lab-camera-optimizer
|
|
30
|
+
Project-URL: Repository, https://github.com/flodelaplace/lab-camera-optimizer
|
|
31
|
+
Project-URL: Documentation, https://github.com/flodelaplace/lab-camera-optimizer/blob/main/ALGORITHM.md
|
|
32
|
+
Project-URL: Bug Tracker, https://github.com/flodelaplace/lab-camera-optimizer/issues
|
|
33
|
+
Keywords: biomechanics,motion-capture,camera-placement,optimisation,markerless,line-of-sight
|
|
34
|
+
Classifier: Programming Language :: Python :: 3
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
38
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
39
|
+
Classifier: Operating System :: OS Independent
|
|
40
|
+
Classifier: Topic :: Scientific/Engineering
|
|
41
|
+
Classifier: Intended Audience :: Science/Research
|
|
42
|
+
Requires-Python: >=3.10
|
|
43
|
+
Description-Content-Type: text/markdown
|
|
44
|
+
License-File: LICENSE
|
|
45
|
+
Requires-Dist: numpy>=1.24
|
|
46
|
+
Requires-Dist: matplotlib>=3.7
|
|
47
|
+
Requires-Dist: pyyaml>=6.0
|
|
48
|
+
Requires-Dist: tqdm>=4.65
|
|
49
|
+
Dynamic: license-file
|
|
50
|
+
|
|
51
|
+
# Lab Camera Optimizer
|
|
52
|
+
|
|
53
|
+
**Optimal camera placement for markerless biomechanics motion capture labs.**
|
|
54
|
+
|
|
55
|
+
Given a room layout, a set of cameras and a capture zone, this tool finds the
|
|
56
|
+
configuration that maximises 3D body coverage (head-to-toe visibility) across
|
|
57
|
+
all evaluation points, with optional bilateral coverage constraints.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Features
|
|
62
|
+
|
|
63
|
+
- **Any room shape** — define any polygon floor plan (L-shaped, rectangular, etc.)
|
|
64
|
+
- **Obstacles & walls** — pillars, partial-height furniture, irregular wall segments
|
|
65
|
+
- **Multiple camera sets** — wall-mounted cameras + optional tripod cameras
|
|
66
|
+
- **Per-camera height variation** — each camera in the same configuration can be at a different height
|
|
67
|
+
- **3D visibility** — checks both horizontal FOV and vertical body coverage (0 → subject height)
|
|
68
|
+
- **Line-of-sight** — occlusion by walls and floor-to-ceiling obstacles
|
|
69
|
+
- **Bilateral constraint** — ensures coverage from both sides of the capture axis (configurable weight)
|
|
70
|
+
- **Zone sweep** — automatically tests multiple corridor/polygon zone positions and finds the best layout
|
|
71
|
+
- **Room preview** — top-down visualisation of your room before running optimisation
|
|
72
|
+
- **YAML configuration** — no code editing required to adapt to your lab
|
|
73
|
+
|
|
74
|
+
> **Want to understand how it works?**
|
|
75
|
+
> See [ALGORITHM.md](ALGORITHM.md) for a full explanation of the scoring
|
|
76
|
+
> function, the greedy optimisation, the combo sweep and all tuning parameters.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Preview
|
|
81
|
+
|
|
82
|
+
### Room layout (`preview_room.py`)
|
|
83
|
+

|
|
84
|
+
|
|
85
|
+
### Optimisation result
|
|
86
|
+

|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Installation
|
|
91
|
+
|
|
92
|
+
### Option A — pip install (recommended)
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
pip install git+https://github.com/flodelaplace/lab-camera-optimizer.git
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Once installed, two commands are available anywhere in your terminal:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
lab-camera-optimizer --config path/to/my_lab.yaml
|
|
102
|
+
lab-camera-preview --config path/to/my_lab.yaml
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Option B — Clone and run locally
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
git clone https://github.com/flodelaplace/lab-camera-optimizer.git
|
|
109
|
+
cd lab-camera-optimizer
|
|
110
|
+
pip install -r requirements.txt
|
|
111
|
+
python optimize.py --config configs/example_simple.yaml
|
|
112
|
+
python preview_room.py --config configs/example_simple.yaml
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Python ≥ 3.10 recommended.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Quick start
|
|
120
|
+
|
|
121
|
+
### 1. Preview your room layout
|
|
122
|
+
|
|
123
|
+
Before running the (potentially long) optimisation, always verify your room
|
|
124
|
+
geometry, obstacles and capture zones visually:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
python preview_room.py --config configs/example_simple.yaml
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
This saves a top-down PNG to `outputs/preview_room/` and opens an interactive
|
|
131
|
+
window. Use it every time you modify your config to catch geometry errors early.
|
|
132
|
+
|
|
133
|
+
> **Tip:** `preview_room.py` can be run standalone at any time — it does not
|
|
134
|
+
> require the optimiser to have been run first.
|
|
135
|
+
|
|
136
|
+
### 2. Run the optimiser
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
python optimize.py --config configs/example_simple.yaml
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The room preview is shown automatically at startup. Close the window to start
|
|
143
|
+
the optimisation. To skip the preview (e.g. for batch runs):
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
python optimize.py --config configs/example_simple.yaml --no-preview
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Results are saved in `outputs/`:
|
|
150
|
+
- `FINAL_RESULT_*.png` — 4-panel figure (top view, heatmap, side view, coverage bar chart)
|
|
151
|
+
- `graphs/` — intermediate graphs for each optimisation attempt
|
|
152
|
+
- `graphs_optimal/` — best result per zone combination, ranked by score
|
|
153
|
+
- `log_*.txt` — full optimisation log
|
|
154
|
+
- `preview_room/` — room layout previews
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Adapting to your lab
|
|
159
|
+
|
|
160
|
+
### Step 1 — Choose a starting config
|
|
161
|
+
|
|
162
|
+
| File | Description |
|
|
163
|
+
|---|---|
|
|
164
|
+
| `configs/example_simple.yaml` | **Start here** — 10×6 m rectangle, one camera set, no obstacles |
|
|
165
|
+
| `configs/example_real_world.yaml` | Full real-world example — L-shaped room, obstacles, two camera sets, corridor |
|
|
166
|
+
| `configs/T_zone_direction_change.yaml` | T-shaped capture zone for direction-change analysis |
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
cp configs/example_simple.yaml configs/my_lab.yaml
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Step 2 — Edit `my_lab.yaml`
|
|
173
|
+
|
|
174
|
+
The YAML file has six sections:
|
|
175
|
+
|
|
176
|
+
#### `room` — room geometry
|
|
177
|
+
```yaml
|
|
178
|
+
room:
|
|
179
|
+
corners: [[0,0],[10,0],[10,5],[0,5]] # (X,Y) vertices in metres, in order
|
|
180
|
+
height: 3.0 # floor-to-ceiling height (metres)
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
#### `obstacles` — walls, pillars, furniture
|
|
184
|
+
```yaml
|
|
185
|
+
obstacles:
|
|
186
|
+
- type: polygon
|
|
187
|
+
vertices: [[1.0,0.0],[1.2,0.0],[1.2,0.5],[1.0,0.5]]
|
|
188
|
+
height: 3.0 # = room height → fully blocks line-of-sight
|
|
189
|
+
label: "Pillar A"
|
|
190
|
+
can_mount_camera: false
|
|
191
|
+
|
|
192
|
+
- type: polygon
|
|
193
|
+
vertices: [[2,0],[2,1],[3,1],[3,0]]
|
|
194
|
+
height: 1.2 # partial height → cameras can see over it
|
|
195
|
+
label: "Table"
|
|
196
|
+
can_mount_camera: false
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
> **Tip:** run `python preview_room.py --config configs/my_lab.yaml` after every
|
|
200
|
+
> obstacle addition to verify the geometry looks right before optimising.
|
|
201
|
+
|
|
202
|
+
#### `subject` — person being recorded
|
|
203
|
+
```yaml
|
|
204
|
+
subject:
|
|
205
|
+
height: 1.9 # metres
|
|
206
|
+
foot_z: 0.0
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
#### `camera_sets` — define your cameras
|
|
210
|
+
```yaml
|
|
211
|
+
camera_sets:
|
|
212
|
+
- id: "cam_A"
|
|
213
|
+
name: "My Camera"
|
|
214
|
+
mounting: "wall" # wall | tripod
|
|
215
|
+
fov_h_landscape: 110.0
|
|
216
|
+
fov_v_landscape: 70.0
|
|
217
|
+
fov_h_portrait: 70.0
|
|
218
|
+
fov_v_portrait: 110.0
|
|
219
|
+
height_options: [2.0, 2.2] # tested heights (metres)
|
|
220
|
+
max_range: 10.0
|
|
221
|
+
min_range: 0.5
|
|
222
|
+
max_count: 8
|
|
223
|
+
min_spacing: 1.2
|
|
224
|
+
score_weight: 1.0
|
|
225
|
+
color: "#1f77b4"
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
#### `capture_zones` — where coverage matters
|
|
229
|
+
|
|
230
|
+
**Corridor-based** (walking path):
|
|
231
|
+
```yaml
|
|
232
|
+
capture_zones:
|
|
233
|
+
- id: "full_corridor"
|
|
234
|
+
type: "corridor"
|
|
235
|
+
priority: 0.5
|
|
236
|
+
length: 10.0
|
|
237
|
+
width: 1.0
|
|
238
|
+
placement:
|
|
239
|
+
x_start_options: [1.0, 2.0]
|
|
240
|
+
y_options: [1.5, 2.0]
|
|
241
|
+
|
|
242
|
+
- id: "analysis_zone"
|
|
243
|
+
type: "sub_zone"
|
|
244
|
+
priority: 1.0
|
|
245
|
+
length: 6.0
|
|
246
|
+
contained_in: "full_corridor"
|
|
247
|
+
offset_options: [1.0, 2.0, 3.0]
|
|
248
|
+
|
|
249
|
+
- id: "key_point"
|
|
250
|
+
type: "point"
|
|
251
|
+
priority: 2.0
|
|
252
|
+
radius: 0.5
|
|
253
|
+
contained_in: "analysis_zone"
|
|
254
|
+
auto_optimize: true
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**Polygon-based** (arbitrary shape — L, T, cross…):
|
|
258
|
+
```yaml
|
|
259
|
+
capture_zones:
|
|
260
|
+
- id: "approach"
|
|
261
|
+
type: "polygon"
|
|
262
|
+
priority: 1.0
|
|
263
|
+
grid_step: 0.30
|
|
264
|
+
vertices:
|
|
265
|
+
- [0.0, 0.0]
|
|
266
|
+
- [6.0, 0.0]
|
|
267
|
+
- [6.0, 1.0]
|
|
268
|
+
- [0.0, 1.0]
|
|
269
|
+
placement:
|
|
270
|
+
x_offsets: [0.0, 0.5]
|
|
271
|
+
y_offsets: [2.0, 2.5]
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
#### `optimization` — tuning parameters
|
|
275
|
+
```yaml
|
|
276
|
+
optimization:
|
|
277
|
+
target_coverage: 4 # cameras per evaluation point
|
|
278
|
+
bilateral_weight: 0.8 # 0 = disabled, 1 = fully enforced
|
|
279
|
+
vertical_coverage_threshold: 0.9
|
|
280
|
+
restarts_per_combo: 15
|
|
281
|
+
algo: "greedy_1opt" # greedy | greedy_1opt
|
|
282
|
+
early_stop: 5 # stop after N restarts with no improvement
|
|
283
|
+
graph_mode: "best_per_combo" # all | records_only | best_per_combo
|
|
284
|
+
wall_step: 0.35
|
|
285
|
+
angle_steps: 24
|
|
286
|
+
tripod_grid_step: 0.70
|
|
287
|
+
distance_quality_factor: 0.001
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### Step 3 — Preview, then run
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
# Verify geometry
|
|
294
|
+
python preview_room.py --config configs/my_lab.yaml
|
|
295
|
+
|
|
296
|
+
# Run optimisation
|
|
297
|
+
python optimize.py --config configs/my_lab.yaml
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## Output explained
|
|
303
|
+
|
|
304
|
+
| Panel | Description |
|
|
305
|
+
|---|---|
|
|
306
|
+
| Top-left: **Top view** | Room plan + camera cones. Grey = blind zone. Coloured = useful coverage. |
|
|
307
|
+
| Top-right: **XY heatmap** | Number of cameras covering each floor position in 3D. |
|
|
308
|
+
| Bottom-left: **XZ side view** | Number of cameras covering each height slice along the room length. |
|
|
309
|
+
| Bottom-right: **Coverage bar chart** | Camera count per X position along the corridor. Green = target reached. |
|
|
310
|
+
|
|
311
|
+
### Example terminal output
|
|
312
|
+
|
|
313
|
+
```
|
|
314
|
+
=================================================================
|
|
315
|
+
OPTIMAL CONFIGURATION
|
|
316
|
+
=================================================================
|
|
317
|
+
Score: 829.08
|
|
318
|
+
Bilateral: SOUTH=939.9 (49%) NORTH=981.1 (51%) balance=96% OK
|
|
319
|
+
|
|
320
|
+
Wall cameras (cam_A):
|
|
321
|
+
A 1 [L][S] pos=(0.00m, 0.36m) h=2.2m
|
|
322
|
+
Pan: 10deg to the RIGHT | Tilt: 50.3deg downward
|
|
323
|
+
A 2 [P][S] pos=(8.78m, 0.00m) h=2.0m
|
|
324
|
+
Pan: 55deg to the RIGHT | Tilt: 36.9deg downward
|
|
325
|
+
A 3 [P][S] pos=(4.22m, 0.00m) h=2.0m
|
|
326
|
+
Pan: 55deg to the LEFT | Tilt: 36.9deg downward
|
|
327
|
+
A 4 [P][S] pos=(11.95m, 0.00m) h=2.2m
|
|
328
|
+
Pan: 55deg to the RIGHT | Tilt: 41.8deg downward
|
|
329
|
+
A 5 [P][N] pos=(8.00m, 4.70m) h=2.2m
|
|
330
|
+
Pan: 55deg to the RIGHT | Tilt: 20.7deg downward
|
|
331
|
+
A 6 [L][N] pos=(0.00m, 2.53m) h=2.0m
|
|
332
|
+
Pan: 10deg to the LEFT | Tilt: 42.9deg downward
|
|
333
|
+
A 7 [P][S] pos=(2.04m, 0.00m) h=2.2m
|
|
334
|
+
Pan: 55deg to the LEFT | Tilt: 41.8deg downward
|
|
335
|
+
A 8 [L][N] pos=(2.04m, 4.07m) h=2.2m
|
|
336
|
+
Pan: 35deg to the LEFT | Tilt: 25.0deg downward
|
|
337
|
+
A 9 [P][N] pos=(0.00m, 4.34m) h=2.2m
|
|
338
|
+
Pan: 25deg to the LEFT | Tilt: 23.0deg downward
|
|
339
|
+
A10 [L][N] pos=(13.00m, 3.00m) h=2.2m
|
|
340
|
+
Pan: 35deg to the RIGHT | Tilt: 38.0deg downward
|
|
341
|
+
|
|
342
|
+
Tripod cameras (cam_B):
|
|
343
|
+
B1 [P] pos=(1.10m, 0.40m) h=1.5m angle=20deg tilt=28.8deg
|
|
344
|
+
B2 [L] pos=(10.90m, 0.40m) h=1.5m angle=180deg tilt=28.8deg
|
|
345
|
+
=================================================================
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
Each camera line gives:
|
|
349
|
+
- `[L]`/`[P]` — landscape or portrait orientation
|
|
350
|
+
- `[S]`/`[N]` — south or north side of the capture axis
|
|
351
|
+
- `pos` — XY position on the wall (metres)
|
|
352
|
+
- `h` — mounting height (metres)
|
|
353
|
+
- **Pan** — horizontal angle left/right from the wall normal
|
|
354
|
+
- **Tilt** — vertical angle downward toward the subject
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
## Room coordinate system
|
|
359
|
+
|
|
360
|
+
```
|
|
361
|
+
Y
|
|
362
|
+
^
|
|
363
|
+
|
|
|
364
|
+
| (room interior)
|
|
365
|
+
|
|
|
366
|
+
+-----------> X
|
|
367
|
+
(0,0)
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
- **X axis**: room length (left → right)
|
|
371
|
+
- **Y axis**: room width (bottom → top)
|
|
372
|
+
- **Z axis**: height (floor = 0)
|
|
373
|
+
- **Angles**: 0° = East (+X), 90° = North (+Y), 180° = West (−X)
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## How it works
|
|
378
|
+
|
|
379
|
+
The full technical documentation is in **[ALGORITHM.md](ALGORITHM.md)**. Here is a short summary:
|
|
380
|
+
|
|
381
|
+
| Component | Description |
|
|
382
|
+
|---|---|
|
|
383
|
+
| **Sample grid** | Evaluation points distributed across capture zones, weighted by `priority` |
|
|
384
|
+
| **Score per point** | `v²` (vertical body coverage) × `dist_quality` × bilateral factor × angular diversity |
|
|
385
|
+
| **Bilateral factor** | Rewards cameras on both sides of the capture axis (configurable weight) |
|
|
386
|
+
| **Greedy** | Cameras added one by one to maximise score; fast but local optima |
|
|
387
|
+
| **Greedy + 1-opt** | Greedy init with diverse spatial spread, then 1-opt local search; recommended |
|
|
388
|
+
| **Coverage ratio** | Penalises candidates that see only a tiny slice of the zone, regardless of proximity |
|
|
389
|
+
| **Combo sweep** | Tests all combinations of zone positions (X offset, Y position, run-up distance) |
|
|
390
|
+
| **walk_y** | Bilateral axis auto-derived from the highest-priority zone centroid each combo |
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
## Citing this tool
|
|
395
|
+
|
|
396
|
+
If you use this tool in a research publication, please cite it using the
|
|
397
|
+
`CITATION.cff` file at the root of this repository (GitHub shows a
|
|
398
|
+
*"Cite this repository"* button automatically).
|
|
399
|
+
|
|
400
|
+
> Delaplace F. — *Lab Camera Optimizer: automated camera placement for
|
|
401
|
+
> markerless biomechanics motion capture laboratories* — 2026.
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
## License
|
|
406
|
+
|
|
407
|
+
This project is licensed under the **MIT License** — see the
|
|
408
|
+
[LICENSE](LICENSE) file for details.
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
412
|
+
## Contributing
|
|
413
|
+
|
|
414
|
+
Pull requests and issues are welcome.
|
|
415
|
+
Please open an issue before submitting large changes.
|
|
416
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
core/__init__.py,sha256=01uRez0vw2wd7X8LOgdwgc3ZiGXN4rjNM5NOtwr5ZKg,39
|
|
2
|
+
core/candidates.py,sha256=3f9W6g3sbX1VmZMKP04KyMMEHL89Xy4Neh1mr02H1n0,21813
|
|
3
|
+
core/config_loader.py,sha256=vn2UeiD5LhD4tFSkYaoHoJWU5J4JD03simSGTx9vDMg,14783
|
|
4
|
+
core/greedy.py,sha256=C9EUNpDFNaPLbjaLmjUGzMM1Ry0d9kX8HBseD3tazuk,21860
|
|
5
|
+
core/room.py,sha256=6tWSKCiC4lR9GjRc-xjZ5kIfihIr18ODXOTwi80Iezo,16940
|
|
6
|
+
core/scoring.py,sha256=VW5I08BPBZm2n9L8l9EqQLXLseS2hBLm2W8G_NSHxHg,11613
|
|
7
|
+
core/visualize.py,sha256=95AdIBCl3gjABqxh3fH_EHQV-5Yg8-WmpUrLuabA-5g,27943
|
|
8
|
+
lab_camera_optimizer-1.0.0.dist-info/licenses/LICENSE,sha256=123NfbIUIZEal5ig9wgzzA8ALqMR46suQx-EURcJjOQ,1097
|
|
9
|
+
lab_camera_optimizer-1.0.0.dist-info/METADATA,sha256=TwJY7DHf1wk-7QLglrHLy1SD-c5soD2dzy4I3GyHSZ0,14070
|
|
10
|
+
lab_camera_optimizer-1.0.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
11
|
+
lab_camera_optimizer-1.0.0.dist-info/entry_points.txt,sha256=E3P_GYmtMjYz9BXFmYqglOAdirrPH-120IA_w_6TR5I,94
|
|
12
|
+
lab_camera_optimizer-1.0.0.dist-info/top_level.txt,sha256=0ebp8k35dOTHVwbY3UcokRsjC7cWLN_iaJ70tIcmODU,5
|
|
13
|
+
lab_camera_optimizer-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Florian Delaplace
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
core
|