Dynamic rolling shutter readout db

pull/1511/head
Piero Toffanin 2022-07-25 12:33:11 -04:00
rodzic 51abdd1373
commit 3fa065e0af
2 zmienionych plików z 41 dodań i 4 usunięć

Wyświetl plik

@ -146,6 +146,10 @@ class ODM_Photo:
self.speed_y = 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.bandwidth = None
@ -281,6 +285,11 @@ class ODM_Photo:
self.speed_y = self.float_value(tags['MakerNote SpeedY'])
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:
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]
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
@ -854,3 +863,15 @@ class ODM_Photo:
self.omega = math.degrees(math.atan2(-ceb[1][2], ceb[2][2]))
self.phi = math.degrees(math.asin(ceb[0][2]))
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

Wyświetl plik

@ -15,6 +15,8 @@ RS_DATABASE = {
'dji fc3170': 27, # DJI Mavic Air 2
'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
'gopro hero4 black': 30, # GoPro Hero 4 Black
@ -22,6 +24,7 @@ RS_DATABASE = {
'teracube teracube one': 32 # TeraCube TeraCube_One TR1907Q Mobile Phone
# Help us add more!
# See: https://github.com/OpenDroneMap/RSCalibration for instructions
}
@ -33,19 +36,32 @@ def make_model_key(make, model):
warn_db_missing = {}
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 info_db_found
make, model = photo.camera_make, photo.camera_model
if override_value > 0:
return override_value
key = make_model_key(make, model)
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:
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
return float(RS_DATABASE[key])
return val
else:
# Warn once
if not key in warn_db_missing: