32c7336bf6
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
85 lines
4.7 KiB
Markdown
85 lines
4.7 KiB
Markdown
---
|
|
group: img-to-3d
|
|
description: "Convertir una imagen 2D en un modelo 3D: estimacion de profundidad monocular (Depth-Anything-V2) + reconstruccion de una malla de relieve texturizada exportada a glTF binario (.glb)."
|
|
---
|
|
|
|
# img-to-3d — Capability Group
|
|
|
|
Cluster de funciones Python (dominio `datascience`) para el flujo **imagen 2D → modelo 3D**. A
|
|
partir de una sola foto se estima un mapa de profundidad monocular con un modelo de vision y se
|
|
reconstruye una malla de relieve (heightmap) texturizada con la imagen original, exportada como
|
|
`.glb` cargable por cualquier visor glTF (three.js `useGLTF`/`GLTFLoader`, Babylon, model-viewer).
|
|
|
|
Promovido desde la app `img_to_3d_webapp` (su backend incrustaba estas dos funciones; ver su
|
|
`backend/depth.py`). El flujo canonico es de **dos pasos encadenados**:
|
|
|
|
```
|
|
estimate_image_depth (imagen -> depth+image) -> depth_to_relief_glb (depth+image -> .glb)
|
|
```
|
|
|
|
## Funciones
|
|
|
|
| ID | Firma corta | Que hace |
|
|
|---|---|---|
|
|
| `estimate_image_depth_py_datascience` | `estimate_image_depth(image_path, model_name?, device?, use_cache?) -> dict` | Estima profundidad monocular con Depth-Anything-V2 (GPU/CPU). Devuelve `depth` ndarray [0,1] + `image` PIL. Paso 1. |
|
|
| `depth_to_relief_glb_py_datascience` | `depth_to_relief_glb(image, depth, out_glb_path, z_scale?, max_dim?) -> dict` | Convierte `depth`+`image` en una malla de relieve texturizada y la exporta a `.glb`. Paso 2. |
|
|
| `build_relief_glb_from_image_py_pipelines` | `build_relief_glb_from_image(image_path, out_glb_path, model_name?, device?, z_scale?, max_dim?) -> dict` | **Pipeline one-shot**: compone los dos pasos en una sola llamada (imagen -> .glb). Salida JSON-serializable, apta para `fn run`. |
|
|
|
|
Las tres son **impuras** (cargan modelo / GPU / escriben archivo), devuelven `dict` con `status`
|
|
(`ok`/`error`) y **nunca lanzan**: los fallos vuelven como `{status:'error', error:str}`. El
|
|
pipeline ademas marca `stage` (`estimate`/`relief`) en el error.
|
|
|
|
## Ejemplo canonico (end-to-end imagen → glb)
|
|
|
|
```python
|
|
# Requiere un venv con torch + transformers + trimesh + pillow + numpy.
|
|
# Import PLANO: el paquete datascience.__init__ arrastra deps de otros dominios (bs4, duckdb...)
|
|
# ausentes en el venv de vision. Ver "Fronteras / gotchas".
|
|
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
|
|
|
|
IMG = "apps/img_to_3d_webapp/samples/cats.jpg"
|
|
OUT = "/tmp/cats_relief.glb"
|
|
|
|
est = estimate_image_depth(IMG) # device='auto' -> GPU si hay
|
|
assert est["status"] == "ok"
|
|
# est["depth"]: ndarray HxW float32 [0,1] (1=mas cerca) | est["image"]: PIL.Image RGB
|
|
|
|
res = depth_to_relief_glb(est["image"], est["depth"], OUT, z_scale=0.35, max_dim=220)
|
|
assert res["status"] == "ok"
|
|
print(res["glb_path"], res["vertices"], res["faces"]) # /tmp/cats_relief.glb 36300 71832
|
|
# OUT es un glTF binario valido: trimesh.load(OUT) devuelve una Scene texturizada.
|
|
```
|
|
|
|
O en una sola llamada con el pipeline (recomendado para fn run / Launcher TUI):
|
|
|
|
```bash
|
|
./fn run build_relief_glb_from_image_py_pipelines apps/img_to_3d_webapp/samples/cats.jpg /tmp/cats_relief.glb
|
|
# {"status": "ok", "glb_path": "/tmp/cats_relief.glb", "vertices": 36300, "faces": 71832, ...}
|
|
```
|
|
|
|
## Fronteras
|
|
|
|
- **Es relieve 2.5D, no reconstruccion volumetrica.** Deforma un plano segun la profundidad
|
|
(heightmap); no recupera caras ocultas ni el volumen trasero del objeto. Para 3D real
|
|
multivista/fotogrametria, NSP/Gaussian Splatting, esto NO aplica.
|
|
- **Profundidad relativa, no metrica.** Depth-Anything devuelve disparidad normalizada a [0,1];
|
|
no comparable entre imagenes ni en unidades del mundo real.
|
|
- **No cubre el render/visualizacion.** Producir el `.glb` es el limite del grupo. Cargarlo y
|
|
subirlo a GPU (OpenGL) en una app C++/ImGui es el grupo **`mesh-3d`** (`gltf_load_mesh_cpp_gfx`
|
|
carga justamente este tipo de `.glb`). img-to-3d **produce**; mesh-3d **consume/renderiza**.
|
|
- **Deps pesadas y de dos mundos.** Requiere `torch`+`transformers` (vision) y `trimesh` (mesh),
|
|
que hoy viven en el venv de `img_to_3d_webapp`, NO en el venv del registry. Ademas el
|
|
`datascience.__init__` arrastra deps de scrapers (`bs4`...) que no estan en el venv de vision,
|
|
por eso el import es **plano** (al modulo) y no via el paquete. `fn run` de estas funciones
|
|
exige un venv que combine ambos mundos (torch + transformers + trimesh + las deps del dominio
|
|
datascience). Ver gotchas en cada `.md`.
|
|
|
|
## Prerequisitos
|
|
|
|
- GPU NVIDIA + CUDA recomendada (corre en CPU pero lento). Primera ejecucion descarga los pesos
|
|
del modelo a `~/.cache/huggingface/` (cientos de MB segun la variante).
|
|
- Paquetes: `torch`, `transformers`, `trimesh`, `pillow`, `numpy`.
|