Merge pull request #1201 from pierotofy/221

Improved orthophotos, added --pc-quality flag
pull/1205/head v2.2.1
Piero Toffanin 2020-11-15 00:34:39 -05:00 zatwierdzone przez GitHub
commit 786833d185
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
10 zmienionych plików z 62 dodań i 29 usunięć

Wyświetl plik

@ -29,7 +29,7 @@ jobs:
strategy:
fail-fast: false
matrix:
language: [ 'cpp', 'python' ]
language: [ 'python' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more...
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection

Wyświetl plik

@ -9,7 +9,7 @@ ExternalProject_Add(${_proj_name}
#--Download step--------------
DOWNLOAD_DIR ${SB_DOWNLOAD_DIR}/${_proj_name}
GIT_REPOSITORY https://github.com/OpenDroneMap/mvs-texturing
GIT_TAG 200
GIT_TAG 221
#--Update/Patch step----------
UPDATE_COMMAND ""
#--Configure step-------------

Wyświetl plik

@ -1 +1 @@
2.2.0
2.2.1

Wyświetl plik

@ -235,7 +235,7 @@ def config(argv=None, parser=None):
action=StoreValue,
type=float,
default=640,
help=('Controls the density of the point cloud by setting the resolution of the depthmap images. Higher values take longer to compute '
help=('Legacy option (use --pc-quality instead). Controls the density of the point cloud by setting the resolution of the depthmap images. Higher values take longer to compute '
'but produce denser point clouds. '
'Default: %(default)s'))
@ -357,6 +357,15 @@ def config(argv=None, parser=None):
'Use 0 to disable cropping. '
'Default: %(default)s'))
parser.add_argument('--pc-quality',
metavar='<string>',
action=StoreValue,
default='medium',
choices=['ultra', 'high', 'medium', 'low'],
help=('Set point cloud quality. Higher quality generates better, denser point clouds, but requires more memory and takes longer. Each step up in quality increases processing time roughly by a factor of 4x.'
'Can be one of: %(choices)s. Default: '
'%(default)s'))
parser.add_argument('--pc-classify',
action=StoreTrue,
nargs=0,
@ -446,17 +455,6 @@ def config(argv=None, parser=None):
help=('Data term: [area, gmi]. Default: '
'%(default)s'))
parser.add_argument('--texturing-nadir-weight',
metavar='<integer: 0 <= x <= 32>',
action=StoreValue,
default=16,
type=int,
help=('Affects orthophotos only. '
'Higher values result in sharper corners, but can affect color distribution and blurriness. '
'Use lower values for planar areas and higher values for urban areas. '
'The default value works well for most scenarios. Default: '
'%(default)s'))
parser.add_argument('--texturing-outlier-removal-type',
metavar='<string>',
action=StoreValue,

Wyświetl plik

@ -9,6 +9,8 @@ from opendm import log
from opendm import system
from opendm import context
from opendm import camera
from opendm.utils import get_depthmap_resolution
from opendm.photo import find_largest_photo_dim
from opensfm.large import metadataset
from opensfm.large import tools
from opensfm.actions import undistort
@ -145,6 +147,7 @@ class OSFMContext:
# Compute feature_process_size
feature_process_size = 2048 # default
if 'resize_to_is_set' in args:
# Legacy
log.ODM_WARNING("Legacy option --resize-to (this might be removed in a future version). Use --feature-quality instead.")
@ -157,12 +160,8 @@ class OSFMContext:
'low': 0.125,
'lowest': 0.0675,
}
# Find largest photo dimension
max_dim = 0
for p in photos:
if p.width is None:
continue
max_dim = max(max_dim, max(p.width, p.height))
max_dim = find_largest_photo_dim(photos)
if max_dim > 0:
log.ODM_INFO("Maximum photo dimensions: %spx" % str(max_dim))
@ -170,6 +169,8 @@ class OSFMContext:
else:
log.ODM_WARNING("Cannot compute max image dimensions, going with defaults")
depthmap_resolution = get_depthmap_resolution(args, photos)
# create config file for OpenSfM
config = [
"use_exif_size: no",
@ -180,7 +181,7 @@ class OSFMContext:
"matching_gps_neighbors: %s" % matcher_neighbors,
"matching_gps_distance: %s" % args.matcher_distance,
"depthmap_method: %s" % args.opensfm_depthmap_method,
"depthmap_resolution: %s" % args.depthmap_resolution,
"depthmap_resolution: %s" % depthmap_resolution,
"depthmap_min_patch_sd: %s" % args.opensfm_depthmap_min_patch_sd,
"depthmap_min_consistent_views: %s" % args.opensfm_depthmap_min_consistent_views,
"optimize_camera_parameters: %s" % ('no' if args.use_fixed_camera_params or args.cameras else 'yes'),

Wyświetl plik

@ -15,6 +15,15 @@ import xmltodict as x2d
from opendm import get_image_size
from xml.parsers.expat import ExpatError
def find_largest_photo_dim(photos):
max_dim = 0
for p in photos:
if p.width is None:
continue
max_dim = max(max_dim, max(p.width, p.height))
return max_dim
class ODM_Photo:
"""ODMPhoto - a class for ODMPhotos"""

23
opendm/utils.py 100644
Wyświetl plik

@ -0,0 +1,23 @@
from opendm import log
from opendm.photo import find_largest_photo_dim
def get_depthmap_resolution(args, photos):
if 'depthmap_resolution_is_set' in args:
# Legacy
log.ODM_WARNING("Legacy option --depthmap-resolution (this might be removed in a future version). Use --pc-quality instead.")
return int(args.depthmap_resolution)
else:
max_dim = find_largest_photo_dim(photos)
pc_quality_scale = {
'ultra': 0.5,
'high': 0.25,
'medium': 0.125,
'low': 0.0675
}
if max_dim > 0:
return int(max_dim * pc_quality_scale[args.pc_quality])
else:
log.ODM_WARNING("Cannot compute max image dimensions, going with default depthmap_resolution of 640")
return 640 # Sensible default

Wyświetl plik

@ -91,7 +91,6 @@ class ODMMvsTexStage(types.ODM_Stage):
'keepUnseenFaces': keepUnseenFaces,
'toneMapping': self.params.get('tone_mapping'),
'nadirMode': nadir,
'nadirWeight': 2 ** args.texturing_nadir_weight - 1,
'nvm_file': r['nvm_file']
}
@ -111,8 +110,7 @@ class ODMMvsTexStage(types.ODM_Stage):
'{skipLocalSeamLeveling} '
'{skipHoleFilling} '
'{keepUnseenFaces} '
'{nadirMode} '
'-n {nadirWeight}'.format(**kwargs))
'{nadirMode}'.format(**kwargs))
if args.optimize_disk_space:
cleanup_files = [

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.utils import get_depthmap_resolution
from opendm.osfm import OSFMContext
class ODMOpenMVSStage(types.ODM_Stage):
@ -39,15 +40,17 @@ class ODMOpenMVSStage(types.ODM_Stage):
depthmaps_dir = os.path.join(tree.openmvs, "depthmaps")
if not io.dir_exists(depthmaps_dir):
os.mkdir(depthmaps_dir)
depthmap_resolution = get_depthmap_resolution(args, photos)
if outputs["undist_image_max_size"] <= args.depthmap_resolution:
if outputs["undist_image_max_size"] <= depthmap_resolution:
resolution_level = 0
else:
resolution_level = math.floor(math.log(outputs['undist_image_max_size'] / float(args.depthmap_resolution)) / math.log(2))
resolution_level = math.floor(math.log(outputs['undist_image_max_size'] / float(depthmap_resolution)) / math.log(2))
config = [
" --resolution-level %s" % int(resolution_level),
"--min-resolution %s" % int(args.depthmap_resolution),
"--min-resolution %s" % depthmap_resolution,
"--max-resolution %s" % int(outputs['undist_image_max_size']),
"--max-threads %s" % args.max_concurrency,
'-w "%s"' % depthmaps_dir,

Wyświetl plik

@ -10,6 +10,7 @@ from opendm import context
from opendm import gsd
from opendm import point_cloud
from opendm import types
from opendm.utils import get_depthmap_resolution
from opendm.osfm import OSFMContext
from opendm import multispectral
@ -60,7 +61,7 @@ class ODMOpenSfMStage(types.ODM_Stage):
# since the undistorted images are used for MVS
outputs['undist_image_max_size'] = max(
gsd.image_max_size(photos, args.orthophoto_resolution, tree.opensfm_reconstruction, ignore_gsd=args.ignore_gsd, has_gcp=reconstruction.has_gcp()),
args.depthmap_resolution
get_depthmap_resolution(args, photos)
)
if not io.file_exists(updated_config_flag_file) or self.rerun():