Merge pull request #1426 from pierotofy/qfix

Dynamic depthmap resolution
pull/1429/head
Piero Toffanin 2022-03-03 15:20:38 -05:00 zatwierdzone przez GitHub
commit e0974e18d3
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
8 zmienionych plików z 55 dodań i 29 usunięć

Wyświetl plik

@ -218,8 +218,8 @@ def config(argv=None, parser=None):
action=StoreValue,
type=float,
default=640,
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. '
help=('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. Overrides the value calculated by --pc-quality.'
'Default: %(default)s'))
parser.add_argument('--use-hybrid-bundle-adjustment',

Wyświetl plik

@ -322,14 +322,7 @@ def median_smoothing(geotiff_path, output_path, smoothing_iterations=1):
# these edge cases, but it's slower.
for i in range(smoothing_iterations):
log.ODM_INFO("Smoothing iteration %s" % str(i + 1))
arr = ndimage.median_filter(arr, size=5, output=dtype)
# Fill corner points with nearest value
if arr.shape >= (4, 4):
arr[0][:2] = arr[1][0] = arr[1][1]
arr[0][-2:] = arr[1][-1] = arr[2][-1]
arr[-1][:2] = arr[-2][0] = arr[-2][1]
arr[-1][-2:] = arr[-2][-1] = arr[-2][-2]
arr = ndimage.median_filter(arr, size=9, output=dtype, mode='nearest')
# Median filter leaves a bunch of zeros in nodata areas
arr[nodata_locs] = nodata

Wyświetl plik

@ -20,6 +20,8 @@ def create_25dmesh(inPointCloud, outMesh, dsm_radius=0.07, dsm_resolution=0.05,
log.ODM_INFO('Created temporary directory: %s' % tmp_directory)
radius_steps = [dsm_radius]
for _ in range(2):
radius_steps.append(radius_steps[-1] * 2) # 2 is arbitrary
log.ODM_INFO('Creating DSM for 2.5D mesh')

Wyświetl plik

@ -13,7 +13,6 @@ from opendm import system
from opendm import context
from opendm import camera
from opendm import location
from opendm.utils import get_depthmap_resolution
from opendm.photo import find_largest_photo_dim, find_largest_photo
from opensfm.large import metadataset
from opensfm.large import tools
@ -89,8 +88,12 @@ class OSFMContext:
merged.add_camera(camera)
for point in rec.points.values():
new_point = merged.create_point(point.id, point.coordinates)
new_point.color = point.color
try:
new_point = merged.create_point(point.id, point.coordinates)
new_point.color = point.color
except RuntimeError as e:
log.ODM_WARNING("Cannot merge shot id %s (%s)" % (shot.id, str(e)))
continue
for shot in rec.shots.values():
merged.add_shot(shot)
@ -195,8 +198,6 @@ 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",

Wyświetl plik

@ -20,6 +20,20 @@ from opensfm.geo import ecef_from_lla
projections = ['perspective', 'fisheye', 'brown', 'dual', 'equirectangular', 'spherical']
def find_largest_photo_dims(photos):
max_mp = 0
max_dims = None
for p in photos:
if p.width is None or p.height is None:
continue
mp = p.width * p.height
if mp > max_mp:
max_mp = mp
max_dims = (p.width, p.height)
return max_dims
def find_largest_photo_dim(photos):
max_dim = 0
for p in photos:

Wyświetl plik

@ -46,6 +46,10 @@ def get_geojson_shots_from_opensfm(reconstruction_file, utm_srs=None, utm_offset
[0, 0, 0, 1]])
raster = None
pseudo = True
# Couldn't get a SRS?
if utm_srs is None:
return None
crstrans = transformer(CRS.from_proj4(utm_srs), CRS.from_epsg("4326"))

Wyświetl plik

@ -1,28 +1,38 @@
import os, shutil
from opendm import log
from opendm.photo import find_largest_photo_dim
from opendm.photo import find_largest_photo_dims
from osgeo import gdal
from opendm.loghelpers import double_quote
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.")
# Override pc-quality
return int(args.depthmap_resolution)
else:
max_dim = find_largest_photo_dim(photos)
max_dims = find_largest_photo_dims(photos)
min_dim = 320 # Never go lower than this
pc_quality_scale = {
'ultra': 0.5,
'high': 0.25,
'medium': 0.125,
'low': 0.0675,
'lowest': 0.03375
}
if max_dims is not None:
w, h = max_dims
max_dim = max(w, h)
if max_dim > 0:
return max(min_dim, int(max_dim * pc_quality_scale[args.pc_quality]))
megapixels = (w * h) / 1e6
multiplier = 1
if megapixels < 6:
multiplier = 2
elif megapixels > 42:
multiplier = 0.5
pc_quality_scale = {
'ultra': 0.5,
'high': 0.25,
'medium': 0.125,
'low': 0.0675,
'lowest': 0.03375
}
return max(min_dim, int(max_dim * pc_quality_scale[args.pc_quality] * multiplier))
else:
log.ODM_WARNING("Cannot compute max image dimensions, going with default depthmap_resolution of 640")
return 640 # Sensible default

Wyświetl plik

@ -46,8 +46,10 @@ class ODMOpenMVSStage(types.ODM_Stage):
if not io.dir_exists(depthmaps_dir):
os.mkdir(depthmaps_dir)
depthmap_resolution = get_depthmap_resolution(args, photos)
log.ODM_INFO("Depthmap resolution set to: %spx" % depthmap_resolution)
if outputs["undist_image_max_size"] <= depthmap_resolution:
resolution_level = 0
else: