kopia lustrzana https://github.com/OpenDroneMap/ODM
rodzic
c1c97c8701
commit
d09b3256bc
|
@ -8,7 +8,7 @@
|
||||||
project_path: '/' #DO NOT CHANGE THIS OR DOCKER WILL NOT WORK. It should be '/'
|
project_path: '/' #DO NOT CHANGE THIS OR DOCKER WILL NOT WORK. It should be '/'
|
||||||
|
|
||||||
# The rest of the settings will default to the values set unless you uncomment and change them
|
# The rest of the settings will default to the values set unless you uncomment and change them
|
||||||
#resize_to: 2400
|
#resize_to: 2048
|
||||||
#start_with: 'resize'
|
#start_with: 'resize'
|
||||||
#end_with: 'odm_orthophoto'
|
#end_with: 'odm_orthophoto'
|
||||||
#rerun_all: False
|
#rerun_all: False
|
||||||
|
|
|
@ -47,16 +47,12 @@ def config():
|
||||||
type=alphanumeric_string,
|
type=alphanumeric_string,
|
||||||
help='Name of Project (i.e subdirectory of projects folder)')
|
help='Name of Project (i.e subdirectory of projects folder)')
|
||||||
|
|
||||||
parser.add_argument('--resize-to', # currently doesn't support 'orig'
|
parser.add_argument('--resize-to',
|
||||||
metavar='<integer>',
|
metavar='<integer>',
|
||||||
default=2400,
|
default=2048,
|
||||||
type=int,
|
type=int,
|
||||||
help='resizes images by the largest side')
|
help='resizes images by the largest side for opensfm. '
|
||||||
|
'Set to -1 to disable. Default: %(default)s')
|
||||||
parser.add_argument('--skip-resize',
|
|
||||||
action='store_true',
|
|
||||||
default=False,
|
|
||||||
help='Skips resizing of images')
|
|
||||||
|
|
||||||
parser.add_argument('--start-with', '-s',
|
parser.add_argument('--start-with', '-s',
|
||||||
metavar='<string>',
|
metavar='<string>',
|
||||||
|
|
|
@ -4,19 +4,17 @@ import system
|
||||||
import dataset
|
import dataset
|
||||||
import types
|
import types
|
||||||
|
|
||||||
from scripts.resize import resize
|
|
||||||
from scripts.opensfm import opensfm
|
from scripts.opensfm import opensfm
|
||||||
|
|
||||||
# Define pipeline tasks
|
# Define pipeline tasks
|
||||||
tasks_dict = {'1': 'resize',
|
tasks_dict = {'1': 'opensfm',
|
||||||
'2': 'opensfm',
|
'2': 'cmvs',
|
||||||
'3': 'cmvs',
|
'3': 'pmvs',
|
||||||
'4': 'pmvs',
|
'4': 'odm_meshing',
|
||||||
'5': 'odm_meshing',
|
'5': 'mvs_texturing',
|
||||||
'6': 'mvs_texturing',
|
'6': 'odm_georeferencing',
|
||||||
'7': 'odm_georeferencing',
|
'7': 'odm_orthophoto',
|
||||||
'8': 'odm_orthophoto',
|
'8': 'zip_results'}
|
||||||
'9': 'zip_results'}
|
|
||||||
|
|
||||||
|
|
||||||
class ODMTaskManager(object):
|
class ODMTaskManager(object):
|
||||||
|
|
|
@ -83,6 +83,8 @@ class ODM_Photo:
|
||||||
self.altitude *= -1.
|
self.altitude *= -1.
|
||||||
except (pyexiv2.ExifValueError, ValueError) as e:
|
except (pyexiv2.ExifValueError, ValueError) as e:
|
||||||
pass
|
pass
|
||||||
|
except KeyError as e:
|
||||||
|
log.ODM_DEBUG('Tag not set')
|
||||||
except NotImplementedError as e:
|
except NotImplementedError as e:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -408,7 +410,6 @@ class ODM_Tree(object):
|
||||||
# order to keep track all files al directories during the
|
# order to keep track all files al directories during the
|
||||||
# whole reconstruction process.
|
# whole reconstruction process.
|
||||||
self.dataset_raw = io.join_paths(self.root_path, 'images')
|
self.dataset_raw = io.join_paths(self.root_path, 'images')
|
||||||
self.dataset_resize = io.join_paths(self.root_path, 'images_resize')
|
|
||||||
self.opensfm = io.join_paths(self.root_path, 'opensfm')
|
self.opensfm = io.join_paths(self.root_path, 'opensfm')
|
||||||
self.pmvs = io.join_paths(self.root_path, 'pmvs')
|
self.pmvs = io.join_paths(self.root_path, 'pmvs')
|
||||||
self.odm_meshing = io.join_paths(self.root_path, 'odm_meshing')
|
self.odm_meshing = io.join_paths(self.root_path, 'odm_meshing')
|
||||||
|
|
|
@ -49,18 +49,11 @@ class ODMLoadDatasetCell(ecto.Cell):
|
||||||
# get images directory
|
# get images directory
|
||||||
input_dir = tree.input_images
|
input_dir = tree.input_images
|
||||||
images_dir = tree.dataset_raw
|
images_dir = tree.dataset_raw
|
||||||
resize_dir = tree.dataset_resize
|
|
||||||
|
|
||||||
# Check first if a project already exists. This is a mediocre way to check, by checking the resize dir
|
if not io.dir_exists(images_dir):
|
||||||
if io.dir_exists(resize_dir):
|
log.ODM_INFO("Project directory %s doesn't exist. Creating it now. " % images_dir)
|
||||||
log.ODM_DEBUG("resize dir: %s" % resize_dir)
|
system.mkdir_p(images_dir)
|
||||||
images_dir = resize_dir
|
copied = [copyfile(io.join_paths(input_dir, f), io.join_paths(images_dir, f)) for f in get_images(input_dir)]
|
||||||
# if first time running, create project directory and copy images over to project/images
|
|
||||||
else:
|
|
||||||
if not io.dir_exists(images_dir):
|
|
||||||
log.ODM_INFO("Project directory %s doesn't exist. Creating it now. " % images_dir)
|
|
||||||
system.mkdir_p(images_dir)
|
|
||||||
copied = [copyfile(io.join_paths(input_dir, f), io.join_paths(images_dir, f)) for f in get_images(input_dir)]
|
|
||||||
|
|
||||||
log.ODM_DEBUG('Loading dataset from: %s' % images_dir)
|
log.ODM_DEBUG('Loading dataset from: %s' % images_dir)
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ from opendm import io
|
||||||
from opendm import system
|
from opendm import system
|
||||||
|
|
||||||
from dataset import ODMLoadDatasetCell
|
from dataset import ODMLoadDatasetCell
|
||||||
from resize import ODMResizeCell
|
|
||||||
from opensfm import ODMOpenSfMCell
|
from opensfm import ODMOpenSfMCell
|
||||||
from odm_slam import ODMSlamCell
|
from odm_slam import ODMSlamCell
|
||||||
from pmvs import ODMPmvsCell
|
from pmvs import ODMPmvsCell
|
||||||
|
@ -39,8 +38,6 @@ class ODMApp(ecto.BlackBox):
|
||||||
cells = {'args': ecto.Constant(value=p.args),
|
cells = {'args': ecto.Constant(value=p.args),
|
||||||
'dataset': ODMLoadDatasetCell(force_focal=p.args.force_focal,
|
'dataset': ODMLoadDatasetCell(force_focal=p.args.force_focal,
|
||||||
force_ccd=p.args.force_ccd),
|
force_ccd=p.args.force_ccd),
|
||||||
'resize': ODMResizeCell(resize_to=p.args.resize_to,
|
|
||||||
skip_resize=p.args.skip_resize),
|
|
||||||
'opensfm': ODMOpenSfMCell(use_exif_size=False,
|
'opensfm': ODMOpenSfMCell(use_exif_size=False,
|
||||||
feature_process_size=p.args.resize_to,
|
feature_process_size=p.args.resize_to,
|
||||||
feature_min_frames=p.args.min_num_features,
|
feature_min_frames=p.args.min_num_features,
|
||||||
|
@ -115,15 +112,10 @@ class ODMApp(ecto.BlackBox):
|
||||||
# load the dataset
|
# load the dataset
|
||||||
connections = [self.tree[:] >> self.dataset['tree']]
|
connections = [self.tree[:] >> self.dataset['tree']]
|
||||||
|
|
||||||
# run resize cell
|
|
||||||
connections += [self.tree[:] >> self.resize['tree'],
|
|
||||||
self.args[:] >> self.resize['args'],
|
|
||||||
self.dataset['photos'] >> self.resize['photos']]
|
|
||||||
|
|
||||||
# run opensfm with images from load dataset
|
# run opensfm with images from load dataset
|
||||||
connections += [self.tree[:] >> self.opensfm['tree'],
|
connections += [self.tree[:] >> self.opensfm['tree'],
|
||||||
self.args[:] >> self.opensfm['args'],
|
self.args[:] >> self.opensfm['args'],
|
||||||
self.resize['photos'] >> self.opensfm['photos']]
|
self.dataset['photos'] >> self.opensfm['photos']]
|
||||||
|
|
||||||
if not p.args.use_pmvs:
|
if not p.args.use_pmvs:
|
||||||
# create odm mesh from opensfm point cloud
|
# create odm mesh from opensfm point cloud
|
||||||
|
@ -154,7 +146,7 @@ class ODMApp(ecto.BlackBox):
|
||||||
# create odm georeference
|
# create odm georeference
|
||||||
connections += [self.tree[:] >> self.georeferencing['tree'],
|
connections += [self.tree[:] >> self.georeferencing['tree'],
|
||||||
self.args[:] >> self.georeferencing['args'],
|
self.args[:] >> self.georeferencing['args'],
|
||||||
self.resize['photos'] >> self.georeferencing['photos'],
|
self.dataset['photos'] >> self.georeferencing['photos'],
|
||||||
self.texturing['reconstruction'] >> self.georeferencing['reconstruction']]
|
self.texturing['reconstruction'] >> self.georeferencing['reconstruction']]
|
||||||
|
|
||||||
# create odm orthophoto
|
# create odm orthophoto
|
||||||
|
|
|
@ -67,7 +67,7 @@ class ODMGeoreferencingCell(ecto.Cell):
|
||||||
# odm_georeference definitions
|
# odm_georeference definitions
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'bin': context.odm_modules_path,
|
'bin': context.odm_modules_path,
|
||||||
'imgs': tree.dataset_resize,
|
'imgs': tree.dataset_raw,
|
||||||
'imgs_list': tree.opensfm_bundle_list,
|
'imgs_list': tree.opensfm_bundle_list,
|
||||||
'coords': tree.odm_georeferencing_coords,
|
'coords': tree.odm_georeferencing_coords,
|
||||||
'log': tree.odm_georeferencing_utm_log,
|
'log': tree.odm_georeferencing_utm_log,
|
||||||
|
@ -117,7 +117,7 @@ class ODMGeoreferencingCell(ecto.Cell):
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'bin': context.odm_modules_path,
|
'bin': context.odm_modules_path,
|
||||||
'bundle': tree.opensfm_bundle,
|
'bundle': tree.opensfm_bundle,
|
||||||
'imgs': tree.dataset_resize,
|
'imgs': tree.dataset_raw,
|
||||||
'imgs_list': tree.opensfm_bundle_list,
|
'imgs_list': tree.opensfm_bundle_list,
|
||||||
'model': r['model'],
|
'model': r['model'],
|
||||||
'log': odm_georeferencing_log,
|
'log': odm_georeferencing_log,
|
||||||
|
|
|
@ -1,158 +0,0 @@
|
||||||
import ecto
|
|
||||||
import cv2
|
|
||||||
import pyexiv2
|
|
||||||
|
|
||||||
from functools import partial
|
|
||||||
from multiprocessing import Pool
|
|
||||||
from opendm import log
|
|
||||||
from opendm import system
|
|
||||||
from opendm import io
|
|
||||||
from opendm import types
|
|
||||||
|
|
||||||
|
|
||||||
def resize(src_dir, target_dir, resize_to, rerun_cell, photo):
|
|
||||||
# define image paths
|
|
||||||
path_file = photo.path_file
|
|
||||||
new_path_file = io.join_paths(target_dir, photo.filename)
|
|
||||||
# set raw image path in case we want to rerun cell
|
|
||||||
if io.file_exists(new_path_file) and rerun_cell:
|
|
||||||
path_file = io.join_paths(src_dir, photo.filename)
|
|
||||||
|
|
||||||
if not io.file_exists(new_path_file) or rerun_cell:
|
|
||||||
# open and resize image with opencv
|
|
||||||
img = cv2.imread(path_file)
|
|
||||||
# compute new size
|
|
||||||
max_side = max(img.shape[0], img.shape[1])
|
|
||||||
if max_side <= resize_to:
|
|
||||||
log.ODM_WARNING('Resize parameter is greater than or equal to the largest side of the image')
|
|
||||||
ratio = float(resize_to) / float(max_side)
|
|
||||||
img_r = cv2.resize(img, None, fx=ratio, fy=ratio)
|
|
||||||
# write image with opencv
|
|
||||||
cv2.imwrite(new_path_file, img_r)
|
|
||||||
# read metadata with pyexiv2
|
|
||||||
old_meta = pyexiv2.ImageMetadata(path_file)
|
|
||||||
new_meta = pyexiv2.ImageMetadata(new_path_file)
|
|
||||||
old_meta.read()
|
|
||||||
new_meta.read()
|
|
||||||
# copy metadata
|
|
||||||
old_meta.copy(new_meta)
|
|
||||||
# update metadata size
|
|
||||||
new_meta['Exif.Photo.PixelXDimension'] = img_r.shape[0]
|
|
||||||
new_meta['Exif.Photo.PixelYDimension'] = img_r.shape[1]
|
|
||||||
new_meta.write()
|
|
||||||
# update photos array with new values
|
|
||||||
photo.path_file = new_path_file
|
|
||||||
photo.width = img_r.shape[0]
|
|
||||||
photo.height = img_r.shape[1]
|
|
||||||
photo.update_focal()
|
|
||||||
|
|
||||||
# log message
|
|
||||||
log.ODM_DEBUG('Resized %s | dimensions: %s' %
|
|
||||||
(photo.filename, img_r.shape))
|
|
||||||
else:
|
|
||||||
# log message
|
|
||||||
log.ODM_WARNING('Already resized %s | dimensions: %s x %s' %
|
|
||||||
(photo.filename, photo.width, photo.height))
|
|
||||||
|
|
||||||
return photo
|
|
||||||
|
|
||||||
|
|
||||||
def no_resize(src_dir,target_dir,rerun_cell,photo):
|
|
||||||
# define image paths
|
|
||||||
path_file = photo.path_file
|
|
||||||
new_path_file = io.join_paths(target_dir, photo.filename)
|
|
||||||
# set raw image path in case we want to rerun cell
|
|
||||||
if io.file_exists(new_path_file) and rerun_cell:
|
|
||||||
path_file = io.join_paths(src_dir, photo.filename)
|
|
||||||
|
|
||||||
if not io.file_exists(new_path_file) or rerun_cell:
|
|
||||||
img = cv2.imread(path_file)
|
|
||||||
io.copy(path_file, new_path_file)
|
|
||||||
photo.path_file = new_path_file
|
|
||||||
photo.width = img.shape[0]
|
|
||||||
photo.height = img.shape[1]
|
|
||||||
photo.update_focal()
|
|
||||||
|
|
||||||
# log message
|
|
||||||
log.ODM_DEBUG('Copied %s | dimensions: %s' %
|
|
||||||
(photo.filename, img.shape))
|
|
||||||
else:
|
|
||||||
# log message
|
|
||||||
log.ODM_WARNING('Already copied %s | dimensions: %s x %s' %
|
|
||||||
(photo.filename, photo.width, photo.height))
|
|
||||||
|
|
||||||
return photo
|
|
||||||
|
|
||||||
|
|
||||||
class ODMResizeCell(ecto.Cell):
|
|
||||||
def declare_params(self, params):
|
|
||||||
params.declare("resize_to", "resizes images by the largest side", 2400)
|
|
||||||
params.declare("skip_resize", "tells if resize should be skipped", False)
|
|
||||||
|
|
||||||
def declare_io(self, params, inputs, outputs):
|
|
||||||
inputs.declare("tree", "Struct with paths", [])
|
|
||||||
inputs.declare("args", "The application arguments.", [])
|
|
||||||
inputs.declare("photos", "Clusters inputs. list of ODMPhoto's", [])
|
|
||||||
outputs.declare("photos", "Clusters output. list of ODMPhoto's", [])
|
|
||||||
|
|
||||||
def process(self, inputs, outputs):
|
|
||||||
|
|
||||||
# Benchmarking
|
|
||||||
start_time = system.now_raw()
|
|
||||||
|
|
||||||
log.ODM_INFO('Running ODM Resize Cell')
|
|
||||||
|
|
||||||
# get inputs
|
|
||||||
args = self.inputs.args
|
|
||||||
tree = self.inputs.tree
|
|
||||||
photos = self.inputs.photos
|
|
||||||
|
|
||||||
if not photos:
|
|
||||||
log.ODM_ERROR('Not enough photos in photos to resize')
|
|
||||||
return ecto.QUIT
|
|
||||||
|
|
||||||
if self.params.resize_to <= 0:
|
|
||||||
log.ODM_ERROR('Resize parameter must be greater than 0')
|
|
||||||
return ecto.QUIT
|
|
||||||
|
|
||||||
# create working directory
|
|
||||||
system.mkdir_p(tree.dataset_resize)
|
|
||||||
|
|
||||||
log.ODM_DEBUG('Resizing dataset to: %s' % tree.dataset_resize)
|
|
||||||
|
|
||||||
# check if we rerun cell or not
|
|
||||||
rerun_cell = (args.rerun is not None and
|
|
||||||
args.rerun == 'resize') or \
|
|
||||||
(args.rerun_all) or \
|
|
||||||
(args.rerun_from is not None and
|
|
||||||
'resize' in args.rerun_from)
|
|
||||||
|
|
||||||
# loop over photos
|
|
||||||
if self.params.skip_resize:
|
|
||||||
photos = Pool().map(
|
|
||||||
partial(no_resize,
|
|
||||||
tree.dataset_raw,
|
|
||||||
tree.dataset_resize,
|
|
||||||
rerun_cell),
|
|
||||||
photos
|
|
||||||
)
|
|
||||||
log.ODM_INFO('Copied %s images' % len(photos))
|
|
||||||
else:
|
|
||||||
photos = Pool().map(
|
|
||||||
partial(resize,
|
|
||||||
tree.dataset_raw,
|
|
||||||
tree.dataset_resize,
|
|
||||||
self.params.resize_to,
|
|
||||||
rerun_cell),
|
|
||||||
photos
|
|
||||||
)
|
|
||||||
log.ODM_INFO('Resized %s images' % len(photos))
|
|
||||||
|
|
||||||
# append photos to cell output
|
|
||||||
self.outputs.photos = photos
|
|
||||||
|
|
||||||
if args.time:
|
|
||||||
system.benchmark(start_time, tree.benchmarking, 'Resizing')
|
|
||||||
|
|
||||||
log.ODM_INFO('Running ODM Resize Cell - Finished')
|
|
||||||
return ecto.OK if args.end_with != 'resize' else ecto.QUIT
|
|
|
@ -8,7 +8,7 @@
|
||||||
project_path: '' # Example: '/home/user/ODMProjects
|
project_path: '' # Example: '/home/user/ODMProjects
|
||||||
|
|
||||||
# The rest of the settings will default to the values set unless you uncomment and change them
|
# The rest of the settings will default to the values set unless you uncomment and change them
|
||||||
#resize_to: 2400
|
#resize_to: 2048
|
||||||
#start_with: 'resize'
|
#start_with: 'resize'
|
||||||
#end_with: 'odm_orthophoto'
|
#end_with: 'odm_orthophoto'
|
||||||
#rerun_all: False
|
#rerun_all: False
|
||||||
|
|
Ładowanie…
Reference in New Issue