# PySfMUtils
A Python package for interacting with Structure-from-Motion (SfM) projects.
## Requirements
* Python 3.6+
* numpy 1.15+
## Installation
The package is [registered on PyPI](https://pypi.org/project/PySfMUtils/).
Released versions can be installed using pip:
```shell
pip install PySfMUtils
```
Development versions can be installed directly from the
[GitLab repository](https://gitlab.com/educelab/sfm-utils):
```shell
python -m pip install -e git+https://gitlab.com/educelab/sfm-utils.git
```
## Usage
This package was originally designed to ease the process of importing pose
priors into [OpenMVG](https://github.com/openMVG/openMVG). It contains a format
agnostic interface for defining an SfM Scene and its component parts:
```python
import sfm_utils as sfm
# Create the scene
scene = sfm.Scene()
scene.root_dir = '/path/to/images/'
# Construct a view
view = sfm.View()
view.path = "view.jpg"
view.width = 800
view.height = 600
view.camera_make = 'PySfMUtils'
view.camera_model = 'Test Camera'
scene.add_view(view)
# Add the view's intrinsics
intrinsic = sfm.IntrinsicRadialK3()
intrinsic.width = view.width
intrinsic.height = view.height
intrinsic.focal_length = 50
intrinsic.sensor_width = 36
intrinsic.dist_params = [-0.1, -1.1, -1.1]
view.intrinsic = scene.add_intrinsic(intrinsic)
# Add the view's pose
pose = sfm.Pose()
pose.center = [10, 10, 10]
view.pose = scene.add_pose(pose)
# Write an OpenMVG project file
sfm.export_scene(path='sfm_data.json', scene=scene)
```
The exported `sfm_data.json` file can be passed directly to OpenMVG programs:
```shell
openMVG_main_ComputeFeatures -i sfm_data.json -o matches/
```
## Export to AliceVision/Meshroom
To export a scene to an AliceVision/Meshroom compatible json file, use
`sfm_utils.export_scene`:
```python
import sfm_utils as sfm
scene = sfm.Scene()
...
sfm.export_scene(path='SfMData.json', scene=scene, fmt=sfm.Format.ALICE_VISION)
```
The AliceVision json file matches an example file generated by Meshroom, but
has not been tested for actually performing reconstructions. Contributions to
this functionality are welcome.
## Pose coordinate system
This package assumes a right-handed<sup>[1](#sfmcoords)</sup> coordinate system,
in contrast to the left-handed<sup>[2](#mvgcoords)</sup> system used by OpenMVG.
When exporting to OpenMVG, this package will premultiply the `Pose.rotation`
matrix with the following conversion matrix:
```
-1, 0, 0
0, 1, 0
0, 0, -1
```
To control this behavior, supply your own change of basis matrix using the
`cob_matrix` parameter of `export_scene`:
```python
custom_cob = np.array([[-1, 0, 0], [0, -1, 0], [0, 0, 1]])
sfm_utils.export_scene(path='sfm_data.json', scene=scene, cob_matrix=custom_cob)
```
<a name="sfmcoords">1</a>: PySfMUtils coordinate system: -Z-forward, +Y-up, and +X-right
<a name="mvgcoords">2</a>: OpenMVG coordinate system: +Z-forward, +Y-up, and -X-right
## Limitations
This package is a work-in-progress and currently implements only the most basic
features needed to import pre-calibrated camera pose information into OpenMVG.
We will gladly accept pull requests for new features. Known limitations in the
current implementation are as follows:
* Only Views, Poses, and Intrinsics are supported. Feature points, control
points, tracks, etc. are not provided.
* Only the Pinhole, RadialK3, and BrownT2 camera intrinsics are implemented.
* AliceVision support is untested.
* There is no support for loading pre-existing SfM files.
## License
The software in this repository is licensed under the
[GNU General Public License v3.0](LICENSE). This project is free software: you
can redistribute it and/or modify it under the terms of the GPLv3 or (at your
option) any later version.