ZayarnyukNick's picture
Upload folder using huggingface_hub
864ebc9 verified
#!/usr/bin/env python3
# Copyright (C) 2024-present Naver Corporation. All rights reserved.
# Licensed under CC BY-NC-SA 4.0 (non-commercial use only).
#
# --------------------------------------------------------
# Preprocessing code for the StaticThings3D dataset
# dataset at https://github.com/lmb-freiburg/robustmvd/blob/master/rmvd/data/README.md#staticthings3d
# 1) Download StaticThings3D in /path/to/StaticThings3D/
# with the script at https://github.com/lmb-freiburg/robustmvd/blob/master/rmvd/data/scripts/download_staticthings3d.sh
# --> depths.tar.bz2 frames_finalpass.tar.bz2 poses.tar.bz2 frames_cleanpass.tar.bz2 intrinsics.tar.bz2
# 2) unzip everything in the same /path/to/StaticThings3D/ directory
# 5) python datasets_preprocess/preprocess_staticthings3d.py --StaticThings3D_dir /path/to/tmp/StaticThings3D/
# --------------------------------------------------------
import os
import os.path as osp
import re
import numpy as np
from tqdm import tqdm
os.environ["OPENCV_IO_ENABLE_OPENEXR"] = "1"
import cv2
import path_to_root # noqa
from dust3r.datasets.utils import cropping # noqa
from dust3r.utils.parallel import parallel_threads
def get_parser():
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--StaticThings3D_dir", required=True)
parser.add_argument("--precomputed_pairs", required=True)
parser.add_argument("--output_dir", default="data/staticthings3d_processed")
return parser
def main(db_root, pairs_path, output_dir):
all_scenes = _list_all_scenes(db_root)
# crop images
args = [
(db_root, osp.join(split, subsplit, seq), camera, f"{n:04d}", output_dir)
for split, subsplit, seq in all_scenes
for camera in ["left", "right"]
for n in range(6, 16)
]
parallel_threads(load_crop_and_save, args, star_args=True, front_num=1)
# verify that all images are there
CAM = {b"l": "left", b"r": "right"}
pairs = np.load(pairs_path)
for scene, seq, cam1, im1, cam2, im2 in tqdm(pairs):
seq_path = osp.join("TRAIN", scene.decode("ascii"), f"{seq:04d}")
for cam, idx in [(CAM[cam1], im1), (CAM[cam2], im2)]:
for ext in ["clean", "final"]:
impath = osp.join(output_dir, seq_path, cam, f"{idx:04n}_{ext}.jpg")
assert osp.isfile(impath), f"missing an image at {impath=}"
print(f">> Saved all data to {output_dir}!")
def load_crop_and_save(db_root, relpath_, camera, num, out_dir):
relpath = osp.join(relpath_, camera, num)
if osp.isfile(osp.join(out_dir, relpath + ".npz")):
return
os.makedirs(osp.join(out_dir, relpath_, camera), exist_ok=True)
# load everything
intrinsics_in = readFloat(
osp.join(db_root, "intrinsics", relpath_, num + ".float3")
)
cam2world = np.linalg.inv(
readFloat(osp.join(db_root, "poses", relpath + ".float3"))
)
depthmap_in = readFloat(osp.join(db_root, "depths", relpath + ".float3"))
img_clean = cv2.cvtColor(
cv2.imread(
osp.join(db_root, "frames_cleanpass", relpath + ".png"), cv2.IMREAD_COLOR
),
cv2.COLOR_BGR2RGB,
)
img_final = cv2.cvtColor(
cv2.imread(
osp.join(db_root, "frames_finalpass", relpath + ".png"), cv2.IMREAD_COLOR
),
cv2.COLOR_BGR2RGB,
)
# do the crop
assert img_clean.shape[:2] == (540, 960)
assert img_final.shape[:2] == (540, 960)
(clean_out, final_out), depthmap, intrinsics_out, R_in2out = _crop_image(
intrinsics_in, (img_clean, img_final), depthmap_in, (512, 384)
)
# write everything
clean_out.save(osp.join(out_dir, relpath + "_clean.jpg"), quality=80)
final_out.save(osp.join(out_dir, relpath + "_final.jpg"), quality=80)
cv2.imwrite(osp.join(out_dir, relpath + ".exr"), depthmap)
# New camera parameters
cam2world[:3, :3] = cam2world[:3, :3] @ R_in2out.T
np.savez(
osp.join(out_dir, relpath + ".npz"),
intrinsics=intrinsics_out,
cam2world=cam2world,
)
def _crop_image(intrinsics_in, color_image_in, depthmap_in, resolution_out=(512, 512)):
image, depthmap, intrinsics_out = cropping.rescale_image_depthmap(
color_image_in, depthmap_in, intrinsics_in, resolution_out
)
R_in2out = np.eye(3)
return image, depthmap, intrinsics_out, R_in2out
def _list_all_scenes(path):
print(">> Listing all scenes")
res = []
for split in ["TRAIN"]:
for subsplit in "ABC":
for seq in os.listdir(osp.join(path, "intrinsics", split, subsplit)):
res.append((split, subsplit, seq))
print(f" (found ({len(res)}) scenes)")
assert res, f"Did not find anything at {path=}"
return res
def readFloat(name):
with open(name, "rb") as f:
if (f.readline().decode("utf-8")) != "float\n":
raise Exception("float file %s did not contain <float> keyword" % name)
dim = int(f.readline())
dims = []
count = 1
for i in range(0, dim):
d = int(f.readline())
dims.append(d)
count *= d
dims = list(reversed(dims))
data = np.fromfile(f, np.float32, count).reshape(dims)
return data # Hxw or CxHxW NxCxHxW
if __name__ == "__main__":
parser = get_parser()
args = parser.parse_args()
main(args.StaticThings3D_dir, args.precomputed_pairs, args.output_dir)