PySfMUtils 1.2.0
A Python library for interacting with Structure-from-Motion projects
Requires Python: >=3.6

# 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.