Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -373,18 +373,33 @@ def run_pipeline(files, objects_text, depth_model_id, erosion_px,
|
|
| 373 |
f"conf is None: {prediction.conf is None}; "
|
| 374 |
f"intrinsics is None: {prediction.intrinsics is None}")
|
| 375 |
|
| 376 |
-
|
|
|
|
|
|
|
|
|
|
| 377 |
|
| 378 |
# conf is a robustness aid, not a hard requirement -- degrade gracefully
|
| 379 |
# to uniform confidence (median+MAD outlier rejection still applies)
|
| 380 |
# rather than crashing if this build of DA3 doesn't return it.
|
| 381 |
if prediction.conf is not None:
|
| 382 |
-
conf = prediction.conf[0]
|
| 383 |
else:
|
| 384 |
gr.Warning("Depth confidence map was unavailable from this DA3 build — "
|
| 385 |
"falling back to uniform confidence (outlier rejection still applies).")
|
| 386 |
conf = np.ones_like(depth)
|
| 387 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 388 |
# Addition 2: prefer EXIF-derived intrinsics over DA3's estimated ones
|
| 389 |
# when available and requested — a known camera beats a network guess.
|
| 390 |
# Intrinsics are required for 3D back-projection; if DA3 didn't return
|
|
|
|
| 373 |
f"conf is None: {prediction.conf is None}; "
|
| 374 |
f"intrinsics is None: {prediction.intrinsics is None}")
|
| 375 |
|
| 376 |
+
def _to_numpy(t):
|
| 377 |
+
return t.cpu().numpy() if hasattr(t, "cpu") else np.asarray(t)
|
| 378 |
+
|
| 379 |
+
depth = np.squeeze(_to_numpy(prediction.depth[0])).astype(np.float32)
|
| 380 |
|
| 381 |
# conf is a robustness aid, not a hard requirement -- degrade gracefully
|
| 382 |
# to uniform confidence (median+MAD outlier rejection still applies)
|
| 383 |
# rather than crashing if this build of DA3 doesn't return it.
|
| 384 |
if prediction.conf is not None:
|
| 385 |
+
conf = np.squeeze(_to_numpy(prediction.conf[0])).astype(np.float32)
|
| 386 |
else:
|
| 387 |
gr.Warning("Depth confidence map was unavailable from this DA3 build — "
|
| 388 |
"falling back to uniform confidence (outlier rejection still applies).")
|
| 389 |
conf = np.ones_like(depth)
|
| 390 |
|
| 391 |
+
# DA3 internally resizes images before its forward pass (see the
|
| 392 |
+
# "Processed Images" log line), so depth/conf come back at that internal
|
| 393 |
+
# resolution -- not the original image's. Masks (from SAM3, via
|
| 394 |
+
# segment_batch's target_sizes=original_sizes) and intrinsics are both in
|
| 395 |
+
# original-image pixel space, so upsample depth/conf to match before
|
| 396 |
+
# indexing with the masks below (otherwise mask/depth shapes mismatch and
|
| 397 |
+
# boolean indexing raises IndexError).
|
| 398 |
+
target_w, target_h = primary_image.size
|
| 399 |
+
if depth.shape[:2] != (target_h, target_w):
|
| 400 |
+
depth = cv2.resize(depth, (target_w, target_h), interpolation=cv2.INTER_LINEAR)
|
| 401 |
+
conf = cv2.resize(conf, (target_w, target_h), interpolation=cv2.INTER_LINEAR)
|
| 402 |
+
|
| 403 |
# Addition 2: prefer EXIF-derived intrinsics over DA3's estimated ones
|
| 404 |
# when available and requested — a known camera beats a network guess.
|
| 405 |
# Intrinsics are required for 3D back-projection; if DA3 didn't return
|