Started adding OpenMVS

pull/1172/head
Piero Toffanin 2020-10-27 17:10:10 -04:00
rodzic c100f03576
commit e3cc8f1f9b
11 zmienionych plików z 94 dodań i 29 usunięć

Wyświetl plik

@ -27,7 +27,9 @@ RUN rm -rf \
/code/SuperBuild/src/opencv \
/code/SuperBuild/src/opengv \
/code/SuperBuild/src/pcl \
/code/SuperBuild/src/pdal
/code/SuperBuild/src/pdal \
/code/SuperBuild/src/openmvs \
/code/SuperBuild/build/openmvs
# Entry point
ENTRYPOINT ["python3", "/code/run.py"]

Wyświetl plik

@ -110,6 +110,7 @@ set(custom_libs OpenSfM
PDAL
Entwine
MvsTexturing
OpenMVS
)
foreach(lib ${custom_libs})

Wyświetl plik

@ -91,6 +91,9 @@ install() {
libboost-python-dev \
libboost-date-time-dev \
libboost-thread-dev
echo "Installing OpenMVS Dependencies"
sudo apt-get install -y -qq --no-install-recommends libcgal-dev
pip install --ignore-installed -r requirements.txt

Wyświetl plik

@ -9,7 +9,7 @@ from pyodm import Node, exceptions
import sys
# parse arguments
processopts = ['dataset', 'split', 'merge', 'opensfm', 'mve', 'odm_filterpoints',
processopts = ['dataset', 'split', 'merge', 'opensfm', 'openmvs', 'odm_filterpoints',
'odm_meshing', 'mvs_texturing', 'odm_georeferencing',
'odm_dem', 'odm_orthophoto', 'odm_report']
@ -275,16 +275,6 @@ def config(argv=None, parser=None):
help='Run local bundle adjustment for every image added to the reconstruction and a global '
'adjustment every 100 images. Speeds up reconstruction for very large datasets.')
parser.add_argument('--mve-confidence',
metavar='<float: 0 <= x <= 1>',
action=StoreValue,
type=float,
default=0.60,
help=('Discard points that have less than a certain confidence threshold. '
'This only affects dense reconstructions performed with MVE. '
'Higher values discard more points. '
'Default: %(default)s'))
parser.add_argument('--use-3dmesh',
action=StoreTrue,
nargs=0,

Wyświetl plik

@ -40,6 +40,9 @@ dem2points_path = os.path.join(superbuild_path, 'src', 'dem2points', 'dem2points
# define mvstex path
mvstex_path = os.path.join(superbuild_path, "install/bin/texrecon")
# openmvs paths
omvs_densify_path = os.path.join(superbuild_path, "install/bin/OpenMVS/DensifyPointCloud")
# define txt2las path
txt2las_path = os.path.join(superbuild_path, 'src/las-tools/bin')
pdal_path = os.path.join(superbuild_path, 'build/pdal/bin')

Wyświetl plik

@ -12,8 +12,8 @@ def extract_path_from_file(file):
return path
def join_paths(path1, path2):
return os.path.join(path1, path2)
def join_paths(*args):
return os.path.join(*args)
def file_exists(path_file):

Wyświetl plik

@ -214,6 +214,7 @@ class ODM_Tree(object):
self.dataset_raw = io.join_paths(self.root_path, 'images')
self.opensfm = io.join_paths(self.root_path, 'opensfm')
self.mve = io.join_paths(self.root_path, 'mve')
self.openmvs = io.join_paths(self.opensfm, 'undistorted', 'openmvs')
self.odm_meshing = io.join_paths(self.root_path, 'odm_meshing')
self.odm_texturing = io.join_paths(self.root_path, 'odm_texturing')
self.odm_25dtexturing = io.join_paths(self.root_path, 'odm_texturing_25d')
@ -244,6 +245,9 @@ class ODM_Tree(object):
self.mve_model = io.join_paths(self.mve, 'mve_dense_point_cloud.ply')
self.mve_views = io.join_paths(self.mve, 'views')
# OpenMVS
self.openmvs_model = io.join_paths(self.openmvs, 'scene_dense.ply')
# filter points
self.filtered_point_cloud = io.join_paths(self.odm_filterpoints, "point_cloud.ply")

Wyświetl plik

@ -27,7 +27,9 @@ RUN rm -rf \
/code/SuperBuild/src/opencv \
/code/SuperBuild/src/opengv \
/code/SuperBuild/src/pcl \
/code/SuperBuild/src/pdal
/code/SuperBuild/src/pdal \
/code/SuperBuild/src/openmvs \
/code/SuperBuild/build/openmvs
# Entry point
ENTRYPOINT ["python3", "/code/run.py"]

Wyświetl plik

@ -8,7 +8,7 @@ from opendm import log
from stages.dataset import ODMLoadDatasetStage
from stages.run_opensfm import ODMOpenSfMStage
from stages.mve import ODMMveStage
from stages.openmvs import ODMOpenMVSStage
from stages.odm_slam import ODMSlamStage
from stages.odm_meshing import ODMeshingStage
from stages.mvstex import ODMMvsTexStage
@ -34,7 +34,7 @@ class ODMApp:
merge = ODMMergeStage('merge', args, progress=100.0)
opensfm = ODMOpenSfMStage('opensfm', args, progress=25.0)
slam = ODMSlamStage('slam', args)
mve = ODMMveStage('mve', args, progress=50.0)
openmvs = ODMOpenMVSStage('openmvs', args, progress=50.0)
filterpoints = ODMFilterPoints('odm_filterpoints', args, progress=52.0)
meshing = ODMeshingStage('odm_meshing', args, progress=60.0,
max_vertex=args.mesh_size,
@ -71,8 +71,8 @@ class ODMApp:
if args.use_opensfm_dense or args.fast_orthophoto:
opensfm.connect(filterpoints)
else:
opensfm.connect(mve) \
.connect(filterpoints)
opensfm.connect(openmvs) \
.connect(filterpoints)
filterpoints \
.connect(meshing) \
@ -82,14 +82,5 @@ class ODMApp:
.connect(orthophoto) \
.connect(report)
# # SLAM pipeline
# # TODO: this is broken and needs work
# log.ODM_WARNING("SLAM module is currently broken. We could use some help fixing this. If you know Python, get in touch at https://community.opendronemap.org.")
# self.first_stage = slam
# slam.connect(mve) \
# .connect(meshing) \
# .connect(texturing)
def execute(self):
self.first_stage.run()

Wyświetl plik

@ -21,7 +21,7 @@ class ODMFilterPoints(types.ODM_Stage):
elif args.use_opensfm_dense:
inputPointCloud = tree.opensfm_model
else:
inputPointCloud = tree.mve_model
inputPointCloud = tree.openmvs_model
point_cloud.filter(inputPointCloud, tree.filtered_point_cloud,
standard_deviation=args.pc_filter,

69
stages/openmvs.py 100644
Wyświetl plik

@ -0,0 +1,69 @@
import shutil, os, glob, math
from opendm import log
from opendm import io
from opendm import system
from opendm import context
from opendm import point_cloud
from opendm import types
from opendm.osfm import OSFMContext
class ODMOpenMVSStage(types.ODM_Stage):
def process(self, args, outputs):
# get inputs
tree = outputs['tree']
reconstruction = outputs['reconstruction']
photos = reconstruction.photos
if not photos:
log.ODM_ERROR('Not enough photos in photos array to start OpenMVS')
exit(1)
# check if reconstruction was done before
if not io.file_exists(tree.openmvs_model) or self.rerun():
if io.dir_exists(tree.openmvs):
shutil.rmtree(tree.openmvs)
# export reconstruction from opensfm
octx = OSFMContext(tree.opensfm)
cmd = 'export_openmvs'
if reconstruction.multi_camera:
# Export only the primary band
primary = reconstruction.multi_camera[0]
image_list = os.path.join(tree.opensfm, "image_list_%s.txt" % primary['name'].lower())
cmd += ' --image_list "%s"' % image_list
octx.run(cmd)
self.update_progress(10)
depthmaps_dir = os.path.join(tree.openmvs, "depthmaps")
if not io.dir_exists(depthmaps_dir):
os.mkdir(depthmaps_dir)
resolution_level = int(float(outputs['undist_image_max_size']) / (2*args.depthmap_resolution))
config = [
" --resolution-level %s" % resolution_level,
"--min-resolution %s" % args.depthmap_resolution,
"--max-resolution %s" % outputs['undist_image_max_size'],
"--max-threads %s" % args.max_concurrency,
'-w "%s"' % depthmaps_dir,
"-v 0",
]
log.ODM_INFO("Running dense reconstruction. This might take a while.")
system.run('%s "%s" %s' % (context.omvs_densify_path,
os.path.join(tree.openmvs, 'scene.mvs'),
' '.join(config)))
self.update_progress(90)
if args.optimize_disk_space:
dense_scene = os.path.join(tree.openmvs, 'scene_dense.mvs')
if os.path.exists(dense_scene):
os.remove(dense_scene)
shutil.rmtree(depthmaps_dir)
else:
log.ODM_WARNING('Found a valid OpenMVS reconstruction file in: %s' %
tree.openmvs_model)