reorder
This commit is contained in:
71
tour-comfy/orbit_qwen_poc.py
Normal file
71
tour-comfy/orbit_qwen_poc.py
Normal file
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
orbit_qwen_poc.py — near-real turntable test via Qwen-Image-Edit.
|
||||
|
||||
python orbit_qwen_poc.py --input front.png --output ./out \
|
||||
--views 12 --mode turntable --interp 4 --seed 42
|
||||
|
||||
Generates one re-rendered view per yaw angle (anchored to the input, fixed seed),
|
||||
flow-interpolates for smoothness, and stitches a looping MP4.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
_HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
if _HERE not in sys.path:
|
||||
sys.path.insert(0, _HERE)
|
||||
|
||||
from orbit_qwen import run_qwen_orbit
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser(description="Qwen turntable (near-real subject turning).")
|
||||
ap.add_argument("--input", "-i", required=True, help="Front-facing source image")
|
||||
ap.add_argument("--output", "-o", default="./out_turntable", help="Output directory")
|
||||
ap.add_argument("--views", "-v", type=int, default=24, help="Qwen keyframes (yaw steps)")
|
||||
ap.add_argument("--mode", "-m", choices=["turntable", "swing"], default="turntable",
|
||||
help="turntable=full 360 loop, swing=front-facing arc only")
|
||||
ap.add_argument("--sweep", type=float, default=180.0, help="swing arc width in degrees")
|
||||
ap.add_argument("--anchor", choices=["original", "chain"], default="original",
|
||||
help="original=each view from source (stable), chain=from previous (smoother)")
|
||||
ap.add_argument("--interp", type=int, default=1,
|
||||
help="interpolated frames per keyframe gap (1=none; >1 ghosts, not advised)")
|
||||
ap.add_argument("--no-smooth", action="store_true", help="crossfade instead of optical-flow morph")
|
||||
ap.add_argument("--fps", type=int, default=12)
|
||||
ap.add_argument("--seed", type=int, default=42)
|
||||
ap.add_argument("--steps", type=int, default=8, help="Qwen sampler steps (4 fast, 8 nicer)")
|
||||
ap.add_argument("--max-area", type=int, default=0, help="output pixel budget (0=API default)")
|
||||
args = ap.parse_args()
|
||||
|
||||
if not os.path.exists(args.input):
|
||||
print(f"[error] input not found: {args.input}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
def prog(i, n, deg):
|
||||
print(f" [{i+1}/{n}] rendering {int(deg):3d}°…", flush=True)
|
||||
|
||||
print(f"[turntable] input : {args.input}")
|
||||
print(f"[turntable] mode={args.mode} views={args.views} anchor={args.anchor} "
|
||||
f"interp×{args.interp} seed={args.seed} steps={args.steps}")
|
||||
|
||||
t0 = time.perf_counter()
|
||||
res = run_qwen_orbit(
|
||||
image_path=args.input, output_dir=args.output,
|
||||
n_views=args.views, seed=args.seed, mode=args.mode, sweep_deg=args.sweep,
|
||||
anchor=args.anchor, interp_factor=args.interp, smooth=not args.no_smooth,
|
||||
fps=args.fps, max_area=args.max_area, steps=args.steps, on_progress=prog,
|
||||
)
|
||||
dt = time.perf_counter() - t0
|
||||
|
||||
print(f"\n[turntable] done in {dt:.1f}s "
|
||||
f"({dt/max(1,res['n_views']):.1f}s/view)")
|
||||
print(f" keyframes : {res['n_views']} → {res['views_dir']}")
|
||||
print(f" frames : {res['n_frames']} (after interpolation)")
|
||||
print(f" video : {res['video_path']}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user