Files
hand-motion-pipeline/third_party/Dyn-HaMR/dyn-hamr/preproc/launch_slam.py
T

187 lines
5.6 KiB
Python

import os
import glob
import json
import numpy as np
import subprocess
from concurrent import futures
import multiprocessing as mp
from preproc.datasets import update_args
SRC_DIR = os.path.abspath(f"{__file__}/../")
def isimage(path):
ext = os.path.splitext(path)[-1].lower()
return ext == ".png" or ext == ".jpg" or ext == ".jpeg"
def split_frames_equal(img_dir, seq_len=-1):
"""
split the sequence into subsequences of seq_len
returns start and end indices for each subsequence
"""
if seq_len == -1: # don't split
return [(0, -1)]
image_list = sorted(list(filter(isimage, os.listdir(img_dir))))
num_imgs = len(image_list)
splits = list(range(0, num_imgs, seq_len))
splits[-1] = num_imgs # add remainder to last subseq
return list(zip(splits[:-1], splits[1:]))
def split_frames_shots(img_dir, shot_path, pad_shot=0, min_len=0):
"""
split the sequence into subsequences according by shots in the video
returns start and end indices for each subsequence
"""
if shot_path is None or not os.path.isfile(shot_path):
print(f"{shot_path} DOES NOT EXIST, USING WHOLE SEQUENCE")
return [(0, -1)], [0]
image_list = sorted(list(filter(isimage, os.listdir(img_dir))))#[:500]
num_frames = len(image_list)
with open(shot_path, "r") as f:
shot_dict = json.load(f)
# print(shot_dict.keys())
shot_idcs = np.array([shot_dict[name] for name in image_list])
subseqs = []
for i in np.unique(shot_idcs):
idcs = np.where(shot_idcs == i)[0]
start, end = idcs.min(), idcs.max() + 1
if pad_shot > 0:
if start > 0:
start = start + pad_shot
if end < num_frames:
end = end - pad_shot
if (end - start) < min_len: # this shot is too short
continue
subseqs.append((start, end))
return subseqs, np.unique(shot_idcs)
def split_sequence(args, img_dir, seq):
subseqs = split_frames_equal(img_dir, args.seq_len)
return subseqs, [None for _ in subseqs]
def get_out_dir(args, seq, shot_idx=None, start=0, end=-1):
if "egobody" in args.type or "3dpw" in args.type:
if args.use_intrins:
out_name = "cameras_intrins"
else:
out_name = "cameras_default"
else:
out_name = "cameras"
if args.seq_len > 0:
out_name = f"{out_name}_split"
out_dir = f"{args.root}/slahmr/{args.split}/{out_name}/{seq}"
if args.seq_len > 0:
return f"{out_dir}/{start}-{end}"
if args.type == "posetrack" and shot_idx is not None:
return f"{out_dir}/shot-{shot_idx}"
return out_dir
def get_intrins_path(data_type, data_root, seq):
raise NotImplementedError
def get_command(img_dir, out_dir, start=0, end=-1, intrins_path=None, overwrite=False):
cmd_args = [
f"python {SRC_DIR}/run_slam.py",
"-i",
img_dir,
"--map_dir",
out_dir,
"--disable_vis",
]
if start != 0:
cmd_args += ["--start", str(start)]
if end != -1:
cmd_args += ["--end", str(end)]
if intrins_path is not None:
cmd_args += ["--intrins_path", intrins_path]
if overwrite:
cmd_args.append("--overwrite")
cmd = " ".join(cmd_args)
return cmd
def check_intrins(data_type, data_root, intrins_path, img_dir):
assert intrins_path is not None
out_name = intrins_path.split(data_root)[1].strip("/").split("/")[0]
out_root = f"{data_root}/{out_name}"
return intrins_path
def get_slam_command(args, img_dir, seq, shot_idx=None, start=0, end=-1):
out_dir = get_out_dir(args, seq, shot_idx, start, end)
intrins_path = None
if args.use_intrins:
intrins_path = get_intrins_path(args.type, args.root, seq)
if intrins_path is not None:
intrins_path = check_intrins(args.type, args.root, intrins_path, img_dir)
return get_command(
img_dir,
out_dir,
start=start,
end=end,
intrins_path=intrins_path,
overwrite=args.overwrite,
)
def launch_job(gpus, cmd):
cur_proc = mp.current_process()
print(cur_proc.name, cur_proc._identity)
worker_id = cur_proc._identity[0] - 1
gpu = gpus[worker_id % len(gpus)]
cmd = f"CUDA_VISIBLE_DEVICES={gpu} {cmd}"
print(cmd)
subprocess.call(cmd, shell=True)
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--type", default="posetrack", help="dataset to process")
parser.add_argument(
"--root", default=None, help="root of data to process, default None"
)
parser.add_argument(
"--split", default="val", help="split of dataset to process, default val"
)
parser.add_argument("--gpus", nargs="*", default=[0])
parser.add_argument("--seqs", nargs="*", default=None)
parser.add_argument("--seq_len", type=int, default=-1)
parser.add_argument(
"--use_intrins", action="store_true", help="use GT intrinsics if available"
)
parser.add_argument("-y", "--overwrite", action="store_true")
args = parser.parse_args()
args = update_args(args)
print(f"Running SLAM on {len(args.seqs)} sequences")
with futures.ProcessPoolExecutor(max_workers=len(args.gpus)) as ex:
for img_dir, seq in zip(args.img_dirs, args.seqs):
subseqs, shot_idcs = split_sequence(args, img_dir, seq)
for shot, (start, end) in zip(shot_idcs, subseqs):
cmd = get_slam_command(args, img_dir, seq, shot, start, end)
print(cmd)
ex.submit(launch_job, args.gpus, cmd)