This commit is contained in:
mike
2026-06-27 00:45:45 +02:00
parent 7eb544211e
commit 36a244cab4
29 changed files with 0 additions and 0 deletions

View 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()