diff --git a/opendm/config.py b/opendm/config.py index 81b84bd4..15492af2 100755 --- a/opendm/config.py +++ b/opendm/config.py @@ -76,15 +76,14 @@ def config(argv=None, parser=None): parser.add_argument('--project-path', metavar='', action=StoreValue, - help='Path to the project folder') - + help='Path to the project folder. Your project folder should contain subfolders for each dataset. Each dataset should have an "images" folder.') parser.add_argument('name', metavar='', action=StoreValue, type=alphanumeric_string, default='code', nargs='?', - help='Name of Project (i.e subdirectory of projects folder)') + help='Name of dataset (i.e subfolder name within project folder). Default: %(default)s') parser.add_argument('--resize-to', metavar='', @@ -93,14 +92,14 @@ def config(argv=None, parser=None): type=int, help='Legacy option (use --feature-quality instead). Resizes images by the largest side for feature extraction purposes only. ' 'Set to -1 to disable. This does not affect the final orthophoto ' - 'resolution quality and will not resize the original images. Default: %(default)s') + 'resolution quality and will not resize the original images. Default: %(default)s') parser.add_argument('--end-with', '-e', metavar='', action=StoreValue, default='odm_report', choices=processopts, - help=('Can be one of:' + ' | '.join(processopts))) + help='End processing at this stage. Can be one of: %(choices)s. Default: %(default)s') rerun = parser.add_mutually_exclusive_group() @@ -108,27 +107,19 @@ def config(argv=None, parser=None): metavar='', action=StoreValue, choices=processopts, - help=('Can be one of:' + ' | '.join(processopts))) + help=('Rerun this stage only and stop. Can be one of: %(choices)s. Default: %(default)s')) rerun.add_argument('--rerun-all', action=StoreTrue, nargs=0, default=False, - help='force rerun of all tasks') + help='Permanently delete all previous results and rerun the processing pipeline.') rerun.add_argument('--rerun-from', action=RerunFrom, metavar='', choices=processopts, - help=('Can be one of:' + ' | '.join(processopts))) - - # parser.add_argument('--video', - # metavar='', - # help='Path to the video file to process') - - # parser.add_argument('--slam-config', - # metavar='', - # help='Path to config file for orb-slam') + help=('Rerun processing from this stage. Can be one of: %(choices)s. Default: %(default)s')) parser.add_argument('--min-num-features', metavar='', @@ -136,8 +127,9 @@ def config(argv=None, parser=None): default=8000, type=int, help=('Minimum number of features to extract per image. ' - 'More features leads to better results but slower ' - 'execution. Default: %(default)s')) + 'More features can be useful for finding more matches between images, ' + 'potentially allowing the reconstruction of areas with little overlap or insufficient features. ' + 'More features also slow down processing. Default: %(default)s')) parser.add_argument('--feature-type', metavar='', @@ -174,10 +166,7 @@ def config(argv=None, parser=None): help='Number of nearest images to pre-match based on GPS ' 'exif data. Set to 0 to skip pre-matching. ' 'Neighbors works together with Distance parameter, ' - 'set both to 0 to not use pre-matching. OpenSFM ' - 'uses both parameters at the same time, Bundler ' - 'uses only one which has value, prefering the ' - 'Neighbors parameter. Default: %(default)s') + 'set both to 0 to not use pre-matching. Default: %(default)s') parser.add_argument('--matcher-distance', metavar='', @@ -193,7 +182,7 @@ def config(argv=None, parser=None): action=StoreTrue, nargs=0, default=False, - help='Turn off camera parameter optimization during bundler') + help='Turn off camera parameter optimization during bundle adjustment. This can be sometimes useful for improving results that exhibit doming/bowling or when images are taken with a rolling shutter camera. Default: %(default)s') parser.add_argument('--cameras', default='', @@ -213,8 +202,7 @@ def config(argv=None, parser=None): choices=['auto', 'perspective', 'brown', 'fisheye', 'spherical'], help=('Set a camera projection type. Manually setting a value ' 'can help improve geometric undistortion. By default the application ' - 'tries to determine a lens type from the images metadata. Can be ' - 'set to one of: %(choices)s. Default: ' + 'tries to determine a lens type from the images metadata. Can be one of: %(choices)s. Default: ' '%(default)s')) parser.add_argument('--radiometric-calibration', @@ -227,7 +215,7 @@ def config(argv=None, parser=None): 'to obtain reflectance values (otherwise you will get digital number values). ' '[camera] applies black level, vignetting, row gradient gain/exposure compensation (if appropriate EXIF tags are found). ' '[camera+sun] is experimental, applies all the corrections of [camera], plus compensates for spectral radiance registered via a downwelling light sensor (DLS) taking in consideration the angle of the sun. ' - 'Can be set to one of: %(choices)s. Default: ' + 'Can be one of: %(choices)s. Default: ' '%(default)s')) parser.add_argument('--max-concurrency', @@ -282,25 +270,25 @@ def config(argv=None, parser=None): nargs=0, default=False, help='Run local bundle adjustment for every image added to the reconstruction and a global ' - 'adjustment every 100 images. Speeds up reconstruction for very large datasets.') + 'adjustment every 100 images. Speeds up reconstruction for very large datasets. Default: %(default)s') parser.add_argument('--use-3dmesh', action=StoreTrue, nargs=0, default=False, - help='Use a full 3D mesh to compute the orthophoto instead of a 2.5D mesh. This option is a bit faster and provides similar results in planar areas.') + help='Use a full 3D mesh to compute the orthophoto instead of a 2.5D mesh. This option is a bit faster and provides similar results in planar areas. Default: %(default)s') parser.add_argument('--skip-3dmodel', action=StoreTrue, nargs=0, default=False, - help='Skip generation of a full 3D model. This can save time if you only need 2D results such as orthophotos and DEMs.') + help='Skip generation of a full 3D model. This can save time if you only need 2D results such as orthophotos and DEMs. Default: %(default)s') parser.add_argument('--use-opensfm-dense', action=StoreTrue, nargs=0, default=False, - help='Use opensfm to compute dense point cloud alternatively') + help='Use OpenSfM to compute the dense point cloud instead of OpenMVS. Default: %(default)s') parser.add_argument('--ignore-gsd', action=StoreTrue, @@ -309,7 +297,7 @@ def config(argv=None, parser=None): help='Ignore Ground Sampling Distance (GSD). GSD ' 'caps the maximum resolution of image outputs and ' 'resizes images when necessary, resulting in faster processing and ' - 'lower memory usage. Since GSD is an estimate, sometimes ignoring it can result in slightly better image output quality.') + 'lower memory usage. Since GSD is an estimate, sometimes ignoring it can result in slightly better image output quality. Default: %(default)s') parser.add_argument('--mesh-size', metavar='', @@ -322,39 +310,19 @@ def config(argv=None, parser=None): parser.add_argument('--mesh-octree-depth', metavar='', action=StoreValue, - default=10, + default=11, type=int, - help=('Oct-tree depth used in the mesh reconstruction, ' + help=('Octree depth used in the mesh reconstruction, ' 'increase to get more vertices, recommended ' 'values are 8-12. Default: %(default)s')) - parser.add_argument('--mesh-samples', - metavar='= 1.0>', - action=StoreValue, - default=1.0, - type=float, - help=('Number of points per octree node, recommended ' - 'and default value: %(default)s')) - - parser.add_argument('--mesh-point-weight', - metavar='', - action=StoreValue, - default=4, - type=float, - help=('This floating point value specifies the importance' - ' that interpolation of the point samples is given in the ' - 'formulation of the screened Poisson equation. The results ' - 'of the original (unscreened) Poisson Reconstruction can ' - 'be obtained by setting this value to 0.' - 'Default= %(default)s')) - parser.add_argument('--fast-orthophoto', action=StoreTrue, nargs=0, default=False, help='Skips dense reconstruction and 3D model generation. ' 'It generates an orthophoto directly from the sparse reconstruction. ' - 'If you just need an orthophoto and do not need a full 3D model, turn on this option.') + 'If you just need an orthophoto and do not need a full 3D model, turn on this option. Default: %(default)s') parser.add_argument('--crop', metavar='', @@ -388,37 +356,35 @@ def config(argv=None, parser=None): action=StoreTrue, nargs=0, default=False, - help='Export the georeferenced point cloud in CSV format. Default: %(default)s') + help='Export the georeferenced point cloud in CSV format. Default: %(default)s') parser.add_argument('--pc-las', action=StoreTrue, nargs=0, default=False, - help='Export the georeferenced point cloud in LAS format. Default: %(default)s') + help='Export the georeferenced point cloud in LAS format. Default: %(default)s') parser.add_argument('--pc-ept', action=StoreTrue, nargs=0, default=False, - help='Export the georeferenced point cloud in Entwine Point Tile (EPT) format. Default: %(default)s') + help='Export the georeferenced point cloud in Entwine Point Tile (EPT) format. Default: %(default)s') parser.add_argument('--pc-filter', metavar='', action=StoreValue, type=float, default=2.5, - help='Filters the point cloud by removing points that deviate more than N standard deviations from the local mean. Set to 0 to disable filtering.' - '\nDefault: ' - '%(default)s') + help='Filters the point cloud by removing points that deviate more than N standard deviations from the local mean. Set to 0 to disable filtering. ' + 'Default: %(default)s') parser.add_argument('--pc-sample', metavar='', action=StoreValue, type=float, default=0, - help='Filters the point cloud by keeping only a single point around a radius N (in meters). This can be useful to limit the output resolution of the point cloud. Set to 0 to disable sampling.' - '\nDefault: ' - '%(default)s') + help='Filters the point cloud by keeping only a single point around a radius N (in meters). This can be useful to limit the output resolution of the point cloud. Set to 0 to disable sampling. ' + 'Default: %(default)s') parser.add_argument('--smrf-scalar', metavar='', @@ -426,8 +392,7 @@ def config(argv=None, parser=None): type=float, default=1.25, help='Simple Morphological Filter elevation scalar parameter. ' - '\nDefault: ' - '%(default)s') + 'Default: %(default)s') parser.add_argument('--smrf-slope', metavar='', @@ -435,8 +400,7 @@ def config(argv=None, parser=None): type=float, default=0.15, help='Simple Morphological Filter slope parameter (rise over run). ' - '\nDefault: ' - '%(default)s') + 'Default: %(default)s') parser.add_argument('--smrf-threshold', metavar='', @@ -444,8 +408,7 @@ def config(argv=None, parser=None): type=float, default=0.5, help='Simple Morphological Filter elevation threshold parameter (meters). ' - '\nDefault: ' - '%(default)s') + 'Default: %(default)s') parser.add_argument('--smrf-window', metavar='', @@ -453,38 +416,33 @@ def config(argv=None, parser=None): type=float, default=18.0, help='Simple Morphological Filter window radius parameter (meters). ' - '\nDefault: ' - '%(default)s') + 'Default: %(default)s') parser.add_argument('--texturing-data-term', metavar='', action=StoreValue, default='gmi', choices=['gmi', 'area'], - help=('Data term: [area, gmi]. Default: ' - '%(default)s')) + help=('When texturing the 3D mesh, for each triangle, choose to prioritize images with sharp features (gmi) or those that cover the largest area (area). Default: %(default)s')) parser.add_argument('--texturing-outlier-removal-type', metavar='', action=StoreValue, default='gauss_clamping', choices=['none', 'gauss_clamping', 'gauss_damping'], - help=('Type of photometric outlier removal method: ' - '[none, gauss_damping, gauss_clamping]. Default: ' - '%(default)s')) + help=('Type of photometric outlier removal method. Can be one of: %(choices)s. Default: %(default)s')) parser.add_argument('--texturing-skip-global-seam-leveling', action=StoreTrue, nargs=0, default=False, - help=('Skip global seam leveling. Useful for IR data.' - 'Default: %(default)s')) + help=('Skip normalization of colors across all images. Useful when processing radiometric data. Default: %(default)s')) parser.add_argument('--texturing-skip-local-seam-leveling', action=StoreTrue, nargs=0, default=False, - help='Skip local seam blending. Default: %(default)s') + help='Skip the blending of colors near seams. Default: %(default)s') parser.add_argument('--texturing-tone-mapping', metavar='', @@ -492,7 +450,7 @@ def config(argv=None, parser=None): choices=['none', 'gamma'], default='none', help='Turn on gamma tone mapping or none for no tone ' - 'mapping. Choices are \'gamma\' or \'none\'. ' + 'mapping. Can be one of %(choices)s. ' 'Default: %(default)s ') parser.add_argument('--gcp', @@ -500,11 +458,12 @@ def config(argv=None, parser=None): action=StoreValue, default=None, help=('Path to the file containing the ground control ' - 'points used for georeferencing. Default: ' - '%(default)s. The file needs to ' + 'points used for georeferencing. ' + 'The file needs to ' 'use the following format: \n' 'EPSG: or <+proj definition>\n' - 'geo_x geo_y geo_z im_x im_y image_name [gcp_name] [extra1] [extra2]')) + 'geo_x geo_y geo_z im_x im_y image_name [gcp_name] [extra1] [extra2]\n' + 'Default: %(default)s')) parser.add_argument('--geo', metavar='', @@ -512,33 +471,32 @@ def config(argv=None, parser=None): default=None, help=('Path to the image geolocation file containing the camera center coordinates used for georeferencing. ' 'Note that omega/phi/kappa are currently not supported (you can set them to 0). ' - 'Default: ' - '%(default)s. The file needs to ' + 'The file needs to ' 'use the following format: \n' 'EPSG: or <+proj definition>\n' - 'image_name geo_x geo_y geo_z [omega (degrees)] [phi (degrees)] [kappa (degrees)] [horz accuracy (meters)] [vert accuracy (meters)]' - '')) + 'image_name geo_x geo_y geo_z [omega (degrees)] [phi (degrees)] [kappa (degrees)] [horz accuracy (meters)] [vert accuracy (meters)]\n' + 'Default: %(default)s')) parser.add_argument('--use-exif', action=StoreTrue, nargs=0, default=False, - help=('Use this tag if you have a gcp_list.txt but ' - 'want to use the exif geotags instead')) + help=('Use this tag if you have a GCP File but ' + 'want to use the EXIF information for georeferencing instead. Default: %(default)s')) parser.add_argument('--dtm', action=StoreTrue, nargs=0, default=False, help='Use this tag to build a DTM (Digital Terrain Model, ground only) using a simple ' - 'morphological filter. Check the --dem* and --smrf* parameters for finer tuning.') + 'morphological filter. Check the --dem* and --smrf* parameters for finer tuning. Default: %(default)s') parser.add_argument('--dsm', action=StoreTrue, nargs=0, default=False, help='Use this tag to build a DSM (Digital Surface Model, ground + objects) using a progressive ' - 'morphological filter. Check the --dem* parameters for finer tuning.') + 'morphological filter. Check the --dem* parameters for finer tuning. Default: %(default)s') parser.add_argument('--dem-gapfill-steps', metavar='', @@ -549,7 +507,7 @@ def config(argv=None, parser=None): 'Starting with a radius equal to the output resolution, N different DEMs are generated with ' 'progressively bigger radius using the inverse distance weighted (IDW) algorithm ' 'and merged together. Remaining gaps are then merged using nearest neighbor interpolation. ' - '\nDefault=%(default)s') + 'Default: %(default)s') parser.add_argument('--dem-resolution', metavar='', @@ -557,7 +515,7 @@ def config(argv=None, parser=None): type=float, default=5, help='DSM/DTM resolution in cm / pixel. Note that this value is capped by a ground sampling distance (GSD) estimate. To remove the cap, check --ignore-gsd also.' - '\nDefault: %(default)s') + ' Default: %(default)s') parser.add_argument('--dem-decimation', metavar='', @@ -565,8 +523,7 @@ def config(argv=None, parser=None): default=1, type=int, help='Decimate the points before generating the DEM. 1 is no decimation (full quality). ' - '100 decimates ~99%% of the points. Useful for speeding up ' - 'generation.\nDefault=%(default)s') + '100 decimates ~99%% of the points. Useful for speeding up generation of DEM results in very large datasets. Default: %(default)s') parser.add_argument('--dem-euclidean-map', action=StoreTrue, @@ -584,21 +541,21 @@ def config(argv=None, parser=None): action=StoreValue, default=5, type=float, - help=('Orthophoto resolution in cm / pixel. Note that this value is capped by a ground sampling distance (GSD) estimate. To remove the cap, check --ignore-gsd also.\n' + help=('Orthophoto resolution in cm / pixel. Note that this value is capped by a ground sampling distance (GSD) estimate. To remove the cap, check --ignore-gsd also. ' 'Default: %(default)s')) parser.add_argument('--orthophoto-no-tiled', action=StoreTrue, nargs=0, default=False, - help='Set this parameter if you want a stripped geoTIFF.\n' + help='Set this parameter if you want a striped GeoTIFF. ' 'Default: %(default)s') parser.add_argument('--orthophoto-png', action=StoreTrue, nargs=0, default=False, - help='Set this parameter if you want to generate a PNG rendering of the orthophoto.\n' + help='Set this parameter if you want to generate a PNG rendering of the orthophoto. ' 'Default: %(default)s') parser.add_argument('--orthophoto-compression', @@ -607,7 +564,7 @@ def config(argv=None, parser=None): type=str, choices=['JPEG', 'LZW', 'PACKBITS', 'DEFLATE', 'LZMA', 'NONE'], default='DEFLATE', - help='Set the compression to use for orthophotos. Options: %(choices)s.\nDefault: %(default)s') + help='Set the compression to use for orthophotos. Can be one of: %(choices)s. Default: %(default)s') parser.add_argument('--orthophoto-cutline', action=StoreTrue, @@ -631,28 +588,27 @@ def config(argv=None, parser=None): action=StoreTrue, nargs=0, default=False, - help='Build orthophoto overviews using gdaladdo.') + help='Build orthophoto overviews for faster display in programs such as QGIS. Default: %(default)s') parser.add_argument('--verbose', '-v', action=StoreTrue, nargs=0, default=False, - help='Print additional messages to the console\n' + help='Print additional messages to the console. ' 'Default: %(default)s') parser.add_argument('--time', action=StoreTrue, nargs=0, default=False, - help='Generates a benchmark file with runtime info\n' + help='Generates a benchmark file with runtime info. ' 'Default: %(default)s') parser.add_argument('--debug', action=StoreTrue, nargs=0, default=False, - help='Print debug messages\n' - 'Default: %(default)s') + help='Print debug messages. Default: %(default)s') parser.add_argument('--version', action='version', @@ -668,7 +624,7 @@ def config(argv=None, parser=None): 'splitting a large dataset into smaller ' 'submodels, images are grouped into clusters. ' 'This value regulates the number of images that ' - 'each cluster should have on average.') + 'each cluster should have on average. Default: %(default)s') parser.add_argument('--split-overlap', type=float, @@ -679,13 +635,13 @@ def config(argv=None, parser=None): 'After grouping images into clusters, images ' 'that are closer than this radius to a cluster ' 'are added to the cluster. This is done to ensure ' - 'that neighboring submodels overlap.') + 'that neighboring submodels overlap. Default: %(default)s') - parser.add_argument('--split-multitracks', - action=StoreTrue, - nargs=0, - default=False, - help='Split multi-track reconstructions.') + # parser.add_argument('--split-multitracks', + # action=StoreTrue, + # nargs=0, + # default=False, + # help='Split multi-track reconstructions.') parser.add_argument('--sm-cluster', metavar='', diff --git a/stages/odm_app.py b/stages/odm_app.py index 9aec5085..7b14c080 100644 --- a/stages/odm_app.py +++ b/stages/odm_app.py @@ -39,8 +39,8 @@ class ODMApp: meshing = ODMeshingStage('odm_meshing', args, progress=60.0, max_vertex=args.mesh_size, oct_tree=args.mesh_octree_depth, - samples=args.mesh_samples, - point_weight=args.mesh_point_weight, + samples=1.0, + point_weight=4.0, max_concurrency=args.max_concurrency, verbose=args.verbose) texturing = ODMMvsTexStage('mvs_texturing', args, progress=70.0, diff --git a/stages/splitmerge.py b/stages/splitmerge.py index 5d1c04e6..b9592da6 100644 --- a/stages/splitmerge.py +++ b/stages/splitmerge.py @@ -104,67 +104,70 @@ class ODMSplitStage(types.ODM_Stage): self.update_progress(50) - resplit_done_file = octx.path('resplit_done.txt') - if not io.file_exists(resplit_done_file) and bool(args.split_multitracks): - submodels = mds.get_submodel_paths() - i = 0 - for s in submodels: - template = octx.path("../aligned_submodels/submodel_%04d") - with open(s+"/reconstruction.json", "r") as f: - j = json.load(f) - for k in range(0, len(j)): - v = j[k] - path = template % i + # TODO: this is currently not working and needs a champion to fix it + # https://community.opendronemap.org/t/filenotfound-error-cameras-json/6047/2 + + # resplit_done_file = octx.path('resplit_done.txt') + # if not io.file_exists(resplit_done_file) and bool(args.split_multitracks): + # submodels = mds.get_submodel_paths() + # i = 0 + # for s in submodels: + # template = octx.path("../aligned_submodels/submodel_%04d") + # with open(s+"/reconstruction.json", "r") as f: + # j = json.load(f) + # for k in range(0, len(j)): + # v = j[k] + # path = template % i - #Create the submodel path up to opensfm - os.makedirs(path+"/opensfm") - os.makedirs(path+"/images") + # #Create the submodel path up to opensfm + # os.makedirs(path+"/opensfm") + # os.makedirs(path+"/images") - #symlinks for common data - images = os.listdir(octx.path("../images")) - for image in images: - os.symlink("../../../images/"+image, path+"/images/"+image) - os.symlink("../../../opensfm/exif", path+"/opensfm/exif") - os.symlink("../../../opensfm/features", path+"/opensfm/features") - os.symlink("../../../opensfm/matches", path+"/opensfm/matches") - os.symlink("../../../opensfm/reference_lla.json", path+"/opensfm/reference_lla.json") - os.symlink("../../../opensfm/camera_models.json", path+"/opensfm/camera_models.json") + # #symlinks for common data + # images = os.listdir(octx.path("../images")) + # for image in images: + # os.symlink("../../../images/"+image, path+"/images/"+image) + # os.symlink("../../../opensfm/exif", path+"/opensfm/exif") + # os.symlink("../../../opensfm/features", path+"/opensfm/features") + # os.symlink("../../../opensfm/matches", path+"/opensfm/matches") + # os.symlink("../../../opensfm/reference_lla.json", path+"/opensfm/reference_lla.json") + # os.symlink("../../../opensfm/camera_models.json", path+"/opensfm/camera_models.json") - shutil.copy(s+"/../cameras.json", path+"/cameras.json") + # shutil.copy(s+"/../cameras.json", path+"/cameras.json") - shutil.copy(s+"/../images.json", path+"/images.json") + # shutil.copy(s+"/../images.json", path+"/images.json") - with open(octx.path("config.yaml")) as f: - doc = yaml.safe_load(f) + # with open(octx.path("config.yaml")) as f: + # doc = yaml.safe_load(f) - dmcv = "depthmap_min_consistent_views" - if dmcv in doc: - if len(v["shots"]) < doc[dmcv]: - doc[dmcv] = len(v["shots"]) - print("WARNING: Reduced "+dmcv+" to accommodate short track") + # dmcv = "depthmap_min_consistent_views" + # if dmcv in doc: + # if len(v["shots"]) < doc[dmcv]: + # doc[dmcv] = len(v["shots"]) + # print("WARNING: Reduced "+dmcv+" to accommodate short track") - with open(path+"/opensfm/config.yaml", "w") as f: - yaml.dump(doc, f) + # with open(path+"/opensfm/config.yaml", "w") as f: + # yaml.dump(doc, f) - #We need the original tracks file for the visualsfm export, since - #there may still be point matches between the tracks - shutil.copy(s+"/tracks.csv", path+"/opensfm/tracks.csv") + # #We need the original tracks file for the visualsfm export, since + # #there may still be point matches between the tracks + # shutil.copy(s+"/tracks.csv", path+"/opensfm/tracks.csv") - #Create our new reconstruction file with only the relevant track - with open(path+"/opensfm/reconstruction.json", "w") as o: - json.dump([v], o) + # #Create our new reconstruction file with only the relevant track + # with open(path+"/opensfm/reconstruction.json", "w") as o: + # json.dump([v], o) - #Create image lists - with open(path+"/opensfm/image_list.txt", "w") as o: - o.writelines(list(map(lambda x: "../images/"+x+'\n', v["shots"].keys()))) - with open(path+"/img_list.txt", "w") as o: - o.writelines(list(map(lambda x: x+'\n', v["shots"].keys()))) + # #Create image lists + # with open(path+"/opensfm/image_list.txt", "w") as o: + # o.writelines(list(map(lambda x: "../images/"+x+'\n', v["shots"].keys()))) + # with open(path+"/img_list.txt", "w") as o: + # o.writelines(list(map(lambda x: x+'\n', v["shots"].keys()))) - i+=1 - os.rename(octx.path("../submodels"), octx.path("../unaligned_submodels")) - os.rename(octx.path("../aligned_submodels"), octx.path("../submodels")) - octx.touch(resplit_done_file) + # i+=1 + # os.rename(octx.path("../submodels"), octx.path("../unaligned_submodels")) + # os.rename(octx.path("../aligned_submodels"), octx.path("../submodels")) + # octx.touch(resplit_done_file) mds = metadataset.MetaDataSet(tree.opensfm) submodel_paths = [os.path.abspath(p) for p in mds.get_submodel_paths()]