kopia lustrzana https://github.com/OpenDroneMap/ODM
Merge pull request #1333 from magnus-eigenvision/update-cap-resolution
Update parameters of cap_resolution().pull/1337/head
commit
9a11f37560
|
@ -5,6 +5,7 @@ import math
|
|||
from repoze.lru import lru_cache
|
||||
from opendm import log
|
||||
|
||||
|
||||
def rounded_gsd(reconstruction_json, default_value=None, ndigits=0, ignore_gsd=False):
|
||||
"""
|
||||
:param reconstruction_json path to OpenSfM's reconstruction.json
|
||||
|
@ -61,12 +62,15 @@ def image_scale_factor(target_resolution, reconstruction_json, gsd_error_estimat
|
|||
return 1
|
||||
|
||||
|
||||
def cap_resolution(resolution, reconstruction_json, gsd_error_estimate = 0.1, ignore_gsd=False, ignore_resolution=False, has_gcp=False):
|
||||
def cap_resolution(resolution, reconstruction_json, gsd_error_estimate = 0.1, gsd_scaling = 1.0, ignore_gsd=False,
|
||||
ignore_resolution=False, has_gcp=False):
|
||||
"""
|
||||
:param resolution resolution in cm / pixel
|
||||
:param reconstruction_json path to OpenSfM's reconstruction.json
|
||||
:param gsd_error_estimate percentage of estimated error in the GSD calculation to set an upper bound on resolution.
|
||||
:param gsd_scaling scaling of estimated GSD.
|
||||
:param ignore_gsd when set to True, forces the function to just return resolution.
|
||||
:param ignore_resolution when set to True, forces the function to return a value based on GSD.
|
||||
:return The max value between resolution and the GSD computed from the reconstruction.
|
||||
If a GSD cannot be computed, or ignore_gsd is set to True, it just returns resolution. Units are in cm / pixel.
|
||||
"""
|
||||
|
@ -76,14 +80,16 @@ def cap_resolution(resolution, reconstruction_json, gsd_error_estimate = 0.1, ig
|
|||
gsd = opensfm_reconstruction_average_gsd(reconstruction_json, use_all_shots=has_gcp or ignore_resolution)
|
||||
|
||||
if gsd is not None:
|
||||
gsd = gsd * (1 - gsd_error_estimate)
|
||||
gsd = gsd * (1 - gsd_error_estimate) * gsd_scaling
|
||||
if gsd > resolution or ignore_resolution:
|
||||
log.ODM_WARNING('Maximum resolution set to GSD - {}% ({} cm / pixel, requested resolution was {} cm / pixel)'.format(gsd_error_estimate * 100, round(gsd, 2), round(resolution, 2)))
|
||||
log.ODM_WARNING('Maximum resolution set to {} * (GSD - {}%) '
|
||||
'({:.2f} cm / pixel, requested resolution was {:.2f} cm / pixel)'
|
||||
.format(gsd_scaling, gsd_error_estimate * 100, gsd, resolution))
|
||||
return gsd
|
||||
else:
|
||||
return resolution
|
||||
else:
|
||||
log.ODM_WARNING('Cannot calculate GSD, using requested resolution of {}'.format(round(resolution, 2)))
|
||||
log.ODM_WARNING('Cannot calculate GSD, using requested resolution of {:.2f}'.format(resolution))
|
||||
return resolution
|
||||
|
||||
|
||||
|
@ -134,6 +140,7 @@ def opensfm_reconstruction_average_gsd(reconstruction_json, use_all_shots=False)
|
|||
|
||||
return None
|
||||
|
||||
|
||||
def calculate_gsd(sensor_width, flight_height, focal_length, image_width):
|
||||
"""
|
||||
:param sensor_width in millimeters
|
||||
|
@ -154,6 +161,7 @@ def calculate_gsd(sensor_width, flight_height, focal_length, image_width):
|
|||
else:
|
||||
return None
|
||||
|
||||
|
||||
def calculate_gsd_from_focal_ratio(focal_ratio, flight_height, image_width):
|
||||
"""
|
||||
:param focal_ratio focal length (mm) / sensor_width (mm)
|
||||
|
|
|
@ -13,6 +13,7 @@ from opendm import pseudogeo
|
|||
from opendm.tiles.tiler import generate_dem_tiles
|
||||
from opendm.cogeo import convert_to_cogeo
|
||||
|
||||
|
||||
class ODMDEMStage(types.ODM_Stage):
|
||||
def process(self, args, outputs):
|
||||
tree = outputs['tree']
|
||||
|
@ -28,11 +29,15 @@ class ODMDEMStage(types.ODM_Stage):
|
|||
ignore_resolution = True
|
||||
pseudo_georeference = True
|
||||
|
||||
# It is probably not reasonable to have accurate DEMs a the same resolution as the source photos, so reduce it
|
||||
# by a factor!
|
||||
gsd_scaling = 2.0
|
||||
|
||||
resolution = gsd.cap_resolution(args.dem_resolution, tree.opensfm_reconstruction,
|
||||
gsd_error_estimate=-1,
|
||||
ignore_gsd=args.ignore_gsd,
|
||||
ignore_resolution=ignore_resolution,
|
||||
has_gcp=reconstruction.has_gcp())
|
||||
gsd_scaling=gsd_scaling,
|
||||
ignore_gsd=args.ignore_gsd,
|
||||
ignore_resolution=ignore_resolution,
|
||||
has_gcp=reconstruction.has_gcp())
|
||||
|
||||
log.ODM_INFO('Classify: ' + str(args.pc_classify))
|
||||
log.ODM_INFO('Create DSM: ' + str(args.dsm))
|
||||
|
|
|
@ -13,6 +13,7 @@ from opendm.utils import double_quote
|
|||
from opendm import pseudogeo
|
||||
from opendm.multispectral import get_primary_band_name
|
||||
|
||||
|
||||
class ODMOrthoPhotoStage(types.ODM_Stage):
|
||||
def process(self, args, outputs):
|
||||
tree = outputs['tree']
|
||||
|
@ -23,18 +24,11 @@ class ODMOrthoPhotoStage(types.ODM_Stage):
|
|||
system.mkdir_p(tree.odm_orthophoto)
|
||||
|
||||
if not io.file_exists(tree.odm_orthophoto_tif) or self.rerun():
|
||||
gsd_error_estimate = 0.1
|
||||
ignore_resolution = False
|
||||
if not reconstruction.is_georeferenced():
|
||||
# Match DEMs
|
||||
gsd_error_estimate = -3
|
||||
ignore_resolution = True
|
||||
|
||||
resolution = 1.0 / (gsd.cap_resolution(args.orthophoto_resolution, tree.opensfm_reconstruction,
|
||||
gsd_error_estimate=gsd_error_estimate,
|
||||
ignore_gsd=args.ignore_gsd,
|
||||
ignore_resolution=ignore_resolution,
|
||||
has_gcp=reconstruction.has_gcp()) / 100.0)
|
||||
ignore_gsd=args.ignore_gsd,
|
||||
ignore_resolution=not reconstruction.is_georeferenced(),
|
||||
has_gcp=reconstruction.has_gcp()) / 100.0)
|
||||
|
||||
# odm_orthophoto definitions
|
||||
kwargs = {
|
||||
|
|
Ładowanie…
Reference in New Issue