kopia lustrzana https://github.com/OpenDroneMap/ODM
Better support for RTK info
rodzic
ee6fb18fc9
commit
b6982e27ac
|
@ -707,6 +707,17 @@ def config(argv=None):
|
|||
help=('Use images\' GPS exif data for reconstruction, even if there are GCPs present.'
|
||||
'This flag is useful if you have high precision GPS measurements. '
|
||||
'If there are no GCPs, this flag does nothing. Default: %(default)s'))
|
||||
|
||||
parser.add_argument('--gps-accuracy',
|
||||
type=float,
|
||||
action=StoreValue,
|
||||
metavar='<positive float>',
|
||||
default=15,
|
||||
help='Set a value in meters for the GPS Dilution of Precision (DOP) '
|
||||
'information for all images. If your images are tagged '
|
||||
'with high precision GPS information (RTK), this value will be automatically '
|
||||
'set accordingly. You can use this option to manually set it in case the reconstruction '
|
||||
'fails. Lowering this option can sometimes help control bowling-effects over large areas. Default: %(default)s')
|
||||
|
||||
parser.add_argument('--optimize-disk-space',
|
||||
action=StoreTrue,
|
||||
|
|
|
@ -103,6 +103,35 @@ class OSFMContext:
|
|||
log.ODM_INFO("Multi-camera setup, using BOW matching")
|
||||
use_bow = True
|
||||
|
||||
# GPSDOP override if we have GPS accuracy information (such as RTK)
|
||||
override_gps_dop = 'gps_accuracy_is_set' in args
|
||||
for p in photos:
|
||||
if p.get_gps_dop() is not None:
|
||||
override_gps_dop = True
|
||||
break
|
||||
|
||||
if override_gps_dop:
|
||||
if 'gps_accuracy_is_set' in args:
|
||||
log.ODM_INFO("Forcing GPS DOP to %s for all images" % args.gps_accuracy)
|
||||
else:
|
||||
log.ODM_INFO("Looks like we have RTK accuracy info for some photos. Good! We'll use it.")
|
||||
|
||||
exif_overrides = {}
|
||||
for p in photos:
|
||||
dop = args.gps_accuracy if 'gps_accuracy_is_set' in args else p.get_gps_dop()
|
||||
if dop is not None and p.latitude is not None and p.longitude is not None:
|
||||
exif_overrides[p.filename] = {
|
||||
'gps': {
|
||||
'latitude': p.latitude,
|
||||
'longitude': p.longitude,
|
||||
'altitude': p.altitude if p.altitude is not None else 0,
|
||||
'dop': dop,
|
||||
}
|
||||
}
|
||||
|
||||
with open(os.path.join(self.opensfm_project_path, "exif_overrides.json"), 'w') as f:
|
||||
f.write(json.dumps(exif_overrides))
|
||||
|
||||
# create config file for OpenSfM
|
||||
config = [
|
||||
"use_exif_size: no",
|
||||
|
|
|
@ -60,6 +60,10 @@ class ODM_Photo:
|
|||
# self.center_wavelength = None
|
||||
# self.bandwidth = None
|
||||
|
||||
# RTK
|
||||
self.gps_xy_stddev = None # Dilution of Precision X/Y
|
||||
self.gps_z_stddev = None # Dilution of Precision Z
|
||||
|
||||
# parse values from metadata
|
||||
self.parse_exif_values(path_file)
|
||||
|
||||
|
@ -183,6 +187,22 @@ class ODM_Photo:
|
|||
'Camera:Irradiance',
|
||||
], float)
|
||||
|
||||
# Phantom 4 RTK
|
||||
if '@drone-dji:RtkStdLon' in tags:
|
||||
y = float(self.get_xmp_tag(tags, '@drone-dji:RtkStdLon'))
|
||||
x = float(self.get_xmp_tag(tags, '@drone-dji:RtkStdLat'))
|
||||
self.gps_xy_stddev = max(x, y)
|
||||
|
||||
if '@drone-dji:RtkStdHgt' in tags:
|
||||
self.gps_z_stddev = float(self.get_xmp_tag(tags, '@drone-dji:RtkStdHgt'))
|
||||
else:
|
||||
self.set_attr_from_xmp_tag('gps_xy_stddev', tags, [
|
||||
'@Camera:GPSXYAccuracy'
|
||||
], float)
|
||||
self.set_attr_from_xmp_tag('gps_z_stddev', tags, [
|
||||
'@Camera:GPSZAccuracy'
|
||||
], float)
|
||||
|
||||
if 'DLS:Yaw' in tags:
|
||||
self.set_attr_from_xmp_tag('dls_yaw', tags, ['DLS:Yaw'], float)
|
||||
self.set_attr_from_xmp_tag('dls_pitch', tags, ['DLS:Pitch'], float)
|
||||
|
@ -239,6 +259,7 @@ class ODM_Photo:
|
|||
|
||||
if xmp_start < xmp_end:
|
||||
xmp_str = img_str[xmp_start:xmp_end + 12]
|
||||
xmp_str = xmp_str.replace("rdf:about=''xmlns", "rdf:about='' xmlns")
|
||||
xdict = x2d.parse(xmp_str)
|
||||
xdict = xdict.get('x:xmpmeta', {})
|
||||
xdict = xdict.get('rdf:RDF', {})
|
||||
|
@ -361,4 +382,15 @@ class ODM_Photo:
|
|||
if self.bits_per_sample:
|
||||
return float(2 ** self.bits_per_sample)
|
||||
|
||||
return None
|
||||
|
||||
def get_gps_dop(self):
|
||||
val = -9999
|
||||
if self.gps_xy_stddev is not None:
|
||||
val = self.gps_xy_stddev
|
||||
if self.gps_z_stddev is not None:
|
||||
val = max(val, self.gps_z_stddev)
|
||||
if val > 0:
|
||||
return val
|
||||
|
||||
return None
|
Ładowanie…
Reference in New Issue