Spaces:
Sleeping
Sleeping
| import os | |
| def reconstruct(files: List[gr.File], max_img_size: int, threads: int) -> Tuple[str, str, str]: | |
| """Main entry for Gradio. Returns (obj_path, obj_download, ply_download).""" | |
| ts = time.strftime("%Y%m%d_%H%M%S") | |
| run_dir = RUNS_DIR / f"run_{ts}" | |
| img_dir = run_dir / "images" | |
| run_dir.mkdir(parents=True, exist_ok=True) | |
| paths = [Path(f.name) for f in files] | |
| _save_images_to(img_dir, paths, int(max_img_size)) | |
| fused = _colmap_pipeline(img_dir, run_dir, num_threads=int(threads)) | |
| obj = _poisson_mesh_from_ply(fused) | |
| logs = run_dir / "logs.txt" | |
| if logs.exists(): | |
| shutil.copy2(logs, OUT_DIR / f"logs_{ts}.txt") | |
| fused_out = OUT_DIR / f"fused_{ts}.ply" | |
| shutil.copy2(fused, fused_out) | |
| return str(obj), str(obj), str(fused_out) | |
| def ui(): | |
| with gr.Blocks(title="Sparse2City3D: Urban massing from few photos") as demo: | |
| gr.Markdown( | |
| """ | |
| # Sparse2City3D | |
| Upload 5–30 photos of a street/building. The app runs **COLMAP** to reconstruct a dense point cloud and converts it into a coarse **OBJ** mesh for urban‑planning massing. | |
| """ | |
| ) | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| files = gr.Files(label="Upload images", file_types=["image"], file_count="multiple") | |
| max_size = gr.Slider(800, 3200, value=2000, step=100, label="Max image size (px)") | |
| threads = gr.Slider(1, 8, value=4, step=1, label="# CPU threads") | |
| run_btn = gr.Button("Reconstruct 3D", variant="primary") | |
| with gr.Column(scale=3): | |
| model3d = gr.Model3D(label="3D preview (OBJ)") | |
| dl_mesh = gr.File(label="Download mesh (OBJ)") | |
| dl_ply = gr.File(label="Download point cloud (PLY)") | |
| def _wrap(files, max_size, threads): | |
| if not files: | |
| raise gr.Error("Please upload at least 5 images.") | |
| obj, obj_dl, ply_dl = reconstruct(files, int(max_size), int(threads)) | |
| return obj, obj_dl, ply_dl | |
| run_btn.click(_wrap, inputs=[files, max_size, threads], outputs=[model3d, dl_mesh, dl_ply]) | |
| return demo | |
| if __name__ == "__main__": | |
| demo = ui() | |
| demo.launch() | |