kopia lustrzana https://github.com/OpenDroneMap/ODM
Pypopsift support
rodzic
4a25bdfb46
commit
0ca7d1cefd
|
@ -137,6 +137,7 @@ set(custom_libs OpenSfM
|
||||||
MvsTexturing
|
MvsTexturing
|
||||||
OpenMVS
|
OpenMVS
|
||||||
FPCFilter
|
FPCFilter
|
||||||
|
PyPopsift
|
||||||
)
|
)
|
||||||
|
|
||||||
# Build entwine only on Linux
|
# Build entwine only on Linux
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
set(_proj_name fpcfilter)
|
||||||
|
set(_SB_BINARY_DIR "${SB_BINARY_DIR}/${_proj_name}")
|
||||||
|
|
||||||
|
ExternalProject_Add(${_proj_name}
|
||||||
|
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/OpenDroneMap/FPCFilter
|
||||||
|
GIT_TAG main
|
||||||
|
#--Update/Patch step----------
|
||||||
|
UPDATE_COMMAND ""
|
||||||
|
#--Configure step-------------
|
||||||
|
SOURCE_DIR ${SB_SOURCE_DIR}/${_proj_name}
|
||||||
|
CMAKE_ARGS
|
||||||
|
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||||
|
-DCMAKE_INSTALL_PREFIX:PATH=${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
|
||||||
|
)
|
|
@ -0,0 +1,37 @@
|
||||||
|
set(_SB_BINARY_DIR "${SB_BINARY_DIR}/pypopsift")
|
||||||
|
|
||||||
|
# Pypopsift
|
||||||
|
find_package(CUDA 7.0)
|
||||||
|
|
||||||
|
if(CUDA_FOUND)
|
||||||
|
ExternalProject_Add(pypopsift
|
||||||
|
DEPENDS opensfm
|
||||||
|
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/uav4geo/pypopsift
|
||||||
|
GIT_TAG 270
|
||||||
|
#--Update/Patch step----------
|
||||||
|
UPDATE_COMMAND ""
|
||||||
|
#--Configure step-------------
|
||||||
|
SOURCE_DIR ${SB_SOURCE_DIR}/pypopsift
|
||||||
|
CMAKE_ARGS
|
||||||
|
-DOUTPUT_DIR=${SB_INSTALL_DIR}/bin/opensfm/opensfm
|
||||||
|
-DCMAKE_INSTALL_PREFIX=${SB_INSTALL_DIR}
|
||||||
|
${GPU_CMAKE_ARGS}
|
||||||
|
${WIN32_CMAKE_ARGS}
|
||||||
|
${ARM64_CMAKE_ARGS}
|
||||||
|
#--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
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
message(WARNING "Could not find CUDA >= 7.0")
|
||||||
|
endif()
|
|
@ -130,7 +130,7 @@ installreqs() {
|
||||||
set -e
|
set -e
|
||||||
pip install --ignore-installed -r requirements.txt
|
pip install --ignore-installed -r requirements.txt
|
||||||
if [ ! -z "$GPU_INSTALL" ]; then
|
if [ ! -z "$GPU_INSTALL" ]; then
|
||||||
pip install --ignore-installed -r requirements.gpu.txt
|
# Nothing, add extra GPU-related build instructions here
|
||||||
fi
|
fi
|
||||||
set +e
|
set +e
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,9 +37,6 @@ COPY --from=builder /code /code
|
||||||
# Copy the Python libraries installed via pip from the builder
|
# Copy the Python libraries installed via pip from the builder
|
||||||
COPY --from=builder /usr/local /usr/local
|
COPY --from=builder /usr/local /usr/local
|
||||||
|
|
||||||
# Install OpenCL Drivers
|
|
||||||
RUN apt update && apt install -y nvidia-opencl-icd-340 intel-opencl-icd
|
|
||||||
|
|
||||||
# Install shared libraries that we depend on via APT, but *not*
|
# Install shared libraries that we depend on via APT, but *not*
|
||||||
# the -dev packages to save space!
|
# the -dev packages to save space!
|
||||||
# Also run a smoke test
|
# Also run a smoke test
|
||||||
|
|
|
@ -162,9 +162,7 @@ def config(argv=None, parser=None):
|
||||||
default=8,
|
default=8,
|
||||||
type=int,
|
type=int,
|
||||||
help='Number of nearest images to pre-match based on GPS '
|
help='Number of nearest images to pre-match based on GPS '
|
||||||
'exif data. Set to 0 to skip pre-matching. '
|
'exif data. Set to 0 to skip pre-matching. Default: %(default)s')
|
||||||
'Neighbors works together with Distance parameter, '
|
|
||||||
'set both to 0 to not use pre-matching. Default: %(default)s')
|
|
||||||
|
|
||||||
parser.add_argument('--use-fixed-camera-params',
|
parser.add_argument('--use-fixed-camera-params',
|
||||||
action=StoreTrue,
|
action=StoreTrue,
|
||||||
|
@ -236,7 +234,7 @@ def config(argv=None, parser=None):
|
||||||
action=StoreValue,
|
action=StoreValue,
|
||||||
default='incremental',
|
default='incremental',
|
||||||
choices=['incremental', 'triangulation'],
|
choices=['incremental', 'triangulation'],
|
||||||
help=('Choose the structure from motion algorithm. If camera positions and angles are available, triangulation is significantly faster for aerial datasets. '
|
help=('Choose the structure from motion algorithm. For aerial datasets, if camera GPS positions and angles are available, triangulation is faster. '
|
||||||
'Can be one of: %(choices)s. Default: '
|
'Can be one of: %(choices)s. Default: '
|
||||||
'%(default)s'))
|
'%(default)s'))
|
||||||
|
|
||||||
|
@ -770,9 +768,9 @@ def config(argv=None, parser=None):
|
||||||
if args.fast_orthophoto:
|
if args.fast_orthophoto:
|
||||||
log.ODM_INFO('Fast orthophoto is turned on, automatically setting --skip-3dmodel')
|
log.ODM_INFO('Fast orthophoto is turned on, automatically setting --skip-3dmodel')
|
||||||
args.skip_3dmodel = True
|
args.skip_3dmodel = True
|
||||||
if not 'sfm_algorithm_is_set' in args:
|
# if not 'sfm_algorithm_is_set' in args:
|
||||||
log.ODM_INFO('Fast orthophoto is turned on, automatically setting --sfm-algorithm to triangulation')
|
# log.ODM_INFO('Fast orthophoto is turned on, automatically setting --sfm-algorithm to triangulation')
|
||||||
args.sfm_algorithm = 'triangulation'
|
# args.sfm_algorithm = 'triangulation'
|
||||||
|
|
||||||
if args.pc_rectify and not args.pc_classify:
|
if args.pc_rectify and not args.pc_classify:
|
||||||
log.ODM_INFO("Ground rectify is turned on, automatically turning on point cloud classification")
|
log.ODM_INFO("Ground rectify is turned on, automatically turning on point cloud classification")
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import shutil
|
||||||
from opendm import log
|
from opendm import log
|
||||||
from repoze.lru import lru_cache
|
from repoze.lru import lru_cache
|
||||||
|
|
||||||
|
@ -7,38 +8,29 @@ def gpu_disabled_by_user():
|
||||||
return bool(os.environ.get('ODM_NO_GPU'))
|
return bool(os.environ.get('ODM_NO_GPU'))
|
||||||
|
|
||||||
@lru_cache(maxsize=None)
|
@lru_cache(maxsize=None)
|
||||||
def has_gpus():
|
def has_popsift():
|
||||||
|
try:
|
||||||
|
from opensfm import pypopsift
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
@lru_cache(maxsize=None)
|
||||||
|
def has_gpu():
|
||||||
if gpu_disabled_by_user():
|
if gpu_disabled_by_user():
|
||||||
log.ODM_INFO("Disabling GPU features (ODM_NO_GPU is set)")
|
log.ODM_INFO("Disabling GPU features (ODM_NO_GPU is set)")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
|
||||||
import pyopencl
|
|
||||||
except:
|
|
||||||
return False
|
|
||||||
|
|
||||||
try:
|
|
||||||
platforms = pyopencl.get_platforms()
|
|
||||||
for p in platforms:
|
|
||||||
log.ODM_INFO("Found GPU device: %s" % p.name)
|
|
||||||
|
|
||||||
return len(platforms) > 0
|
|
||||||
except Exception as e:
|
|
||||||
return False
|
|
||||||
|
|
||||||
@lru_cache(maxsize=None)
|
|
||||||
def windows_no_cuda():
|
|
||||||
"""
|
|
||||||
Check if CUDA lib is available on Windows
|
|
||||||
Returns true if OS is windows and CUDA is not found.
|
|
||||||
"""
|
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
nvcuda_path = os.path.join(os.environ.get('SYSTEMROOT'), 'system32', 'nvcuda.dll')
|
nvcuda_path = os.path.join(os.environ.get('SYSTEMROOT'), 'system32', 'nvcuda.dll')
|
||||||
if os.path.isfile(nvcuda_path):
|
if os.path.isfile(nvcuda_path):
|
||||||
return False
|
return True
|
||||||
else:
|
else:
|
||||||
log.ODM_INFO("No CUDA drivers detected, using CPU")
|
log.ODM_INFO("No CUDA drivers detected, using CPU")
|
||||||
return True
|
return False
|
||||||
else:
|
else:
|
||||||
return False
|
if shutil.which('nvidia-smi') is not None:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
log.ODM_INFO("nvidia-smi not found in PATH, using CPU")
|
||||||
|
return False
|
||||||
|
|
|
@ -21,7 +21,7 @@ from opensfm.actions import undistort
|
||||||
from opensfm.dataset import DataSet
|
from opensfm.dataset import DataSet
|
||||||
from opensfm import report
|
from opensfm import report
|
||||||
from opendm.multispectral import get_photos_by_band
|
from opendm.multispectral import get_photos_by_band
|
||||||
from opendm.gpu import has_gpus
|
from opendm.gpu import has_popsift, has_gpu
|
||||||
from opensfm import multiview, exif
|
from opensfm import multiview, exif
|
||||||
from opensfm.actions.export_geocoords import _transform
|
from opensfm.actions.export_geocoords import _transform
|
||||||
|
|
||||||
|
@ -164,6 +164,7 @@ class OSFMContext:
|
||||||
"feature_min_frames: %s" % args.min_num_features,
|
"feature_min_frames: %s" % args.min_num_features,
|
||||||
"processes: %s" % args.max_concurrency,
|
"processes: %s" % args.max_concurrency,
|
||||||
"matching_gps_neighbors: %s" % args.matcher_neighbors,
|
"matching_gps_neighbors: %s" % args.matcher_neighbors,
|
||||||
|
"matching_gps_distance: 0",
|
||||||
"matching_graph_rounds: 50",
|
"matching_graph_rounds: 50",
|
||||||
"optimize_camera_parameters: %s" % ('no' if args.use_fixed_camera_params or args.cameras else 'yes'),
|
"optimize_camera_parameters: %s" % ('no' if args.use_fixed_camera_params or args.cameras else 'yes'),
|
||||||
"reconstruction_algorithm: %s" % (args.sfm_algorithm),
|
"reconstruction_algorithm: %s" % (args.sfm_algorithm),
|
||||||
|
@ -200,9 +201,8 @@ class OSFMContext:
|
||||||
config.append("matcher_type: %s" % osfm_matchers[matcher_type])
|
config.append("matcher_type: %s" % osfm_matchers[matcher_type])
|
||||||
|
|
||||||
# GPU acceleration?
|
# GPU acceleration?
|
||||||
if has_gpus() and feature_type == "SIFT" and (not 'min_num_features_is_set' in args):
|
if has_gpu() and has_popsift() and feature_type == "SIFT":
|
||||||
log.ODM_INFO("Using GPU for extracting SIFT features")
|
log.ODM_INFO("Using GPU for extracting SIFT features")
|
||||||
log.ODM_INFO("--min-num-features will be ignored")
|
|
||||||
feature_type = "SIFT_GPU"
|
feature_type = "SIFT_GPU"
|
||||||
|
|
||||||
config.append("feature_type: %s" % feature_type)
|
config.append("feature_type: %s" % feature_type)
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
silx>=0.12.0
|
|
||||||
pyopencl==2021.1.1
|
|
|
@ -173,3 +173,11 @@ class ODMLoadDatasetStage(types.ODM_Stage):
|
||||||
else:
|
else:
|
||||||
args.boundary = None
|
args.boundary = None
|
||||||
log.ODM_WARNING("Reconstruction is not georeferenced, but boundary file provided (will ignore boundary file)")
|
log.ODM_WARNING("Reconstruction is not georeferenced, but boundary file provided (will ignore boundary file)")
|
||||||
|
|
||||||
|
# If sfm-algorithm is triangulation, check if photos have OPK
|
||||||
|
if args.sfm_algorithm == 'triangulation':
|
||||||
|
for p in photos:
|
||||||
|
if not p.has_opk():
|
||||||
|
log.ODM_WARNING("No omega/phi/kappa angles found in input photos (%s), switching sfm-algorithm to incremental" % p.filename)
|
||||||
|
args.sfm_algorithm = 'incremental'
|
||||||
|
break
|
||||||
|
|
|
@ -6,7 +6,7 @@ from opendm import system
|
||||||
from opendm import context
|
from opendm import context
|
||||||
from opendm import point_cloud
|
from opendm import point_cloud
|
||||||
from opendm import types
|
from opendm import types
|
||||||
from opendm.gpu import gpu_disabled_by_user, windows_no_cuda
|
from opendm.gpu import has_gpu
|
||||||
from opendm.utils import get_depthmap_resolution
|
from opendm.utils import get_depthmap_resolution
|
||||||
from opendm.osfm import OSFMContext
|
from opendm.osfm import OSFMContext
|
||||||
from opendm.multispectral import get_primary_band_name
|
from opendm.multispectral import get_primary_band_name
|
||||||
|
@ -73,7 +73,7 @@ class ODMOpenMVSStage(types.ODM_Stage):
|
||||||
|
|
||||||
gpu_config = []
|
gpu_config = []
|
||||||
|
|
||||||
if gpu_disabled_by_user() or windows_no_cuda():
|
if not has_gpu():
|
||||||
gpu_config.append("--cuda-device -1")
|
gpu_config.append("--cuda-device -1")
|
||||||
|
|
||||||
if args.pc_tile:
|
if args.pc_tile:
|
||||||
|
|
Ładowanie…
Reference in New Issue