Commit 8f5663f9 authored by Clément Pinard's avatar Clément Pinard
Browse files

Add options to main_pipeline

parent 530512dd
...@@ -23,7 +23,7 @@ def add_to_db(db_path, metadata_path, frame_list_path, **env): ...@@ -23,7 +23,7 @@ def add_to_db(db_path, metadata_path, frame_list_path, **env):
frame_list = [] frame_list = []
if frame_list_path is not None: if frame_list_path is not None:
with open(frame_list_path, "r") as f: with open(frame_list_path, "r") as f:
frame_list = [line[:1] for line in f.readlines()] frame_list = [line[:-1] for line in f.readlines()]
metadata = metadata[metadata["image_path"].isin(frame_list)] metadata = metadata[metadata["image_path"].isin(frame_list)]
for image_id, row in tqdm(metadata.iterrows(), total=len(metadata)): for image_id, row in tqdm(metadata.iterrows(), total=len(metadata)):
...@@ -34,11 +34,15 @@ def add_to_db(db_path, metadata_path, frame_list_path, **env): ...@@ -34,11 +34,15 @@ def add_to_db(db_path, metadata_path, frame_list_path, **env):
else: else:
frame_gps = np.full(3, np.NaN) frame_gps = np.full(3, np.NaN)
try: try:
print(image_path, camera_id)
database.add_image(image_path, int(camera_id), prior_t=frame_gps) database.add_image(image_path, int(camera_id), prior_t=frame_gps)
except IntegrityError: except IntegrityError:
sql_string = "SELECT camera_id FROM images WHERE name='{}'".format(image_path) sql_string = "SELECT camera_id FROM images WHERE name='{}'".format(image_path)
existing_camera_id = print(next(database.execute(sql_string))[0]) row = next(database.execute(sql_string))
existing_camera_id = row[0]
assert(existing_camera_id == camera_id) assert(existing_camera_id == camera_id)
database.commit()
database.close()
def main(): def main():
......
...@@ -71,7 +71,7 @@ def extract_metadata(folder_path, file_path, native_wrapper, proj, w, h, f, cent ...@@ -71,7 +71,7 @@ def extract_metadata(folder_path, file_path, native_wrapper, proj, w, h, f, cent
metadata["width"] = w metadata["width"] = w
metadata["framerate"] = f metadata["framerate"] = f
metadata["video"] = file_path metadata["video"] = file_path
metadata['frame'] = metadata.index metadata['frame'] = metadata.index + 1
if save_path is not None: if save_path is not None:
metadata.to_csv(save_path) metadata.to_csv(save_path)
return metadata return metadata
...@@ -19,7 +19,7 @@ global_steps = ["Point Cloud Preparation", ...@@ -19,7 +19,7 @@ global_steps = ["Point Cloud Preparation",
"Alignment of photogrammetric reconstruction with Lidar point cloud", "Alignment of photogrammetric reconstruction with Lidar point cloud",
"Occlusion Mesh computing"] "Occlusion Mesh computing"]
pre_vid_steps = ["Full video extraction" pre_vid_steps = ["Full video extraction",
"Sky mask generation", "Sky mask generation",
"Complete photogrammetry with video at 1 fps", "Complete photogrammetry with video at 1 fps",
"Localizing remaining frames", "Localizing remaining frames",
...@@ -43,7 +43,13 @@ main_parser.add_argument('-v', '--verbose', action="count", default=0) ...@@ -43,7 +43,13 @@ main_parser.add_argument('-v', '--verbose', action="count", default=0)
main_parser.add_argument('--vid_ext', nargs='+', default=[".mp4", ".MP4"]) main_parser.add_argument('--vid_ext', nargs='+', default=[".mp4", ".MP4"])
main_parser.add_argument('--pic_ext', nargs='+', default=[".jpg", ".JPG", ".png", ".PNG"]) main_parser.add_argument('--pic_ext', nargs='+', default=[".jpg", ".JPG", ".png", ".PNG"])
main_parser.add_argument('--raw_ext', nargs='+', default=[".ARW", ".NEF", ".DNG"]) main_parser.add_argument('--raw_ext', nargs='+', default=[".ARW", ".NEF", ".DNG"])
main_parser.add_argument('--fine_sift_features', action="store_true")
main_parser.add_argument('--save_space', action="store_true") main_parser.add_argument('--save_space', action="store_true")
main_parser.add_argument('--add_new_videos', action="store_true")
pcp_parser = parser.add_argument("PointCLoud preparation")
pcp_parser.add_argument("--pointcloud_resolution", default=0.1, type=float)
pcp_parser.add_argument("--SOR", default=[6, 2], nargs=2, type=int)
ve_parser = parser.add_argument_group("Video extractor") ve_parser = parser.add_argument_group("Video extractor")
ve_parser.add_argument('--total_frames', default=500, type=int) ve_parser.add_argument('--total_frames', default=500, type=int)
...@@ -62,8 +68,16 @@ exec_parser.add_argument("--eth3d", default="../dataset-pipeline/build", ...@@ -62,8 +68,16 @@ exec_parser.add_argument("--eth3d", default="../dataset-pipeline/build",
exec_parser.add_argument("--ffmpeg", default="ffmpeg") exec_parser.add_argument("--ffmpeg", default="ffmpeg")
exec_parser.add_argument("--pcl_util", default="pcl_util/build", type=Path) exec_parser.add_argument("--pcl_util", default="pcl_util/build", type=Path)
video_registration_parser = parser.add_argument_group("Video Registration") vr_parser = parser.add_argument_group("Video Registration")
video_registration_parser.add_argument("--vocab_tree", type=Path, default="vocab_tree_flickr100K_words256K.bin") vr_parser.add_argument("--vocab_tree", type=Path, default="vocab_tree_flickr100K_words256K.bin")
om_parser = parser.add_argument_group("Occlusion Mesh")
om_parser.add_argument('--normal_radius', default=0.2, type=float)
om_parser.add_argument('--mesh_resolution', default=0.2, type=float)
om_parser.add_argument('--splat_threshold', default=0.1, type=float)
om_parser.add_argument('--resolution_weight', default=1, type=float)
om_parser.add_argument('--num_neighbours', default=10, type=int)
om_parser.add_argument('--system', default="epsg:2154")
def print_workflow(): def print_workflow():
...@@ -83,7 +97,7 @@ def print_step(step_number, step_name): ...@@ -83,7 +97,7 @@ def print_step(step_number, step_name):
print("=================") print("=================")
def convert_point_cloud(pointclouds, lidar_path, verbose, eth3d, pcl_util, **env): def convert_point_cloud(pointclouds, lidar_path, verbose, eth3d, pcl_util, pointcloud_resolution, save_space, **env):
converted_clouds = [] converted_clouds = []
centroids = [] centroids = []
for pc in pointclouds: for pc in pointclouds:
...@@ -92,13 +106,17 @@ def convert_point_cloud(pointclouds, lidar_path, verbose, eth3d, pcl_util, **env ...@@ -92,13 +106,17 @@ def convert_point_cloud(pointclouds, lidar_path, verbose, eth3d, pcl_util, **env
verbose=verbose >= 1) verbose=verbose >= 1)
centroids.append(centroid) centroids.append(centroid)
eth3d.clean_pointcloud(ply, filter=(6, 2)) eth3d.clean_pointcloud(ply, filter=(6, 2))
pcl_util.subsample(input_file=ply + ".inliers.ply", output_file=ply + "_subsampled.ply", resolution=0.1) pcl_util.subsample(input_file=ply + ".inliers.ply", output_file=ply + "_subsampled.ply", resolution=pointcloud_resolution)
if save_space:
(ply + ".inliers.ply").remove()
(ply + ".outliers.ply").remove()
ply.remove()
converted_clouds.append(ply + "_subsampled.ply") converted_clouds.append(ply + "_subsampled.ply")
return converted_clouds, centroids[0] return converted_clouds, centroids[0]
def extract_pictures_to_workspace(input_folder, image_path, workspace, colmap, raw_ext, pic_ext, **env): def extract_pictures_to_workspace(input_folder, image_path, workspace, colmap, raw_ext, pic_ext, fine_sift_features, **env):
picture_folder = input_folder / "Pictures" picture_folder = input_folder / "Pictures"
picture_folder.merge_tree(image_path) picture_folder.merge_tree(image_path)
raw_files = sum((list(image_path.walkfiles('*{}'.format(ext))) for ext in raw_ext), []) raw_files = sum((list(image_path.walkfiles('*{}'.format(ext))) for ext in raw_ext), [])
...@@ -109,7 +127,7 @@ def extract_pictures_to_workspace(input_folder, image_path, workspace, colmap, r ...@@ -109,7 +127,7 @@ def extract_pictures_to_workspace(input_folder, image_path, workspace, colmap, r
imageio.imsave(raw.stripext() + ".jpg", rgb) imageio.imsave(raw.stripext() + ".jpg", rgb)
raw.remove() raw.remove()
gsm.process_folder(folder_to_process=image_path, image_path=image_path, pic_ext=pic_ext, **env) gsm.process_folder(folder_to_process=image_path, image_path=image_path, pic_ext=pic_ext, **env)
colmap.extract_features(per_sub_folder=True, fine=False) colmap.extract_features(per_sub_folder=True, fine=fine_sift_features)
return sum((list(image_path.walkfiles('*{}'.format(ext))) for ext in pic_ext), []) return sum((list(image_path.walkfiles('*{}'.format(ext))) for ext in pic_ext), [])
...@@ -159,6 +177,8 @@ def main(): ...@@ -159,6 +177,8 @@ def main():
env = vars(args) env = vars(args)
if args.show_steps: if args.show_steps:
print_workflow() print_workflow()
if args.add_new_videos:
args.skip_step += [1, 2, 4, 5, 6]
if args.begin_step is not None: if args.begin_step is not None:
args.skip_step += list(range(args.begin_step)) args.skip_step += list(range(args.begin_step))
check_input_folder(args.input_folder) check_input_folder(args.input_folder)
...@@ -212,17 +232,18 @@ def main(): ...@@ -212,17 +232,18 @@ def main():
with open(env["videos_output_folders"][v] / "to_scan.txt", "w") as f: with open(env["videos_output_folders"][v] / "to_scan.txt", "w") as f:
f.write("\n".join(path_lists[v])) f.write("\n".join(path_lists[v]))
else: else:
by_basename = {v.basename(): v for v in env["videos_list"]} env["videos_output_folders"] = {}
by_name = {v.namebase: v for v in env["videos_list"]}
for folder in env["video_path"].walkdirs(): for folder in env["video_path"].walkdirs():
video_name = folder.basename() video_name = folder.basename()
if video_name in by_basename.keys(): if video_name in by_name.keys():
env["videos_output_folders"][by_basename[video_name]] = folder env["videos_output_folders"][by_name[video_name]] = folder
i, s = next(i_global_steps) i, s = next(i_global_steps)
if i + 1 not in args.skip_step: if i + 1 not in args.skip_step:
print_step(i, s) print_step(i, s)
gsm.process_folder(folder_to_process=env["video_path"], **env) gsm.process_folder(folder_to_process=env["video_path"], **env)
colmap.extract_features(image_list=env["video_frame_list_thorough"], fine=False) colmap.extract_features(image_list=env["video_frame_list_thorough"], fine=args.fine_sift_features)
colmap.match() colmap.match()
colmap.map(output_model=env["thorough_recon"].parent) colmap.map(output_model=env["thorough_recon"].parent)
...@@ -246,9 +267,9 @@ def main(): ...@@ -246,9 +267,9 @@ def main():
print_step(i, s) print_step(i, s)
with_normals_path = env["lidar_path"] / "with_normals.ply" with_normals_path = env["lidar_path"] / "with_normals.ply"
eth3d.compute_normals(with_normals_path, env["aligned_mlp"], neighbor_radius=0.2) eth3d.compute_normals(with_normals_path, env["aligned_mlp"], neighbor_radius=args.normal_radius)
pcl_util.triangulate_mesh(env["occlusion_ply"], with_normals_path, resolution=0.2) pcl_util.triangulate_mesh(env["occlusion_ply"], with_normals_path, resolution=args.mesh_resolution)
eth3d.create_splats(env["splats_ply"], with_normals_path, env["occlusion_ply"], threshold=0.1) eth3d.create_splats(env["splats_ply"], with_normals_path, env["occlusion_ply"], threshold=args.splat_threshold)
mxw.create_project(env["occlusion_mlp"], [env["occlusion_ply"], env["splats_ply"]]) mxw.create_project(env["occlusion_mlp"], [env["occlusion_ply"], env["splats_ply"]])
if args.save_space: if args.save_space:
with_normals_path.remove() with_normals_path.remove()
...@@ -261,12 +282,16 @@ def main(): ...@@ -261,12 +282,16 @@ def main():
current_db = current_video_folder / "video.db" current_db = current_video_folder / "video.db"
current_metadata = current_video_folder / "metadata.csv" current_metadata = current_video_folder / "metadata.csv"
former_db.copy(current_db) former_db.copy(current_db)
image_list_path = current_video_folder / "to_scan.txt"
colmap.db = current_db colmap.db = current_db
i, s = next(i_pv_steps) i, s = next(i_pv_steps)
print_step(i, s) print_step(i, s)
existing_images = list(current_video_folder.files()) if args.save_space:
ffmpeg.extract_images(v, current_video_folder) existing_images = list(current_video_folder.files())
ffmpeg.extract_images(v, current_video_folder)
else:
print("Already Done.")
i, s = next(i_pv_steps) i, s = next(i_pv_steps)
print_step(i, s) print_step(i, s)
...@@ -276,15 +301,11 @@ def main(): ...@@ -276,15 +301,11 @@ def main():
print_step(i, s) print_step(i, s)
image_list_path = current_video_folder / "to_scan.txt" image_list_path = current_video_folder / "to_scan.txt"
avtd.add_to_db(current_db, current_metadata, image_list_path) avtd.add_to_db(current_db, current_metadata, image_list_path)
colmap.extract_features(image_list=image_list_path, fine=False) colmap.extract_features(image_list=image_list_path, fine=args.fine_sift_features)
i, s = next(i_pv_steps)
print_step(i, s)
colmap.match(method="sequential", vocab_tree=args.vocab_tree) colmap.match(method="sequential", vocab_tree=args.vocab_tree)
video_output_model = env["video_recon"] / v.basename() video_output_model = env["video_recon"] / v.basename()
video_output_model.makedirs_p() video_output_model.makedirs_p()
colmap.map(output_model=video_output_model, input_model=env["georef"]) colmap.map(output_model=video_output_model, input_model=env["georef_recon"])
colmap.align_model(output_model=video_output_model, colmap.align_model(output_model=video_output_model,
input_model=video_output_model, input_model=video_output_model,
ref_images=env["georef_frames_list"]) ref_images=env["georef_frames_list"])
...@@ -292,7 +313,7 @@ def main(): ...@@ -292,7 +313,7 @@ def main():
i, s = next(i_pv_steps) i, s = next(i_pv_steps)
print_step(i, s) print_step(i, s)
avtd.add_to_db(current_db, current_metadata, frame_list_path=None) avtd.add_to_db(current_db, current_metadata, frame_list_path=None)
colmap.extract_features(image_list=current_video_folder / "to_scan.txt", fine=False) colmap.extract_features(fine=args.fine_sift_features)
colmap.match(method="sequential", vocab_tree=args.vocab_tree) colmap.match(method="sequential", vocab_tree=args.vocab_tree)
colmap.register_images(output_model=video_output_model, input_model=video_output_model) colmap.register_images(output_model=video_output_model, input_model=video_output_model)
colmap.adjust_bundle(output_model=video_output_model, input_model=video_output_model) colmap.adjust_bundle(output_model=video_output_model, input_model=video_output_model)
......
...@@ -29,7 +29,7 @@ class Colmap(Wrapper): ...@@ -29,7 +29,7 @@ class Colmap(Wrapper):
"--SiftMatching.guided_matching", "0"] "--SiftMatching.guided_matching", "0"]
if method == "sequential": if method == "sequential":
assert vocab_tree is not None assert vocab_tree is not None
options += ["--SequentialMatching.loop_detection", 1, options += ["--SequentialMatching.loop_detection", "1",
"--SequentialMatching.vocab_tree_path", vocab_tree] "--SequentialMatching.vocab_tree_path", vocab_tree]
self.__call__(options) self.__call__(options)
......
...@@ -31,11 +31,6 @@ class ETH3D(Wrapper): ...@@ -31,11 +31,6 @@ class ETH3D(Wrapper):
options += ["--neighbor_radius", str(neighbor_radius)] options += ["--neighbor_radius", str(neighbor_radius)]
self.__call__(options) self.__call__(options)
def triangulate_mesh(self, output_mesh, input_normals, resolution=20):
options = ["MeshTriangulator", "--point_normal_cloud_path", input_normals,
"--resolution", str(resolution), "--out_mesh", output_mesh]
self.__call__(options)
def create_splats(self, output_splats, pointnormals_ply, occlusion_ply, threshold=0.1): def create_splats(self, output_splats, pointnormals_ply, occlusion_ply, threshold=0.1):
options = ["SplatCreator", "--point_normal_cloud_path", pointnormals_ply, options = ["SplatCreator", "--point_normal_cloud_path", pointnormals_ply,
"--mesh_path", occlusion_ply, "--mesh_path", occlusion_ply,
......
...@@ -16,7 +16,7 @@ class PCLUtil(Wrapper): ...@@ -16,7 +16,7 @@ class PCLUtil(Wrapper):
"--resolution", str(resolution), "--output", output_file] "--resolution", str(resolution), "--output", output_file]
self.__call__(options) self.__call__(options)
def triangulate_mesh(self, input_file, output_file, resolution=0.2): def triangulate_mesh(self, output_file, input_file, resolution=0.2):
options = ["MeshTriangulator", "--point_normal_cloud_path", input_file, options = ["MeshTriangulator", "--point_normal_cloud_path", input_file,
"--resolution", str(resolution), "--out_mesh", output_file] "--resolution", str(resolution), "--out_mesh", output_file]
self.__call__(options) self.__call__(options)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment