jboth commited on
Commit
236a930
·
verified ·
1 Parent(s): d66f250

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +92 -0
app.py CHANGED
@@ -266,6 +266,87 @@ def reconstruct_objects(image: np.ndarray):
266
  print(tb)
267
  return None, None, f"Error:\n{tb[-1500:]}"
268
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
  # --- UI ---
270
  with gr.Blocks(title="SAM 3D Objects") as demo:
271
  gr.Markdown("# SAM 3D Objects\nImage → 3D (GLB). SAM2 detection + SAM3D reconstruction.")
@@ -282,6 +363,17 @@ with gr.Blocks(title="SAM 3D Objects") as demo:
282
  dl = gr.File(label="Download GLB")
283
  btn.click(reconstruct_objects, inputs=[inp], outputs=[m3d, prev, stat])
284
  m3d.change(lambda x: x, inputs=[m3d], outputs=[dl])
 
 
 
 
 
 
 
 
 
 
 
285
  with gr.Tab("Diagnose"):
286
  dbtn = gr.Button("Diagnose GPU & Modules")
287
  dout = gr.Textbox(lines=15)
 
266
  print(tb)
267
  return None, None, f"Error:\n{tb[-1500:]}"
268
 
269
+
270
+ @spaces.GPU(duration=240)
271
+ def test_sam3d_only(image: np.ndarray):
272
+ """Test SAM3D reconstruction with center-crop mask (no SAM2)."""
273
+ if image is None:
274
+ return None, None, "No image"
275
+ try:
276
+ import torch, time, gc
277
+ t0 = time.time()
278
+ print(f"GPU: {torch.cuda.get_device_name()}, VRAM: {torch.cuda.memory_allocated()/1e9:.1f}GB")
279
+
280
+ image_np = np.array(image) if not isinstance(image, np.ndarray) else image
281
+ h, w = image_np.shape[:2]
282
+
283
+ # Create a center mask (middle 60% of image)
284
+ mask = np.zeros((h, w), dtype=bool)
285
+ y1, y2 = int(h * 0.2), int(h * 0.8)
286
+ x1, x2 = int(w * 0.2), int(w * 0.8)
287
+ mask[y1:y2, x1:x2] = True
288
+
289
+ preview = image_np.copy()
290
+ preview[mask] = (preview[mask] * 0.5 + np.array([0, 255, 0]) * 0.5).astype(np.uint8)
291
+ print(f" Mask created: {mask.sum()} pixels ({time.time()-t0:.0f}s)")
292
+
293
+ from inference import Inference
294
+ print(f" Loading SAM3D... VRAM: {torch.cuda.memory_allocated()/1e9:.1f}GB")
295
+ sam3d = Inference(CONFIG_PATH, compile=False)
296
+ print(f" SAM3D loaded ({time.time()-t0:.0f}s, VRAM: {torch.cuda.memory_allocated()/1e9:.1f}GB)")
297
+
298
+ print(f" Running reconstruction...")
299
+ result = sam3d(image=image_np, mask=mask, seed=42)
300
+ print(f" Done ({time.time()-t0:.0f}s, VRAM: {torch.cuda.memory_allocated()/1e9:.1f}GB)")
301
+
302
+ if result is None:
303
+ return None, preview, "Reconstruction returned None"
304
+
305
+ import tempfile
306
+ od = tempfile.mkdtemp()
307
+ glb = f"{od}/object.glb"
308
+
309
+ gs = None
310
+ if isinstance(result, dict):
311
+ for k in ("gs", "gaussian", "gaussians", "scene"):
312
+ v = result.get(k)
313
+ if v is not None:
314
+ gs = v[0] if isinstance(v, (list, tuple)) else v
315
+ break
316
+
317
+ if gs is not None and hasattr(gs, "save_ply"):
318
+ ply = f"{od}/temp.ply"
319
+ gs.save_ply(ply)
320
+ import open3d as o3d
321
+ pcd = o3d.io.read_point_cloud(ply)
322
+ pcd.estimate_normals()
323
+ mesh, _ = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(pcd, depth=8)
324
+ o3d.io.write_triangle_mesh(glb, mesh)
325
+ elif gs is not None and hasattr(gs, "_xyz"):
326
+ import open3d as o3d
327
+ pcd = o3d.geometry.PointCloud()
328
+ pcd.points = o3d.utility.Vector3dVector(gs._xyz.detach().cpu().numpy())
329
+ pcd.estimate_normals()
330
+ mesh, _ = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(pcd, depth=8)
331
+ o3d.io.write_triangle_mesh(glb, mesh)
332
+ else:
333
+ keys = list(result.keys()) if isinstance(result, dict) else dir(result)
334
+ return None, preview, f"Cannot extract 3D. Keys: {keys}"
335
+
336
+ import trimesh
337
+ n = 0
338
+ try:
339
+ n = len(trimesh.load(glb, force="mesh").faces)
340
+ except: pass
341
+ elapsed = int(time.time() - t0)
342
+ return glb, preview, f"OK: {n:,} faces ({elapsed}s)"
343
+ except Exception as e:
344
+ import traceback
345
+ tb = traceback.format_exc()
346
+ print(tb)
347
+ return None, None, f"Error:\n{tb[-1500:]}"
348
+
349
+
350
  # --- UI ---
351
  with gr.Blocks(title="SAM 3D Objects") as demo:
352
  gr.Markdown("# SAM 3D Objects\nImage → 3D (GLB). SAM2 detection + SAM3D reconstruction.")
 
363
  dl = gr.File(label="Download GLB")
364
  btn.click(reconstruct_objects, inputs=[inp], outputs=[m3d, prev, stat])
365
  m3d.change(lambda x: x, inputs=[m3d], outputs=[dl])
366
+ with gr.Tab("Test SAM3D Only"):
367
+ with gr.Row():
368
+ with gr.Column():
369
+ tinp = gr.Image(label="Input", type="numpy")
370
+ tbtn = gr.Button("Test SAM3D (no SAM2)", variant="primary")
371
+ with gr.Column():
372
+ tprev = gr.Image(label="Mask Preview", type="numpy", interactive=False)
373
+ tstat = gr.Textbox(label="Status")
374
+ with gr.Row():
375
+ tm3d = gr.Model3D(label="3D Preview")
376
+ tbtn.click(test_sam3d_only, inputs=[tinp], outputs=[tm3d, tprev, tstat])
377
  with gr.Tab("Diagnose"):
378
  dbtn = gr.Button("Diagnose GPU & Modules")
379
  dout = gr.Textbox(lines=15)