Files
fn_registry/python/functions/datascience/depth_to_relief_glb.md
T
egutierrez 3cf8b21fea feat(datascience): promover remove_background al registry + mask en depth_to_relief_glb (grupo img-to-3d)
Completa la promoción del flujo imagen->3D al registry (grupo de capacidad
img-to-3d), extraído de la app img_to_3d_webapp.

- remove_background_py_datascience (nueva): elimina el fondo con cascada
  rembg/U2Net -> OpenCV GrabCut -> umbral NumPy, compone el objeto sobre gris
  neutro y devuelve image + mask + engine. Impura, nunca lanza. Adaptada de
  backend/bg_removal.py con firma de ruta (image_path) y salida dict, demo CLI
  JSON-serializable.
- depth_to_relief_glb_py_datascience (v1.1.0): añade el parámetro opcional mask
  para recortar la malla de relieve al objeto (descarta las caras del fondo),
  cerrando la cadena con remove_background. Aditivo (mask=None = comportamiento
  previo), fiel al original de backend/depth.py.
- docs/capabilities/img-to-3d.md: incorpora remove_background como paso 0
  (pre-proceso), actualiza el flujo a 3 pasos encadenados, la tabla de funciones
  (4), el ejemplo end-to-end con mask y las deps (rembg/opencv).
- docs/capabilities/INDEX.md: conteo del grupo 3 -> 4.

Las dos funciones ya presentes (estimate_image_depth, depth_to_relief_glb) y el
pipeline build_relief_glb_from_image fueron promovidas en una ronda previa.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 21:43:08 +02:00

6.0 KiB

name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, params, output, tested, tests, test_file_path, file_path
name kind lang domain version purity signature description tags uses_functions uses_types returns returns_optional error_type imports params output tested tests test_file_path file_path
depth_to_relief_glb function py datascience 1.1.0 impure def depth_to_relief_glb(image: Image.Image, depth: np.ndarray, out_glb_path: str, z_scale: float = 0.35, max_dim: int = 220, mask: np.ndarray | None = None) -> dict Construye una malla de relieve (heightmap) texturizada a partir de un mapa de profundidad + la imagen original y la exporta como glTF binario (.glb). El depth se vuelve el eje Z de un grid regular de vertices y la imagen se mapea como textura UV. Con mask opcional recorta la malla al objeto (descarta las caras del fondo). Paso 2 del flujo img->3D (grupo img-to-3d): consume la salida de estimate_image_depth y, opcionalmente, la mask de remove_background.
img-to-3d
datascience
mesh
glb
gltf
relief
heightmap
trimesh
3d
texture
false error_go_core
name desc
image PIL.Image RGB usada como textura de la malla. Tipicamente la 'image' devuelta por estimate_image_depth (la imagen original).
name desc
depth ndarray HxW float32 en [0,1] (1=mas cerca). Tipicamente el 'depth' devuelto por estimate_image_depth. Si ndim != 2 se devuelve status error.
name desc
out_glb_path Ruta de salida del .glb. El directorio padre debe existir (si no, la exportacion de trimesh falla -> status error).
name desc
z_scale Amplitud del relieve como fraccion del lado de la malla (default 0.35). Mayor = relieve mas pronunciado/exagerado.
name desc
max_dim Lado maximo del grid tras downsample bilineal (default 220, ~48k vertices / ~96k caras). Controla resolucion de la malla vs tamano del .glb. Imagenes mayores se reducen; menores se dejan igual.
name desc
mask Mascara opcional HxW (0..255, 255=objeto), tipicamente la 'mask' de remove_background. Si se pasa, se reescala al grid (NEAREST), el fondo se aplana a Z=0 y las caras cuyos tres vertices caen en el fondo se descartan: la malla queda recortada al objeto. None (default) = malla del frame completo (relieve incluido el fondo).
dict. Exito: {status:'ok', glb_path:str, vertices:int, faces:int, height:int, width:int}. Con mask, 'faces' es menor (solo caras del objeto); 'vertices' no cambia (el grid completo se conserva). Error: {status:'error', error:str} (depth con forma invalida, directorio de salida inexistente, fallo de trimesh.export). No lanza. false
python/functions/datascience/depth_to_relief_glb.py

Ejemplo

# Requiere un venv con torch + transformers + trimesh + pillow (el de apps/img_to_3d_webapp/backend/.venv).
# Import PLANO a los modulos (el paquete datascience.__init__ arrastra deps de otros dominios).
import sys
sys.path.insert(0, "python/functions/datascience")
from estimate_image_depth import estimate_image_depth
from depth_to_relief_glb import depth_to_relief_glb

est = estimate_image_depth("apps/img_to_3d_webapp/samples/cats.jpg")
assert est["status"] == "ok"

res = depth_to_relief_glb(est["image"], est["depth"], "/tmp/cats_relief.glb", z_scale=0.35, max_dim=220)
print(res["status"], res["vertices"], res["faces"])   # ok 48400 96114
print(res["glb_path"])                                 # /tmp/cats_relief.glb (cargable con useGLTF/GLTFLoader)

Lanzable end-to-end (el demo CLI encadena estimate_image_depth internamente):

./fn run depth_to_relief_glb_py_datascience apps/img_to_3d_webapp/samples/cats.jpg /tmp/cats_relief.glb
# {"status": "ok", "glb_path": "/tmp/cats_relief.glb", "vertices": ..., "faces": ..., ...}

Cuando usarla

Tras estimate_image_depth, cuando quieras un modelo 3D real (no solo el mapa de profundidad): visualizar una foto en relieve navegable, exportar a un visor web (three.js useGLTF/GLTFLoader, Babylon, model-viewer) o a cualquier herramienta que lea glTF. Es el paso 2 (final) del grupo img-to-3d. Usa max_dim para equilibrar detalle vs peso del .glb y z_scale para exagerar o suavizar el relieve.

Gotchas

  • Impura: escribe el archivo .glb en out_glb_path. El directorio padre debe existir o trimesh.export falla (vuelve como status error, no crash).
  • Dep: requiere trimesh (4.5.x) + pillow + numpy. trimesh se importa dentro de la funcion. No esta en el venv del registry; vive en el venv de la app img_to_3d_webapp.
  • No es reconstruccion real de geometria: es un heightmap (relieve 2.5D). Solo deforma un plano segun la profundidad; no recupera las caras ocultas ni el volumen trasero del objeto.
  • El downsample a max_dim usa interpolacion bilineal sobre el depth cuantizado a uint8 (0-255) para reescalar; introduce una ligera perdida de precision en la profundidad de la malla.
  • UV con V invertido (1 - v) por convencion glTF; la textura es la imagen convertida a RGB.
  • process=False en Trimesh: no se hace merge de vertices ni limpieza, para preservar la correspondencia 1:1 vertice<->pixel (necesaria para el mapeo UV del grid).
  • Import plano: importa el modulo directo, NO from datascience import ... (el __init__ del paquete arrastra deps de otros dominios ausentes en el venv de vision). Ver misma gotcha en estimate_image_depth.
  • mask opcional (v1.1.0): pasa la mask de remove_background para recortar la malla al objeto. Se reescala con NEAREST (sin interpolar, preserva el borde binario), el fondo se aplana a Z=0 y sus caras se eliminan. El nº de vertices no baja (el grid completo se conserva para no romper el mapeo UV 1:1); solo baja faces. Una mask degenerada (todo objeto) deja la malla intacta; una mask vacia (todo fondo) deja la malla sin caras (glb valido pero vacio).

Capability growth log

  • v1.1.0 (2026-06-21) — anade parametro opcional mask para recortar la malla al objeto (descarta las caras del fondo), cerrando la cadena con remove_background del grupo img-to-3d. Aditivo: mask=None mantiene el comportamiento previo. Fiel al original de backend/depth.py.