Merge pull request #1362 from pierotofy/gpuomvs

GPU-enabled Point Cloud Densification (OpenMVS)
pull/1374/head
Piero Toffanin 2021-11-15 15:54:05 -05:00 zatwierdzone przez GitHub
commit b69f5ef26b
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
22 zmienionych plików z 102 dodań i 36 usunięć

Wyświetl plik

@ -22,6 +22,10 @@ jobs:
uses: ilammy/msvc-dev-cmd@v1
with:
arch: x64
- uses: Jimver/cuda-toolkit@v0.2.4
id: cuda-toolkit
with:
cuda: '11.2.2'
- name: Extract code signing cert
id: code_sign
uses: timheuer/base64-to-file@v1

Wyświetl plik

@ -23,7 +23,7 @@ ExternalProject_Add(${_proj_name}
-DADDITIONAL_LINK_DIRECTORIES_PATHS=${SB_INSTALL_DIR}/lib
-DWITH_TESTS=OFF
-DWITH_ZSTD=OFF
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR}
#--Build step-----------------
BINARY_DIR ${_SB_BINARY_DIR}

Wyświetl plik

@ -15,7 +15,7 @@ ExternalProject_Add(${_proj_name}
SOURCE_DIR ${SB_SOURCE_DIR}/${_proj_name}
CMAKE_ARGS
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
-DCMAKE_BUILD_TYPE:STRING=Release
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
-DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR}
#--Build step-----------------
BINARY_DIR ${_SB_BINARY_DIR}

Wyświetl plik

@ -16,7 +16,7 @@ ExternalProject_Add(${_proj_name}
SOURCE_DIR ${SB_SOURCE_DIR}/${_proj_name}
CMAKE_ARGS
-DRESEARCH=OFF
-DCMAKE_BUILD_TYPE:STRING=Release
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
-DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR}
${WIN32_CMAKE_ARGS}
#--Build step-----------------

Wyświetl plik

@ -57,7 +57,7 @@ ExternalProject_Add(${_proj_name}
-DBUILD_opencv_ts=OFF
-DBUILD_opencv_xfeatures2d=ON
-DOPENCV_ALLOCATOR_STATS_COUNTER_TYPE=int64_t
-DCMAKE_BUILD_TYPE:STRING=Release
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
-DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR}
${WIN32_CMAKE_ARGS}
${WIN32_CMAKE_EXTRA_ARGS}

Wyświetl plik

@ -12,20 +12,38 @@ externalproject_add(vcg
INSTALL_COMMAND ""
)
externalproject_add(eigen34
GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
GIT_TAG 3.4
UPDATE_COMMAND ""
SOURCE_DIR ${SB_SOURCE_DIR}/eigen34
CONFIGURE_COMMAND ""
BUILD_IN_SOURCE 1
BUILD_COMMAND ""
INSTALL_COMMAND ""
)
SET(ARM64_CMAKE_ARGS "")
if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64" )
SET(ARM64_CMAKE_ARGS -DOpenMVS_USE_SSE=OFF)
endif()
SET(GPU_CMAKE_ARGS "")
if(UNIX)
if (EXISTS "/usr/local/cuda/lib64/stubs")
SET(GPU_CMAKE_ARGS -DCMAKE_LIBRARY_PATH=/usr/local/cuda/lib64/stubs)
endif()
endif()
ExternalProject_Add(${_proj_name}
DEPENDS ceres opencv vcg
DEPENDS ceres opencv vcg eigen34
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/openMVS
GIT_TAG 256
GIT_TAG 267
#--Update/Patch step----------
UPDATE_COMMAND ""
#--Configure step-------------
@ -33,8 +51,11 @@ ExternalProject_Add(${_proj_name}
CMAKE_ARGS
-DOpenCV_DIR=${SB_INSTALL_DIR}/lib/cmake/opencv4
-DVCG_ROOT=${SB_SOURCE_DIR}/vcg
-DCMAKE_BUILD_TYPE=Release
-DEIGEN3_INCLUDE_DIR=${SB_SOURCE_DIR}/eigen34/
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DCMAKE_INSTALL_PREFIX=${SB_INSTALL_DIR}
-DOpenMVS_MAX_CUDA_COMPATIBILITY=ON
${GPU_CMAKE_ARGS}
${WIN32_CMAKE_ARGS}
${ARM64_CMAKE_ARGS}
#--Build step-----------------

Wyświetl plik

@ -39,7 +39,7 @@ ExternalProject_Add(${_proj_name}
-DWITH_LIBUSB=OFF
-DWITH_PCAP=OFF
-DWITH_PXCAPI=OFF
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DPCL_VERBOSITY_LEVEL=Error
-DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR}
-DPCL_BUILD_WITH_FLANN_DYNAMIC_LINKING_WIN32=ON

Wyświetl plik

@ -45,7 +45,7 @@ ExternalProject_Add(${_proj_name}
-DLASZIP_INCLUDE_DIR=${SB_INSTALL_DIR}/include
-DLASZIP_LIBRARY=${LASZIP_LIB}
-DWITH_TESTS=OFF
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR}
${WIN32_CMAKE_ARGS}
${WIN32_GDAL_ARGS}

Wyświetl plik

@ -16,7 +16,7 @@ ExternalProject_Add(${_proj_name}
SOURCE_DIR ${SB_SOURCE_DIR}/${_proj_name}
CMAKE_ARGS
-DPDAL_DIR=${SB_INSTALL_DIR}/lib/cmake/PDAL
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR}
#--Build step-----------------
BINARY_DIR ${_SB_BINARY_DIR}

Wyświetl plik

@ -1 +1 @@
2.6.6
2.6.7

Wyświetl plik

@ -1,4 +1,4 @@
FROM nvidia/cuda:11.2.0-runtime-ubuntu20.04 AS builder
FROM nvidia/cuda:11.2.0-devel-ubuntu20.04 AS builder
# Env variables
ENV DEBIAN_FRONTEND=noninteractive \
@ -22,6 +22,7 @@ RUN bash configure.sh clean
### Use a second image for the final asset to reduce the number and
# size of the layers.
FROM nvidia/cuda:11.2.0-runtime-ubuntu20.04
#FROM nvidia/cuda:11.2.0-devel-ubuntu20.04
# Env variables
ENV DEBIAN_FRONTEND=noninteractive \

Wyświetl plik

@ -133,7 +133,7 @@ def config(argv=None, parser=None):
metavar='<string>',
action=StoreValue,
default='sift',
choices=['sift', 'orb', 'hahog'],
choices=['akaze', 'hahog', 'orb', 'sift'],
help=('Choose the algorithm for extracting keypoints and computing descriptors. '
'Can be one of: %(choices)s. Default: '
'%(default)s'))
@ -151,8 +151,8 @@ def config(argv=None, parser=None):
metavar='<string>',
action=StoreValue,
default='flann',
choices=['flann', 'bow'],
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. '
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.'
'Can be one of: %(choices)s. Default: '
'%(default)s'))

Wyświetl plik

@ -16,7 +16,10 @@ class GCPFile:
if self.exists():
with open(self.gcp_path, 'r') as f:
contents = f.read().strip()
# Strip eventual BOM characters
contents = contents.replace('\ufeff', '')
lines = list(map(str.strip, contents.split('\n')))
if lines:
self.raw_srs = lines[0] # SRS

Wyświetl plik

@ -2,9 +2,12 @@ import os
from opendm import log
from repoze.lru import lru_cache
def gpu_disabled_by_user():
return bool(os.environ.get('ODM_NO_GPU'))
@lru_cache(maxsize=None)
def has_gpus():
if os.environ.get('ODM_NO_GPU'):
if gpu_disabled_by_user():
log.ODM_INFO("Disabling GPU features (ODM_NO_GPU is set)")
return False

Wyświetl plik

@ -122,6 +122,7 @@ def parse_srs_header(header):
log.ODM_INFO('Parsing SRS header: %s' % header)
header = header.strip()
ref = header.split(' ')
try:
if ref[0] == 'WGS84' and ref[1] == 'UTM':
datum = ref[0]

Wyświetl plik

@ -117,9 +117,6 @@ class OSFMContext:
except Exception as e:
log.ODM_WARNING("Cannot set camera_models_overrides.json: %s" % str(e))
use_bow = args.matcher_type == "bow"
feature_type = "SIFT"
# GPSDOP override if we have GPS accuracy information (such as RTK)
if 'gps_accuracy_is_set' in args:
log.ODM_INFO("Forcing GPS DOP to %s for all images" % args.gps_accuracy)
@ -208,22 +205,29 @@ class OSFMContext:
if args.camera_lens != 'auto':
config.append("camera_projection_type: %s" % args.camera_lens.upper())
if not has_gps:
log.ODM_INFO("No GPS information, using BOW matching")
use_bow = True
matcher_type = args.matcher_type
feature_type = args.feature_type.upper()
if use_bow:
config.append("matcher_type: WORDS")
osfm_matchers = {
"bow": "WORDS",
"flann": "FLANN",
"bruteforce": "BRUTEFORCE"
}
# Cannot use SIFT with BOW
if feature_type == "SIFT":
if not has_gps and not 'matcher_type_is_set' in args:
log.ODM_INFO("No GPS information, using BOW matching by default (you can override this by setting --matcher-type explicitly)")
matcher_type = "bow"
if matcher_type == "bow":
# Cannot use anything other than HAHOG with BOW
if feature_type != "HAHOG":
log.ODM_WARNING("Using BOW matching, will use HAHOG feature type, not SIFT")
feature_type = "HAHOG"
config.append("matcher_type: %s" % osfm_matchers[matcher_type])
# GPU acceleration?
if has_gpus() and feature_type == "SIFT":
if has_gpus() and feature_type == "SIFT" and (not 'min_num_features_is_set' in args):
log.ODM_INFO("Using GPU for extracting SIFT features")
log.ODM_INFO("--min-num-features will be ignored")
feature_type = "SIFT_GPU"

Wyświetl plik

@ -341,6 +341,10 @@ class Task:
if os.path.exists(self.path("gcp_list.txt")):
images.append(self.path("gcp_list.txt"))
# Add GEO (optional)
if os.path.exists(self.path("geo.txt")):
images.append(self.path("geo.txt"))
# Add seed file
images.append(seed_file)

Wyświetl plik

@ -25,7 +25,6 @@ class ODM_Reconstruction(object):
self.photos = photos
self.georef = None
self.gcp = None
self.geo_file = None
self.multi_camera = self.detect_multi_camera()
def detect_multi_camera(self):

Wyświetl plik

@ -115,7 +115,7 @@ class ODMLoadDatasetStage(types.ODM_Stage):
dataset_list.write(photos[-1].filename + '\n')
# Check if a geo file is available
if tree.odm_geo_file is not None and os.path.exists(tree.odm_geo_file):
if tree.odm_geo_file is not None and os.path.isfile(tree.odm_geo_file):
log.ODM_INFO("Found image geolocation file")
gf = GeoFile(tree.odm_geo_file)
updated = 0

Wyświetl plik

@ -6,6 +6,7 @@ from opendm import system
from opendm import context
from opendm import point_cloud
from opendm import types
from opendm.gpu import gpu_disabled_by_user
from opendm.utils import get_depthmap_resolution
from opendm.osfm import OSFMContext
from opendm.multispectral import get_primary_band_name
@ -62,7 +63,7 @@ class ODMOpenMVSStage(types.ODM_Stage):
config = [
" --resolution-level %s" % int(resolution_level),
"--min-resolution %s" % depthmap_resolution,
"--min-resolution %s" % depthmap_resolution,
"--max-resolution %s" % int(outputs['undist_image_max_size']),
"--max-threads %s" % args.max_concurrency,
"--number-views-fuse 2",
@ -70,6 +71,9 @@ class ODMOpenMVSStage(types.ODM_Stage):
"-v 0"
]
if gpu_disabled_by_user():
config.append("--cuda-device -1")
if args.pc_tile:
config.append("--fusion-mode 1")

Wyświetl plik

@ -89,7 +89,13 @@ class ODMSplitStage(types.ODM_Stage):
io.copy(submodel_gcp_file, os.path.abspath(sp_octx.path("gcp_list.txt")))
else:
log.ODM_INFO("No GCP will be copied for %s, not enough images in the submodel are referenced by the GCP" % sp_octx.name())
# Copy GEO file if needed (one for each submodel project directory)
if tree.odm_geo_file is not None and os.path.isfile(tree.odm_geo_file):
geo_dst_path = os.path.abspath(sp_octx.path("..", "geo.txt"))
io.copy(tree.odm_geo_file, geo_dst_path)
log.ODM_INFO("Copied GEO file to %s" % geo_dst_path)
# Reconstruct each submodel
log.ODM_INFO("Dataset has been split into %s submodels. Reconstructing each submodel..." % len(submodel_paths))
self.update_progress(25)

Wyświetl plik

@ -23,6 +23,7 @@ if [ "$1" = "--setup" ]; then
echo "Adding $2 to /etc/shadow"
echo "$2:x:14871::::::" >> /etc/shadow
echo "$2 ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
echo "odm ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
echo "echo '' && echo '' && echo '' && echo '###################################' && echo 'ODM Dev Environment Ready. Hack on!' && echo '###################################' && echo '' && cd /code" > $HOME/.bashrc
# Install qt creator
@ -81,12 +82,20 @@ fi
if hash docker 2>/dev/null; then
has_docker="YES"
fi
if hash nvidia-smi 2>/dev/null; then
has_nvidia_smi="YES"
fi
if [ "$has_docker" != "YES" ]; then
echo "You need to install docker before running this script."
exit 1
fi
IMAGE_SET=NO
if [[ ! -z $IMAGE ]]; then
IMAGE_SET=YES
fi
export PORT="${PORT:=3000}"
export QTC="${QTC:=NO}"
export IMAGE="${IMAGE:=opendronemap/nodeodm}"
@ -119,11 +128,18 @@ fi
USER_ID=$(id -u)
GROUP_ID=$(id -g)
USER=$(id -un)
GPU_FLAG=""
GPU_FLAGS=""
if [[ "$GPU" != "NO" ]]; then
GPU_FLAG="--gpus all"
if [[ "$IMAGE_SET" = "NO" ]]; then
IMAGE="$IMAGE:gpu"
fi
GPU_FLAGS="--gpus all"
if [[ "$has_nvidia_smi" = "YES" ]]; then
GPU_FLAGS="$GPU_FLAGS --device /dev/nvidia0 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidia-modeset --device /dev/nvidiactl"
fi
fi
xhost + || true
docker run -ti --entrypoint bash --name odmdev -v $(pwd):/code -v "$DATA":/datasets -p $PORT:3000 $GPU_FLAG --privileged -e DISPLAY -e LANG=C.UTF-8 -e LC_ALL=C.UTF-8 -v="/tmp/.X11-unix:/tmp/.X11-unix:rw" -v="$HOME/.odm-dev-home:/home/$USER" $IMAGE -c "/code/start-dev-env.sh --setup $USER $USER_ID $GROUP_ID $QTC"
docker run -ti --entrypoint bash --name odmdev --user root -v $(pwd):/code -v "$DATA":/datasets -p $PORT:3000 $GPU_FLAGS --privileged -e DISPLAY -e LANG=C.UTF-8 -e LC_ALL=C.UTF-8 -v="/tmp/.X11-unix:/tmp/.X11-unix:rw" -v="$HOME/.odm-dev-home:/home/$USER" $IMAGE -c "/code/start-dev-env.sh --setup $USER $USER_ID $GROUP_ID $QTC"
exit 0