kopia lustrzana https://github.com/OpenDroneMap/ODM
Better support for AV Quantix drones
rodzic
de4bd062ec
commit
89ea21284a
|
@ -421,6 +421,18 @@ def compute_homography(image_filename, align_image_filename):
|
||||||
def find_ecc_homography(image_gray, align_image_gray, number_of_iterations=1000, termination_eps=1e-8, start_eps=1e-4):
|
def find_ecc_homography(image_gray, align_image_gray, number_of_iterations=1000, termination_eps=1e-8, start_eps=1e-4):
|
||||||
pyramid_levels = 0
|
pyramid_levels = 0
|
||||||
h,w = image_gray.shape
|
h,w = image_gray.shape
|
||||||
|
max_dim = max(h, w)
|
||||||
|
|
||||||
|
max_size = 1280
|
||||||
|
|
||||||
|
if max_dim > max_size:
|
||||||
|
if max_dim == w:
|
||||||
|
f = max_size / w
|
||||||
|
else:
|
||||||
|
f = max_size / h
|
||||||
|
image_gray = cv2.resize(image_gray, None, fx=f, fy=f, interpolation=cv2.INTER_AREA)
|
||||||
|
h,w = image_gray.shape
|
||||||
|
|
||||||
min_dim = min(h, w)
|
min_dim = min(h, w)
|
||||||
|
|
||||||
while min_dim > 300:
|
while min_dim > 300:
|
||||||
|
@ -434,10 +446,10 @@ def find_ecc_homography(image_gray, align_image_gray, number_of_iterations=1000,
|
||||||
align_image_gray = to_8bit(align_image_gray)
|
align_image_gray = to_8bit(align_image_gray)
|
||||||
image_gray = to_8bit(image_gray)
|
image_gray = to_8bit(image_gray)
|
||||||
|
|
||||||
fx = align_image_gray.shape[1]/image_gray.shape[1]
|
fx = image_gray.shape[1]/align_image_gray.shape[1]
|
||||||
fy = align_image_gray.shape[0]/image_gray.shape[0]
|
fy = image_gray.shape[0]/align_image_gray.shape[0]
|
||||||
|
|
||||||
image_gray = cv2.resize(image_gray, None,
|
align_image_gray = cv2.resize(align_image_gray, None,
|
||||||
fx=fx,
|
fx=fx,
|
||||||
fy=fy,
|
fy=fy,
|
||||||
interpolation=(cv2.INTER_AREA if (fx < 1.0 and fy < 1.0) else cv2.INTER_LANCZOS4))
|
interpolation=(cv2.INTER_AREA if (fx < 1.0 and fy < 1.0) else cv2.INTER_LANCZOS4))
|
||||||
|
|
|
@ -459,6 +459,21 @@ class ODM_Photo:
|
||||||
# self.set_attr_from_xmp_tag('bandwidth', xtags, [
|
# self.set_attr_from_xmp_tag('bandwidth', xtags, [
|
||||||
# 'Camera:WavelengthFWHM'
|
# 'Camera:WavelengthFWHM'
|
||||||
# ], float)
|
# ], float)
|
||||||
|
|
||||||
|
# Special case band handling for AeroVironment Quantix images
|
||||||
|
# for some reason, they don't store band information in EXIFs
|
||||||
|
if self.camera_make.lower() == 'aerovironment' and \
|
||||||
|
self.camera_model.lower() == 'quantix':
|
||||||
|
matches = re.match("IMG_(\d+)_(\w+)\.\w+", self.filename, re.IGNORECASE)
|
||||||
|
if matches:
|
||||||
|
band_aliases = {
|
||||||
|
'GRN': 'Green',
|
||||||
|
'NIR': 'Nir',
|
||||||
|
'RED': 'Red',
|
||||||
|
'RGB': 'RedGreenBlue',
|
||||||
|
}
|
||||||
|
self.capture_uuid = matches.group(1)
|
||||||
|
self.band_name = band_aliases.get(matches.group(2), matches.group(2))
|
||||||
|
|
||||||
# Sanitize band name since we use it in folder paths
|
# Sanitize band name since we use it in folder paths
|
||||||
self.band_name = re.sub('[^A-Za-z0-9]+', '', self.band_name)
|
self.band_name = re.sub('[^A-Za-z0-9]+', '', self.band_name)
|
||||||
|
|
|
@ -76,17 +76,27 @@ class ODM_Reconstruction(object):
|
||||||
bands = {}
|
bands = {}
|
||||||
for b in self.multi_camera:
|
for b in self.multi_camera:
|
||||||
bands[b['name'].lower()] = b['name']
|
bands[b['name'].lower()] = b['name']
|
||||||
|
|
||||||
|
bands_to_remove = []
|
||||||
|
|
||||||
if ('rgb' in bands or 'redgreenblue' in bands) and \
|
if 'rgb' in bands or 'redgreenblue' in bands:
|
||||||
('red' in bands and 'green' in bands and 'blue' in bands):
|
if 'red' in bands and 'green' in bands and 'blue' in bands:
|
||||||
band_to_remove = bands['rgb'] if 'rgb' in bands else bands['redgreenblue']
|
bands_to_remove.append(bands['rgb'] if 'rgb' in bands else bands['redgreenblue'])
|
||||||
|
else:
|
||||||
|
for b in ['red', 'green', 'blue']:
|
||||||
|
if b in bands:
|
||||||
|
bands_to_remove.append(bands[b])
|
||||||
|
|
||||||
self.multi_camera = [b for b in self.multi_camera if b['name'] != band_to_remove]
|
if len(bands_to_remove) > 0:
|
||||||
photos_before = len(self.photos)
|
log.ODM_WARNING("Redundant bands detected, probably because RGB images are mixed with single band images. We will trim some bands as needed")
|
||||||
self.photos = [p for p in self.photos if p.band_name != band_to_remove]
|
|
||||||
photos_after = len(self.photos)
|
|
||||||
|
|
||||||
log.ODM_WARNING("RGB images detected alongside individual Red/Green/Blue images, we will use individual bands (skipping %s images)" % (photos_before - photos_after))
|
for band_to_remove in bands_to_remove:
|
||||||
|
self.multi_camera = [b for b in self.multi_camera if b['name'] != band_to_remove]
|
||||||
|
photos_before = len(self.photos)
|
||||||
|
self.photos = [p for p in self.photos if p.band_name != band_to_remove]
|
||||||
|
photos_after = len(self.photos)
|
||||||
|
|
||||||
|
log.ODM_WARNING("Skipping %s band (%s images)" % (band_to_remove, photos_before - photos_after))
|
||||||
|
|
||||||
def is_georeferenced(self):
|
def is_georeferenced(self):
|
||||||
return self.georef is not None
|
return self.georef is not None
|
||||||
|
|
|
@ -104,9 +104,9 @@ class ODMOpenSfMStage(types.ODM_Stage):
|
||||||
image = func(shot_id, image)
|
image = func(shot_id, image)
|
||||||
return image
|
return image
|
||||||
|
|
||||||
def resize_thermal_images(shot_id, image):
|
def resize_secondary_images(shot_id, image):
|
||||||
photo = reconstruction.get_photo(shot_id)
|
photo = reconstruction.get_photo(shot_id)
|
||||||
if photo.is_thermal():
|
if photo.band_name != primary_band_name:
|
||||||
return thermal.resize_to_match(image, largest_photo)
|
return thermal.resize_to_match(image, largest_photo)
|
||||||
else:
|
else:
|
||||||
return image
|
return image
|
||||||
|
@ -138,8 +138,8 @@ class ODMOpenSfMStage(types.ODM_Stage):
|
||||||
return image
|
return image
|
||||||
|
|
||||||
if reconstruction.multi_camera:
|
if reconstruction.multi_camera:
|
||||||
largest_photo = find_largest_photo(photos)
|
largest_photo = find_largest_photo([p for p in photos if p.band_name == primary_band_name])
|
||||||
undistort_pipeline.append(resize_thermal_images)
|
undistort_pipeline.append(resize_secondary_images)
|
||||||
|
|
||||||
if args.radiometric_calibration != "none":
|
if args.radiometric_calibration != "none":
|
||||||
undistort_pipeline.append(radiometric_calibrate)
|
undistort_pipeline.append(radiometric_calibrate)
|
||||||
|
|
Ładowanie…
Reference in New Issue