Skip to content

Commit 236e609

Browse files
committed
add:stand alone binary instructions
1 parent 9d20ac5 commit 236e609

1 file changed

Lines changed: 198 additions & 0 deletions

File tree

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
# opensfm_runner
2+
3+
Standalone OpenSfM pipeline binary for macOS (arm64 / Apple Silicon).
4+
No Python installation or dependencies required.
5+
6+
---
7+
8+
## Requirements
9+
10+
- macOS on Apple Silicon (arm64)
11+
- The binary is self-contained — no Python, conda, or pip needed
12+
13+
---
14+
15+
## Quick Start
16+
17+
```bash
18+
# Make executable (first time only)
19+
chmod +x ./opensfm_runner
20+
21+
# Full help manual
22+
./opensfm_runner --help
23+
24+
# Run the full pipeline on a dataset
25+
./opensfm_runner run /path/to/dataset
26+
```
27+
28+
A **dataset directory** must contain:
29+
- `images/` — JPEG/PNG/TIFF source photos
30+
- `config.yaml` — OpenSfM configuration (optional; defaults are used if absent)
31+
32+
---
33+
34+
## Commands
35+
36+
### Full pipeline
37+
38+
Runs all six steps in order and writes all output files to the dataset directory.
39+
40+
```bash
41+
./opensfm_runner run /path/to/dataset
42+
```
43+
44+
Add `--json` for newline-delimited JSON progress (useful for programmatic consumers such as a Tauri app reading stdout):
45+
46+
```bash
47+
./opensfm_runner run /path/to/dataset --json
48+
```
49+
50+
### Individual steps
51+
52+
Run a single step independently. Steps must be executed in pipeline order.
53+
54+
```bash
55+
./opensfm_runner extract_metadata /path/to/dataset
56+
./opensfm_runner detect_features /path/to/dataset
57+
./opensfm_runner match_features /path/to/dataset
58+
./opensfm_runner create_tracks /path/to/dataset
59+
./opensfm_runner reconstruct /path/to/dataset
60+
./opensfm_runner export_ply /path/to/dataset
61+
```
62+
63+
Each step also accepts `--json` for JSON output.
64+
65+
### Pipeline order
66+
67+
```
68+
extract_metadata → detect_features → match_features →
69+
create_tracks → reconstruct → export_ply
70+
```
71+
72+
---
73+
74+
## Output Files
75+
76+
All outputs are written inside the dataset directory:
77+
78+
| File | Created by |
79+
|---|---|
80+
| `exif/<image>.exif` | extract_metadata |
81+
| `camera_models.json` | extract_metadata |
82+
| `features/<image>.features.npz` | detect_features |
83+
| `reference_lla.json` | match_features |
84+
| `matches/<image>_matches.pkl.gz` | match_features |
85+
| `tracks.csv` | create_tracks |
86+
| `reconstruction.json` | reconstruct |
87+
| `reconstruction.ply` | export_ply |
88+
89+
---
90+
91+
## Running the Test Suite
92+
93+
The `test` command runs all six pipeline steps from scratch against a dataset and validates that every expected output file is produced correctly. It runs 16 checks in total.
94+
95+
```bash
96+
# Clean run — removes previous outputs first, then runs all steps
97+
./opensfm_runner test /path/to/dataset
98+
99+
# Validate existing outputs without re-running (no clean)
100+
./opensfm_runner test /path/to/dataset --no-clean
101+
```
102+
103+
### Example output
104+
105+
```
106+
Dataset : data/lund
107+
Images : 29
108+
Cleaning previous outputs ...
109+
110+
[1/6] extract_metadata
111+
PASS exif/ dir created
112+
PASS exif file count matches image count (29)
113+
PASS camera_models.json created
114+
115+
[2/6] detect_features
116+
PASS features/ dir created
117+
PASS feature file count matches image count (29)
118+
PASS first feature file is non-empty
119+
120+
[3/6] match_features
121+
PASS matches/ dir created
122+
PASS at least one match file produced
123+
PASS reference_lla.json created
124+
125+
[4/6] create_tracks
126+
PASS tracks.csv created
127+
PASS tracks.csv is non-empty
128+
129+
[5/6] reconstruct
130+
PASS reconstruction.json created
131+
PASS reconstruction.json contains at least one reconstruction
132+
PASS reconstruction contains shots (29 cameras placed)
133+
134+
[6/6] export_ply
135+
PASS reconstruction.ply created
136+
PASS reconstruction.ply is non-empty (3891148 bytes)
137+
138+
Results: 16/16 passed
139+
```
140+
141+
Exit code is `0` on full pass, `1` if any check fails.
142+
143+
---
144+
145+
## Known Warnings (harmless)
146+
147+
| Warning | Cause | Impact |
148+
|---|---|---|
149+
| `/bin/sh: free: command not found` | OpenSfM checks available RAM via a Linux-only command | None — ignored on macOS |
150+
| `Shots aligned on a single-line. Using horizontal prior` | Dataset images were captured in a nearly straight line | None — a fallback alignment prior is used automatically |
151+
152+
---
153+
154+
## Troubleshooting
155+
156+
**`zlib.error: unknown compression method` on startup**
157+
158+
This happens when macOS reuses a stale extraction cache from a previous version of the binary. Clear it with:
159+
160+
```bash
161+
find "$TMPDIR" -maxdepth 1 -name '_MEI*' -exec rm -rf {} +
162+
```
163+
164+
Then run the binary again.
165+
166+
**Fewer shots placed than images in the dataset**
167+
168+
This is normal for datasets with a linear capture path (e.g. a straight walkway). The incremental reconstructor may exclude frames that don't meet geometric constraints. The reconstruction is still valid.
169+
170+
---
171+
172+
## Rebuilding the Binary
173+
174+
If you modify `opensfm_runner.py`, rebuild with:
175+
176+
```bash
177+
CENV=/opt/homebrew/Cellar/micromamba/2.5.0_4/envs/opensfm
178+
PYTHONPATH=/path/to/OpenSfM \
179+
$CENV/bin/pyinstaller \
180+
--onefile --name opensfm_runner \
181+
--paths /path/to/OpenSfM \
182+
--collect-all opensfm --collect-all yaml --collect-all pyproj \
183+
--collect-all fpdf --collect-all scipy \
184+
--hidden-import xmltodict \
185+
--hidden-import opensfm.actions.extract_metadata \
186+
--hidden-import opensfm.actions.detect_features \
187+
--hidden-import opensfm.actions.match_features \
188+
--hidden-import opensfm.actions.create_tracks \
189+
--hidden-import opensfm.actions.reconstruct \
190+
--hidden-import opensfm.actions.export_ply \
191+
opensfm_runner.py
192+
```
193+
194+
Then clear the extraction cache before testing the new build:
195+
196+
```bash
197+
find "$TMPDIR" -maxdepth 1 -name '_MEI*' -exec rm -rf {} +
198+
```

0 commit comments

Comments
 (0)