kopia lustrzana https://github.com/OpenDroneMap/ODM
Dynamic rolling shutter readout db
rodzic
51abdd1373
commit
3fa065e0af
|
@ -146,6 +146,10 @@ class ODM_Photo:
|
||||||
self.speed_y = None
|
self.speed_y = None
|
||||||
self.speed_z = None
|
self.speed_z = None
|
||||||
|
|
||||||
|
# Original image width/height at capture time (before possible resizes)
|
||||||
|
self.exif_width = None
|
||||||
|
self.exif_height = None
|
||||||
|
|
||||||
# self.center_wavelength = None
|
# self.center_wavelength = None
|
||||||
# self.bandwidth = None
|
# self.bandwidth = None
|
||||||
|
|
||||||
|
@ -281,6 +285,11 @@ class ODM_Photo:
|
||||||
self.speed_y = self.float_value(tags['MakerNote SpeedY'])
|
self.speed_y = self.float_value(tags['MakerNote SpeedY'])
|
||||||
self.speed_z = self.float_value(tags['MakerNote SpeedZ'])
|
self.speed_z = self.float_value(tags['MakerNote SpeedZ'])
|
||||||
|
|
||||||
|
if 'EXIF ExifImageWidth' in tags and \
|
||||||
|
'EXIF ExifImageLength' in tags:
|
||||||
|
self.exif_width = self.int_value(tags['EXIF ExifImageWidth'])
|
||||||
|
self.exif_height = self.int_value(tags['EXIF ExifImageLength'])
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.ODM_WARNING("Cannot read extended EXIF tags for %s: %s" % (self.filename, str(e)))
|
log.ODM_WARNING("Cannot read extended EXIF tags for %s: %s" % (self.filename, str(e)))
|
||||||
|
|
||||||
|
@ -779,7 +788,7 @@ class ODM_Photo:
|
||||||
d['speed'] = [self.speed_y, self.speed_x, self.speed_z]
|
d['speed'] = [self.speed_y, self.speed_x, self.speed_z]
|
||||||
|
|
||||||
if rolling_shutter:
|
if rolling_shutter:
|
||||||
d['rolling_shutter'] = get_rolling_shutter_readout(self.camera_make, self.camera_model, rolling_shutter_readout)
|
d['rolling_shutter'] = get_rolling_shutter_readout(self, rolling_shutter_readout)
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
@ -854,3 +863,15 @@ class ODM_Photo:
|
||||||
self.omega = math.degrees(math.atan2(-ceb[1][2], ceb[2][2]))
|
self.omega = math.degrees(math.atan2(-ceb[1][2], ceb[2][2]))
|
||||||
self.phi = math.degrees(math.asin(ceb[0][2]))
|
self.phi = math.degrees(math.asin(ceb[0][2]))
|
||||||
self.kappa = math.degrees(math.atan2(-ceb[0][1], ceb[0][0]))
|
self.kappa = math.degrees(math.atan2(-ceb[0][1], ceb[0][0]))
|
||||||
|
|
||||||
|
def get_capture_megapixels(self):
|
||||||
|
if self.exif_width is not None and self.exif_height is not None:
|
||||||
|
# Accurate so long as resizing / postprocess software
|
||||||
|
# did not fiddle with the tags
|
||||||
|
return self.exif_width * self.exif_height / 1e6
|
||||||
|
elif self.width is not None and self.height is not None:
|
||||||
|
# Fallback, might not be accurate since the image
|
||||||
|
# could have been resized
|
||||||
|
return self.width * self.height / 1e6
|
||||||
|
else:
|
||||||
|
return 0.0
|
||||||
|
|
|
@ -15,6 +15,8 @@ RS_DATABASE = {
|
||||||
'dji fc3170': 27, # DJI Mavic Air 2
|
'dji fc3170': 27, # DJI Mavic Air 2
|
||||||
'dji fc3411': 32, # DJI Mavic Air 2S
|
'dji fc3411': 32, # DJI Mavic Air 2S
|
||||||
|
|
||||||
|
'dji fc3582': lambda p: 26 if p.get_capture_megapixels() < 48 else 60, # DJI Mini 3 pro (at 48MP readout is 60ms, at 12MP it's 26ms)
|
||||||
|
|
||||||
'dji fc350': 30, # Inspire 1
|
'dji fc350': 30, # Inspire 1
|
||||||
|
|
||||||
'gopro hero4 black': 30, # GoPro Hero 4 Black
|
'gopro hero4 black': 30, # GoPro Hero 4 Black
|
||||||
|
@ -22,6 +24,7 @@ RS_DATABASE = {
|
||||||
|
|
||||||
'teracube teracube one': 32 # TeraCube TeraCube_One TR1907Q Mobile Phone
|
'teracube teracube one': 32 # TeraCube TeraCube_One TR1907Q Mobile Phone
|
||||||
|
|
||||||
|
|
||||||
# Help us add more!
|
# Help us add more!
|
||||||
# See: https://github.com/OpenDroneMap/RSCalibration for instructions
|
# See: https://github.com/OpenDroneMap/RSCalibration for instructions
|
||||||
}
|
}
|
||||||
|
@ -33,19 +36,32 @@ def make_model_key(make, model):
|
||||||
warn_db_missing = {}
|
warn_db_missing = {}
|
||||||
info_db_found = {}
|
info_db_found = {}
|
||||||
|
|
||||||
def get_rolling_shutter_readout(make, model, override_value=0):
|
def get_rolling_shutter_readout(photo, override_value=0):
|
||||||
global warn_db_missing
|
global warn_db_missing
|
||||||
global info_db_found
|
global info_db_found
|
||||||
|
|
||||||
|
make, model = photo.camera_make, photo.camera_model
|
||||||
|
|
||||||
if override_value > 0:
|
if override_value > 0:
|
||||||
return override_value
|
return override_value
|
||||||
|
|
||||||
key = make_model_key(make, model)
|
key = make_model_key(make, model)
|
||||||
if key in RS_DATABASE:
|
if key in RS_DATABASE:
|
||||||
|
rsd = RS_DATABASE[key]
|
||||||
|
val = 0.0
|
||||||
|
|
||||||
|
if isinstance(rsd, int) or isinstance(rsd, float):
|
||||||
|
val = float(rsd)
|
||||||
|
elif callable(rsd):
|
||||||
|
val = float(rsd(photo))
|
||||||
|
else:
|
||||||
|
log.ODM_WARNING("Invalid rolling shutter calibration entry, returning default of %sms" % DEFAULT_RS_READOUT)
|
||||||
|
|
||||||
if not key in info_db_found:
|
if not key in info_db_found:
|
||||||
log.ODM_INFO("Rolling shutter profile for \"%s %s\" selected, using %sms as --rolling-shutter-readout." % (make, model, RS_DATABASE[key]))
|
log.ODM_INFO("Rolling shutter profile for \"%s %s\" selected, using %sms as --rolling-shutter-readout." % (make, model, val))
|
||||||
info_db_found[key] = True
|
info_db_found[key] = True
|
||||||
return float(RS_DATABASE[key])
|
|
||||||
|
return val
|
||||||
else:
|
else:
|
||||||
# Warn once
|
# Warn once
|
||||||
if not key in warn_db_missing:
|
if not key in warn_db_missing:
|
||||||
|
|
Ładowanie…
Reference in New Issue