kuai / generative-models /scripts /sampling /collect_results.py
Larer's picture
Add files using upload-large-folder tool
3c3a938
"""
Collect and visualize SV4D batch results.
For each sample, concatenate the 4 novel-view videos into a 2x2 grid,
and save all grids to a single folder for easy browsing.
Usage:
python scripts/sampling/collect_results.py
"""
import os
import argparse
import numpy as np
import imageio
from PIL import Image
INPUT_DIR = "./outputs/outputs_4d"
OUTPUT_DIR = "./outputs/gallery"
def make_grid(frames_list, nrow=2):
"""
frames_list: list of N lists, each containing T frames (H, W, 3).
Returns: list of T grid frames.
"""
n_views = len(frames_list)
n_frames = min(len(f) for f in frames_list)
h, w = frames_list[0][0].shape[:2]
ncol = (n_views + nrow - 1) // nrow
grids = []
for t in range(n_frames):
canvas = np.full((h * nrow, w * ncol, 3), 255, dtype=np.uint8)
for idx in range(n_views):
r, c = divmod(idx, ncol)
canvas[r * h : (r + 1) * h, c * w : (c + 1) * w] = frames_list[idx][t]
grids.append(canvas)
return grids
def find_view_videos(directory):
"""Find novel-view mp4s (_v0XX.mp4) in a directory, handling both SV4D and SV4D2."""
view_files = []
for f in sorted(os.listdir(directory)):
if not f.endswith(".mp4"):
continue
if "_v0" in f and "_v000" not in f:
view_files.append(os.path.join(directory, f))
return view_files
def process_one(sample_dir, output_dir):
for sub in ["sv4d2", "sv4d", ""]:
search_dir = os.path.join(sample_dir, sub) if sub else sample_dir
if not os.path.isdir(search_dir):
continue
view_files = find_view_videos(search_dir)
if view_files:
break
else:
return False
if not view_files:
return False
all_views = []
for vf in view_files:
frames = [np.array(f) for f in imageio.mimread(vf)]
all_views.append(frames)
grid_frames = make_grid(all_views, nrow=2)
name = os.path.basename(sample_dir)
out_path = os.path.join(output_dir, f"{name}.mp4")
imageio.mimwrite(out_path, grid_frames, fps=4)
return True
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--input_dir", default=INPUT_DIR)
parser.add_argument("--output_dir", default=OUTPUT_DIR)
args = parser.parse_args()
os.makedirs(args.output_dir, exist_ok=True)
samples = sorted([
os.path.join(args.input_dir, d)
for d in os.listdir(args.input_dir)
if os.path.isdir(os.path.join(args.input_dir, d))
])
done = 0
for s in samples:
name = os.path.basename(s)
ok = process_one(s, args.output_dir)
if ok:
done += 1
print(f"[{done}/{len(samples)}] {name}")
else:
print(f"[skip] {name} (no view videos found)")
print(f"\nDone! {done} grid videos saved to {args.output_dir}")
if __name__ == "__main__":
main()