Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
9a7b166
Set laszip build paths, fix _transform call
pierotofy Jul 1, 2026
89de044
Update OpenSfM, runs on default settings end-to-end
pierotofy Jul 1, 2026
260f648
Cleanup OpenSfMdirs, remove old functions
pierotofy Jul 2, 2026
958cacf
Add Abseil
pierotofy Jul 2, 2026
187b426
Fix OpenSfM, abseil build
pierotofy Jul 2, 2026
1c0fa5d
Add tcmalloc
pierotofy Jul 2, 2026
b9ac920
Add support for new ground control point format
pierotofy Jul 2, 2026
6b7c223
Add libtcmalloc to runtime deps
pierotofy Jul 2, 2026
37bb71f
Dont use LD_PRELOAD, remove multiprocessing dep from context
pierotofy Jul 3, 2026
863831f
Pass WGS84 GCPs to OpenSfM
pierotofy Jul 3, 2026
a360ef3
Set OpenSfM install path, remove include files
pierotofy Jul 3, 2026
9650f08
Update Obj2Tiles
pierotofy Jul 3, 2026
e1797dd
Write GCP vector files
pierotofy Jul 3, 2026
8336b97
Add laszip dependency
pierotofy Jul 3, 2026
d609af1
Add --report-units
pierotofy Jul 3, 2026
2dd55a6
Merge branch '380' of https://github.com/WebODM/ODX into 380
pierotofy Jul 3, 2026
a20919e
laszip before opensfm
pierotofy Jul 3, 2026
803f8ad
Compile abseil with c++17
pierotofy Jul 4, 2026
c18eebf
Use new rolling shutter command
pierotofy Jul 4, 2026
a6757a7
Merge branch '380' of https://github.com/WebODM/ODX into 380
pierotofy Jul 4, 2026
72a8a04
Feat: GPU hamming support
pierotofy Jul 6, 2026
602c9c3
Update README
pierotofy Jul 6, 2026
aec4829
Scale Z
pierotofy Jul 7, 2026
373b2c9
Cleanup OpenSfM files on Windows build, remove fast-float
pierotofy Jul 7, 2026
58d38e7
Update OpenSfM
pierotofy Jul 7, 2026
60dac19
Update FPCFilter
pierotofy Jul 7, 2026
253bc56
Fix GCP NaN handling
pierotofy Jul 7, 2026
414566a
Handle case when GCP error is None
pierotofy Jul 7, 2026
a828a2b
Add GCP warning
pierotofy Jul 7, 2026
ecd540e
Tie new GPS DOP functionality
pierotofy Jul 7, 2026
cd2df26
Bump OpenSfM
pierotofy Jul 8, 2026
69a4d6d
Improve compatibility of LAZ outputs
pierotofy Jul 8, 2026
c3e0e79
SignPath code signing, fix GCP code
pierotofy Jul 8, 2026
45b1def
SignPath required README additions
pierotofy Jul 8, 2026
e5b25aa
Bump OpenSfM
pierotofy Jul 9, 2026
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
23 changes: 21 additions & 2 deletions .github/workflows/publish-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ concurrency:
cancel-in-progress: true

permissions:
actions: read
contents: write

jobs:
Expand Down Expand Up @@ -45,22 +46,40 @@ jobs:
run: |
rmdir SuperBuild\download /s /q
rmdir SuperBuild\build /s /q
rmdir SuperBuild\install\include /s /q
rmdir SuperBuild\install\bin\opensfm\.git /s /q
rmdir SuperBuild\install\bin\opensfm\.github /s /q
rmdir SuperBuild\install\bin\opensfm\annotation_gui_gcp /s /q
rmdir SuperBuild\install\bin\opensfm\doc /s /q
rmdir SuperBuild\install\bin\opensfm\viewer /s /q
rmdir SuperBuild\install\bin\opensfm\data /s /q
rmdir SuperBuild\install\bin\opensfm\opensfm\src\lib\third_party\pybind11\.git /s /q
shell: cmd
- name: Create setup
run: |
python configure.py dist
shell: cmd
- name: Upload Setup File
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: Setup
path: dist\*.exe
- name: Code Signing Request
uses: signpath/github-action-submit-signing-request@v2
with:
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
organization-id: 'c36aaa28-05f1-40aa-b65d-122efb3f4699'
project-slug: 'ODX'
signing-policy-slug: 'test-signing'
github-artifact-id: '${{ steps.upload-unsigned-artifact.outputs.artifact-id }}'
wait-for-completion: true
output-artifact-directory: 'dist/signed'
- name: Upload Setup to Release
uses: svenstaro/upload-release-action@v2
if: startsWith(github.ref, 'refs/tags/')
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: dist/*.exe
file: dist/signed/*.exe
file_glob: true
tag: ${{ github.ref }}
overwrite: true
Expand Down
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

![CPU Build](https://img.shields.io/github/actions/workflow/status/WebODM/ODX/publish-docker.yml?branch=master&label=docker%20CPU) ![GPU Build](https://img.shields.io/github/actions/workflow/status/WebODM/ODX/publish-docker-gpu.yml?branch=master&label=docker%20GPU) ![Windows Build](https://img.shields.io/github/actions/workflow/status/WebODM/ODX/publish-windows.yml?branch=master&label=windows) ![Version](https://img.shields.io/github/v/release/WebODM/ODX) ![License](https://img.shields.io/github/license/WebODM/ODX) ![Contributors](https://img.shields.io/github/contributors/WebODM/ODX) ![Updated](https://img.shields.io/github/last-commit/WebODM/ODX)

> **📢 Now with NVIDIA GeForce RTX 50 Series support, checkpoints support and tons of improvements!** [Read the announcement](https://webodm.org/blog/announcement/)
> **📢 Now faster than ODM, with OpenSfM 1.0 support, GPU based feature matching, NVIDIA GeForce RTX 50 Series support, checkpoints support and tons of improvements!** [Read the announcement](https://webodm.org/blog/announcement/)

A free and open source photogrammetry engine for processing aerial and ground imagery. ODX turns images into:

Expand Down Expand Up @@ -221,6 +221,14 @@ The dev environment makes use of `webodm/nodeodx` by default. You may want to ru

In order to make a clean build, remove `~/.odm-dev-home` and `ODX/.setupdevenv`.

## Code signing policy

Free code signing provided by SignPath.io, certificate by SignPath Foundation.

* Approvers, committers and reviewers: https://github.com/orgs/WebODM/people

This program will not transfer any information to other networked systems unless specifically requested by the user or the person installing or operating it.

## Credits

ODX makes use of other awesome open source projects to perform its tasks. Among them we'd like to highlight:
Expand Down
5 changes: 3 additions & 2 deletions SuperBuild/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,9 @@ set(ODM_Ceres_Version 2.0.0)
option(ODM_BUILD_Ceres "Force to build Ceres library" OFF)
SETUP_EXTERNAL_PROJECT(Ceres ${ODM_Ceres_Version} ${ODM_BUILD_Ceres})

set(custom_libs OpenSfM
LASzip
set(custom_libs Abseil
LASzip
OpenSfM
PDAL
PDALPython
Untwine
Expand Down
29 changes: 29 additions & 0 deletions SuperBuild/cmake/External-Abseil.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
set(_proj_name abseil)
set(_SB_BINARY_DIR "${SB_BINARY_DIR}/${_proj_name}")

ExternalProject_Add(${_proj_name}
DEPENDS
PREFIX ${_SB_BINARY_DIR}
TMP_DIR ${_SB_BINARY_DIR}/tmp
STAMP_DIR ${_SB_BINARY_DIR}/stamp
#--Download step--------------
DOWNLOAD_DIR ${SB_DOWNLOAD_DIR}/${_proj_name}
URL https://github.com/abseil/abseil-cpp/archive/refs/heads/lts_2026_01_07.zip
#--Update/Patch step----------
UPDATE_COMMAND ""
#--Configure step-------------
SOURCE_DIR ${SB_SOURCE_DIR}/${_proj_name}
CMAKE_ARGS
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
-DCMAKE_CXX_STANDARD=17
-DCMAKE_CXX_STANDARD_REQUIRED=ON
-DCMAKE_INSTALL_PREFIX=${SB_INSTALL_DIR}
#--Build step-----------------
BINARY_DIR ${_SB_BINARY_DIR}
#--Install step---------------
INSTALL_DIR ${SB_INSTALL_DIR}
#--Output logging-------------
LOG_DOWNLOAD OFF
LOG_CONFIGURE OFF
LOG_BUILD OFF
)
2 changes: 1 addition & 1 deletion SuperBuild/cmake/External-FPCFilter.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ ExternalProject_Add(${_proj_name}
#--Download step--------------
DOWNLOAD_DIR ${SB_DOWNLOAD_DIR}
GIT_REPOSITORY https://github.com/WebODM/FPCFilter
GIT_TAG bbac1be23832a51a5d23a4f896a4ef43b55eb306
GIT_TAG b747662c908cafda3a0ceb7cb723e27f14ba585c
#--Update/Patch step----------
UPDATE_COMMAND ""
#--Configure step-------------
Expand Down
2 changes: 1 addition & 1 deletion SuperBuild/cmake/External-Obj2Tiles.cmake
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
set(_proj_name obj2tiles)
set(_SB_BINARY_DIR "${SB_BINARY_DIR}/${_proj_name}")

set(OBJ2TILES_VERSION v1.4.0)
set(OBJ2TILES_VERSION v1.5.0)
set(OBJ2TILES_EXT "")

set(OBJ2TILES_ARCH "Linux64")
Expand Down
15 changes: 11 additions & 4 deletions SuperBuild/cmake/External-OpenSfM.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,30 @@ set(EXTRA_INCLUDE_DIRS "")
if(WIN32)
set(OpenCV_DIR "${SB_INSTALL_DIR}/x64/vc17/lib")
set(BUILD_CMD ${CMAKE_COMMAND} --build "${SB_BUILD_DIR}/opensfm" --config "${CMAKE_BUILD_TYPE}")
set(LASZIP_LIB "${SB_INSTALL_DIR}/lib/laszip.lib")

else()
set(BUILD_CMD make "-j${nproc}")
if (APPLE)
set(OpenCV_DIR "${SB_INSTALL_DIR}")
set(EXTRA_INCLUDE_DIRS "${HOMEBREW_INSTALL_PREFIX}/include")
set(LASZIP_LIB "${SB_INSTALL_DIR}/lib/liblaszip.dylib")

else()
set(OpenCV_DIR "${SB_INSTALL_DIR}/lib/cmake/opencv4")
set(LASZIP_LIB "${SB_INSTALL_DIR}/lib/liblaszip.so")
endif()
endif()

ExternalProject_Add(${_proj_name}
DEPENDS ceres opencv gflags
DEPENDS abseil ceres opencv gflags laszip
PREFIX ${_SB_BINARY_DIR}
TMP_DIR ${_SB_BINARY_DIR}/tmp
STAMP_DIR ${_SB_BINARY_DIR}/stamp
#--Download step--------------
DOWNLOAD_DIR ${SB_DOWNLOAD_DIR}
GIT_REPOSITORY https://github.com/WebODM/OpenSfM/
GIT_TAG 91f58841370b0c28bc1248d038b1930fa11d0637
GIT_TAG bf7f84a9109098971f7a15ed9b0348b98e093ed7
#--Update/Patch step----------
UPDATE_COMMAND git submodule update --init --recursive
#--Configure step-------------
Expand All @@ -37,12 +42,14 @@ ExternalProject_Add(${_proj_name}
-DYET_ADDITIONAL_INCLUDE_DIRS=${EXTRA_INCLUDE_DIRS}
-DOPENSFM_BUILD_TESTS=off
-DPYTHON_EXECUTABLE=${PYTHON_EXE_PATH}
-DLASZIP_LIBRARY=${LASZIP_LIB}
-DLASZIP_INCLUDE_DIR=${SB_INSTALL_DIR}/include/laszip
-Dabsl_DIR=${SB_INSTALL_DIR}/lib/cmake/absl
-DCMAKE_INSTALL_PREFIX=${SB_INSTALL_DIR}/bin/${_proj_name}/opensfm
${WIN32_CMAKE_ARGS}
BUILD_COMMAND ${BUILD_CMD}
#--Build step-----------------
BINARY_DIR ${_SB_BINARY_DIR}
#--Install step---------------
INSTALL_COMMAND ""
#--Output logging-------------
LOG_DOWNLOAD OFF
LOG_CONFIGURE OFF
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.7.6
3.8.0
10 changes: 9 additions & 1 deletion configure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ installruntimedeps() {
libjpeg-turbo8 \
libopenjpip7 \
liblapack3 \
libtcmalloc-minimal4t64 \
libpng16-16 \
libproj25 \
libswscale7 \
Expand Down Expand Up @@ -147,6 +148,7 @@ installbuilddeps(){
libgtk2.0-dev \
libjpeg-dev \
liblapack-dev \
libtcmalloc-minimal4t64 \
libopenjpip7 \
libpng-dev \
libproj-dev \
Expand Down Expand Up @@ -241,8 +243,14 @@ clean() {
${RUNPATH}/SuperBuild/build \
${RUNPATH}/SuperBuild/download \
${RUNPATH}/SuperBuild/src \
${RUNPATH}/SuperBuild/install/include/ \
${RUNPATH}/SuperBuild/install/bin/opensfm/.git \
${RUNPATH}/SuperBuild/install/bin/opensfm/opensfm/src/third_party/pybind11/.git
${RUNPATH}/SuperBuild/install/bin/opensfm/.github \
${RUNPATH}/SuperBuild/install/bin/opensfm/annotation_gui_gcp \
${RUNPATH}/SuperBuild/install/bin/opensfm/doc \
${RUNPATH}/SuperBuild/install/bin/opensfm/viewer \
${RUNPATH}/SuperBuild/install/bin/opensfm/data \
${RUNPATH}/SuperBuild/install/bin/opensfm/opensfm/src/lib/third_party/pybind11/.git

# find in /code and delete static libraries and intermediate object files
find ${RUNPATH} -type f -name "*.a" -delete -or -type f -name "*.o" -delete
Expand Down
2 changes: 1 addition & 1 deletion opendm/boundary.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def compute_boundary_from_shots(reconstruction_json, buffer=0, reconstruction_of

for shot_image in reconstruction['shots']:
shot = reconstruction['shots'][shot_image]
if shot.get('gps_dop', 999999) < 999999:
if shot.get('gps_accuracy', [999999])[0] < 999999:
camera = reconstruction['cameras'][shot['camera']]

p = ogr.Geometry(ogr.wkbPoint)
Expand Down
25 changes: 19 additions & 6 deletions opendm/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,9 @@ def config(argv=None, parser=None):
parser.add_argument('--matcher-type',
metavar='<string>',
action=StoreValue,
default='flann',
choices=['bow', 'bruteforce', 'flann'],
help=('Matcher algorithm, Fast Library for Approximate Nearest Neighbors or Bag of Words. FLANN is slower, but more stable. BOW is faster, but can sometimes miss valid matches. BRUTEFORCE is very slow but robust.'
default='auto',
choices=['auto', 'bow', 'bruteforce', 'flann', 'hamming'],
help=('Matcher algorithm, Fast Library for Approximate Nearest Neighbors or Bag of Words. FLANN is slower, but more stable. BOW is faster, but can sometimes miss valid matches. BRUTEFORCE is very slow but robust. HAMMING is much faster with large datasets but requires a GPU.'
'Can be one of: %(choices)s. Default: '
'%(default)s'))

Expand Down Expand Up @@ -328,7 +328,7 @@ def config(argv=None, parser=None):
action=StoreValue,
default='incremental',
choices=['incremental', 'triangulation', 'planar'],
help=('Choose the structure from motion algorithm. For aerial datasets, if camera GPS positions and angles are available, triangulation can generate better results. For planar scenes captured at fixed altitude with nadir-only images, planar can be much faster. '
help=('Choose the structure from motion algorithm. For aerial datasets, if camera GPS positions and angles are available, triangulation can be faster. Planar is deprecated and will be removed in a future version. '
'Can be one of: %(choices)s. Default: '
'%(default)s'))

Expand Down Expand Up @@ -548,6 +548,14 @@ def config(argv=None, parser=None):
help='Simple Morphological Filter window radius parameter (meters). '
'Default: %(default)s')

parser.add_argument('--report-units',
metavar='<string>',
action=StoreValue,
type=str,
choices=['m', 'ft', 'US survey foot'],
default='m',
help='Set the units of the PDF report. By default the vertical units of the coordinate reference system are used. Can be one of: %(choices)s. Default: %(default)s')

parser.add_argument('--texturing-skip-global-seam-leveling',
action=StoreTrue,
nargs=0,
Expand Down Expand Up @@ -854,8 +862,9 @@ def config(argv=None, parser=None):
default=3,
help='Set a value in meters for the GPS Dilution of Precision (DOP) '
'information for all images. If your images are tagged '
'with high precision GPS information (RTK), this value can be lowered. '
'Lowering this option can sometimes help control bowling-effects over large areas. Default: %(default)s')
'with high precision GPS information (RTK), this value will be automatically '
'set accordingly. You can use this option to manually set it in case the reconstruction '
'fails. Lowering this option can sometimes help control bowling-effects over large areas. Default: %(default)s')

parser.add_argument('--gps-z-offset',
type=float,
Expand Down Expand Up @@ -926,6 +935,10 @@ def config(argv=None, parser=None):
if args.orthophoto_cutline and not args.crop:
log.WARNING("--orthophoto-cutline is set, but --crop is not. --crop will be set to 0.01")
args.crop = 0.01

if args.sfm_algorithm == 'planar':
log.WARNING("--sfm-algorithm planar is deprecated. --sfm-algorithm will be set to incremental")
args.sfm_algorithm = 'incremental'

if args.sm_cluster:
try:
Expand Down
3 changes: 1 addition & 2 deletions opendm/context.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import os
import sys
import multiprocessing

# Define some needed locations
current_path = os.path.abspath(os.path.dirname(__file__))
Expand Down Expand Up @@ -42,7 +41,7 @@
supported_video_extensions = {'.mp4', '.mov', '.lrv', '.ts'}

# Define the number of cores
num_cores = multiprocessing.cpu_count()
num_cores = os.cpu_count()


# Print python paths if invoked as a script
Expand Down
Loading
Loading