Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
!doc
!LICENSE
!opensfm
!pyproject.toml
!README.md
!requirements.txt
!setup.cfg
!setup.py
!viewer
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/conda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
submodules: true

Expand All @@ -26,7 +26,7 @@ jobs:

- name: Build OpenSfM
shell: bash -l {0}
run: python setup.py build
run: pip install -e .[test]

- name: Run C++ tests
shell: bash -l {0}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/docker_ubuntu24.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
run: docker build . --file Dockerfile.ubuntu24 --tag mapillary/opensfm.ubuntu24:$GITHUB_SHA

- name: Run C++ tests
run: docker run mapillary/opensfm.ubuntu24:$GITHUB_SHA /bin/sh -c "cd cmake_build && ctest"
run: docker run mapillary/opensfm.ubuntu24:$GITHUB_SHA /bin/bash -c "cd cmake_build && ctest --output-on-failure"

- name: Run Python tests
run: docker run mapillary/opensfm.ubuntu24:$GITHUB_SHA python3 -m pytest
run: docker run mapillary/opensfm.ubuntu24:$GITHUB_SHA python -m pytest -v
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ xcode
launch.json
.vscode
.idea
.claude
uv.lock

# Ignore generated files
/build
Expand Down
33 changes: 4 additions & 29 deletions Dockerfile.ubuntu24
Original file line number Diff line number Diff line change
Expand Up @@ -11,45 +11,20 @@ RUN apt-get update \
libopencv-dev \
libceres-dev \
python3-dev \
python3-numpy \
python3-opencv \
python3-pip \
python3-venv \
python3-pyproj \
python3-scipy \
python3-yaml \
curl \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# Create and activate virtual environment
RUN python3 -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"

# Install Python packages in the virtual environment
RUN pip install \
cloudpickle==3.1.1 \
ExifRead==3.5.1 \
Flask==3.1.2 \
fpdf2==2.8.4 \
joblib==1.5.2 \
matplotlib==3.10.6 \
networkx==3.5 \
numpy==1.26.4 \
opencv-python==4.11.0.86 \
pillow==11.3.0 \
pyproj==3.7.2 \
pytest==8.4.2 \
python-dateutil==2.9.0.post0 \
PyYAML==6.0.3 \
scipy==1.16.2 \
setuptools==80.9.0 \
Sphinx==6.2.1 \
wheel==0.45.1 \
xmltodict==1.0.2

COPY . /source/OpenSfM

WORKDIR /source/OpenSfM

RUN python3 setup.py build
# Build and install OpenSfM using pip with pyproject.toml
# C++ tests are built automatically (OPENSFM_BUILD_TESTS=ON in pyproject.toml)
# and will be available in cmake_build/ directory for running with ctest
RUN pip install --no-cache-dir -e .[test]
20 changes: 0 additions & 20 deletions conda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,3 @@ dependencies:
- ceres-solver=2.1
- conda-forge::llvm-openmp
- conda-forge::cxx-compiler
- pip
- pip:
- cloudpickle==3.1.1
- ExifRead==3.3.1
- Flask==3.1.1
- fpdf2==2.8.3
- joblib==1.5.1
- matplotlib==3.5.1
- networkx==3.4.2
- numpy==1.21.5
- Pillow==9.0.1
- pyproj>=3.3.0
- pytest==8.4.0
- python-dateutil==2.8.1
- PyYAML>=5.4.1
- scipy==1.8.0
- Sphinx==4.2.0
- xmltodict==0.14.2
- wheel
- sphinx_rtd_theme
33 changes: 33 additions & 0 deletions doc/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = ../build/doc
PORT ?= 8000

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile serve clean

# Serve the documentation locally
serve:
@echo "Serving documentation at http://localhost:$(PORT)/"
@echo "Press Ctrl+C to stop the server"
@python -m http.server --directory $(BUILDDIR)/html $(PORT)

# Clean build artifacts
clean:
@echo "Cleaning build directory: $(BUILDDIR)"
@rm -rf $(BUILDDIR)
@echo "Done"

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
8 changes: 6 additions & 2 deletions doc/source/annotation_tool.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ Main toolbox
~~~~~~~~~~~~

The main toolbox contains the list of existing control points as well as several controls.
The basic controls are explained here. Scroll to :ref:`additional-controls` for information on the rest.
The basic controls are explained here. Scroll to :ref:`advanced-features` for information on the rest.

- The 'Load', 'Save' buttons save and load the ground control points into a ``ground_control_points.json`` file with :ref:`json-gcps`.
- The 'Load', 'Save' buttons save and load the ground control points into a ``ground_control_points.json`` file (see the JSON file format section in the Ground Control Points documentation).
- If there is a ``ground_control_points.json`` file in the dataset directory, it will be loaded upon launch.
- Control points can be added or removed with the 'Add GCP' and 'Remove GCP' buttons. The active point can be selected from the dropdown.
- By selecting a point in the list it becomes active and can be annotated on all images.
Expand Down Expand Up @@ -84,6 +84,7 @@ Assuming that you have a set of ground control points whose geodetic coordinates
You can use ``data/berlin`` for this example.
2. Generate a ``ground_control_points.json`` file with all your measured ground control points and place it in the root of the dataset
See the example below. Note how the 'observations' is empty as we will generate those using the annotation tool.

::

"points": [
Expand All @@ -93,6 +94,7 @@ Assuming that you have a set of ground control points whose geodetic coordinates
"observations": []
}
]

3. Launch the annotation tool, note how the control points dropdown contains your ground control points.
4. Scroll through all the images, annotating each GCP on all the locations where it is visible.
5. Click on 'save' to overwrite the ``ground_control_points.json`` file with your annotations.
Expand Down Expand Up @@ -122,6 +124,8 @@ The 'Flex' and 'Full' buttons produce additional analysis results and
are explained in :ref:`two-reconstruction-annotation`


.. _advanced-features:

Advanced features
-----------------

Expand Down
67 changes: 47 additions & 20 deletions doc/source/building.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,25 @@
Building
========

Quick start
-----------

To build OpenSfM, follow these steps:

1. Download the OpenSfM code from Github::

git clone --recursive https://github.com/mapillary/OpenSfM

2. Install the dependencies (we recommend using conda)::

conda env create --file conda.yml --yes
conda activate opensfm

3. Build OpenSfM::

pip install -e .


Download
--------

Expand All @@ -20,14 +39,14 @@ If you already have the code or you downloaded a release_, make sure to update t
Install dependencies
--------------------

OpenSfM depends on multiple libraries (OpenCV_, `Ceres Solver`_, ...) and python packages that need to be installed before building it.
OpenSfM depends on multiple libraries (OpenCV_, `Ceres Solver`_, ...) that need to be installed before building it.

The way to install these dependencies depends on your system. We recommend using a virtual environment manager such as anaconda or miniconda, not to mess up with your current setup. Anaconda will take care of installing both systems and python dependencies.

Installing dependencies using Conda (recommended)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Creating a conda environment will take care of installing all dependencies. Make sure you have conda or miniconda installed. From the project root directory, run::
Creating a conda environment will take care of installing all dependencies. Make sure you have conda or miniconda installed. From the project root directory, run::

conda env create --file conda.yml --yes

Expand All @@ -40,19 +59,19 @@ and you are ready to build OpenSfM.
(Anaconda dependencies installation has been tested under MacOS (Sequoia), Ubuntu 24.04 and Fedora 42.)

Installing dependencies on Ubuntu
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you are not using conda, see this `Dockerfile <https://github.com/mapillary/OpenSfM/blob/main/Dockerfile>`_ for the commands to install all dependencies on Ubuntu 20.04.
If you are not using conda, see this `Dockerfile.ubuntu24 <https://github.com/mapillary/OpenSfM/blob/main/Dockerfile.ubuntu24>`_ for the commands to install all dependencies on Ubuntu 24.04.


Installing dependencies on MacOSX
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

While it is possible to install all dependencies using brew, we recommend using the conda instructions above instead.


Installing dependencies on Windows
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Install git_.

Expand All @@ -73,39 +92,47 @@ Then install OpenCV, Ceres, SuiteSparse and LAPACK (this will take a while)::

vcpkg install opencv4 ceres ceres[suitesparse] lapack suitesparse --triplet x64-windows

Finally install the PIP requirements::

pip install -r requirements.txt


Building the library
--------------------

Once the dependencies have been installed, you can build OpenSfM by running the following command from the main folder::

python setup.py build
pip install -e .

This will first install python dependencies on your current python environment, and then build OpenSfM and install it in editable mode.


Building Docker images
----------------------

Once dependencies have been installed, you can build OpenSfM Docker images by running the following command from the main folder::

docker build -t opensfm -f Dockerfile .
You can also use OpenSfM inside docker. We provide example Dockerfiles for Ubuntu 20.04 and 24.04. Build it by running the following command from the main folder::

To build an image using the Ceres 2 solver, use::
docker build -t opensfm.ubuntu24 -f Dockerfile.ubuntu24 .

docker build -t opensfm:ceres2 -f Dockerfile.ceres2 .

Building the documentation
--------------------------
To build the documentation and browse it locally use::

pip install sphinx_rtd_theme
python setup.py build_doc
python -m http.server --directory build/doc/html/
To build the documentation and browse it locally, first install Sphinx::

pip install -e .[docs]

Then build the documentation using make::

cd doc
make html

To browse the documentation locally::

make serve

and browse `http://localhost:8000/ <http://localhost:8000/>`_

To clean the build artifacts::

make clean


.. _Github: https://github.com/mapillary/OpenSfM
.. _release: https://github.com/mapillary/OpenSfM/releases
Expand Down
4 changes: 2 additions & 2 deletions doc/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@

# General information about the project.
project = "OpenSfM"
copyright = "2021, Mapillary"
copyright = "2025, Mapillary"
author = "Mapillary"

# The version info for the project you're documenting, acts as replacement for
Expand All @@ -67,7 +67,7 @@
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
language = "en"

# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
Expand Down
2 changes: 0 additions & 2 deletions doc/source/gcp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ In the bundle adjustment step, GCP observations are used as a constraint to refi

GPSs can be specified in two file formats. If existing, both are loaded.

.. _json-gcps:

JSON file format
~~~~~~~~~~~~~~~~
GCPs can be specified by adding a text file named ``ground_control_points.json`` at the root folder of the dataset. The format of the file should be as follows::
Expand Down
10 changes: 5 additions & 5 deletions doc/source/quality_report.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@ Reconstruction Details

|rec|

- Average reprojection error (normalized/pixels): normalized (by features uncertainty) average norm of reprojection errors and same, but pixel-wise,
un-normalized, error. Errors bigger than 4 pixels are pruned out.
- Average Track Length : average number of images in which a reconstructed points has been detected.
- Average Track Length (> 2) : same as above but ignoring 2-images points.
- Average reprojection error (normalized/pixels): normalized (by features uncertainty) average norm of reprojection errors and same, but pixel-wise,
un-normalized, error. Errors bigger than 4 pixels are pruned out.
- Average Track Length : average number of images in which a reconstructed points has been detected.
- Average Track Length (> 2) : same as above but ignoring 2-images points.

|residual_histogram|
|residual_histogram|

The tables are the histogram of the certainty-normalized and un-normalized reprojection errors norm. Errors bigger than 4 pixels are pruned out.

Expand Down
Loading
Loading