3cf8b21fea
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>
5.8 KiB
5.8 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, source_file
| 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 | source_file | |||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| remove_background | function | py | datascience | 1.0.0 | impure | def remove_background(image_path: str, engine: str = 'auto') -> dict | Elimina el fondo de una imagen con cascada de motores (rembg/U2Net -> OpenCV GrabCut -> umbral NumPy), compone el objeto sobre fondo gris neutro y devuelve image+mask+engine. Paso de pre-proceso del flujo img->3D (grupo img-to-3d): su mask alimenta depth_to_relief_glb para recortar la malla de relieve al objeto. |
|
false | error_go_core |
|
dict. Exito: {status:'ok', image: PIL.Image RGB del objeto compuesto sobre fondo gris neutro (127,127,127), mask: ndarray HxW uint8 (0..255, 255=objeto), engine: str del motor usado ('rembg:u2net' | 'opencv:grabcut' | 'threshold:border' | 'passthrough:alpha'), height:int, width:int, fg_fraction: float (fraccion de pixeles objeto, redondeada a 4 decimales)}. Error: {status:'error', error:str} (ruta invalida, motor desconocido, motor forzado no disponible/fallido, o ningun motor produjo una mascara valida). No lanza nunca. El demo CLI (__main__) imprime un resumen JSON sin el ndarray ni la imagen y, si se pasa out_dir, guarda rgb.png + mask.png. | false | python/functions/datascience/remove_background.py | apps/img_to_3d_webapp/backend/bg_removal.py |
Ejemplo
# Requiere un venv con pillow + numpy (rembg/opencv solo si fuerzas esos motores; el umbral es NumPy puro).
# Import PLANO al modulo: el paquete datascience.__init__ arrastra deps de otros dominios
# (bs4, duckdb...) que no estan en ese venv. Ver Gotchas.
import sys
sys.path.insert(0, "python/functions/datascience")
from remove_background import remove_background
res = remove_background("apps/img_to_3d_webapp/samples/cats.jpg", engine="auto")
assert res["status"] == "ok"
print(res["engine"]) # p.ej. "rembg:u2net" (o "opencv:grabcut" / "threshold:border")
print(res["height"], res["width"]) # p.ej. 1024 768
print(res["mask"].shape, res["mask"].dtype) # (1024, 768) uint8 (255=objeto)
assert 0.0 < res["fg_fraction"] < 1.0
# res["mask"] (ndarray HxW uint8) alimenta depth_to_relief_glb para recortar la malla al objeto.
# res["image"] es el objeto compuesto sobre gris neutro, listo para estimar profundidad.
Lanzable como demo (imprime resumen JSON, sin serializar el ndarray; guarda PNGs si das out_dir):
./fn run remove_background_py_datascience apps/img_to_3d_webapp/samples/cats.jpg auto /tmp/cut
# {"status": "ok", "engine": "rembg:u2net", "height": 1024, "width": 768,
# "fg_fraction": 0.4123, "rgb_path": "/tmp/cut/rgb.png", "mask_path": "/tmp/cut/mask.png"}
Cuando usarla
Como pre-proceso ANTES de estimar profundidad en el flujo img->3D: aislar el objeto evita que el
modelo de profundidad estire el fondo plano, y la mask permite recortar la malla de relieve al
objeto (se pasa a depth_to_relief_glb). Tambien para segmentacion de primer plano generica
cuando necesitas separar un objeto de su fondo y componerlo sobre un color neutro (recortes para
catalogos, datasets, miniaturas).
Gotchas
- Impura: segun el motor carga modelos neuronales y lee disco.
rembg/onnxruntime(~170MB) DESCARGA el modelo U2Net la primera vez a su cache (~/.u2net/), requiere red en esa primera carga;opencv-pythonpara GrabCut; el umbral (threshold:border) es NumPy puro sin deps externas. - Estado de proceso:
_REMBG_SESSIONcachea la sesion rembg a nivel de modulo para no recargar los pesos en cada llamada. Es estado mutable compartido del proceso y ocupa RAM hasta que el interprete muere. - engine='auto' nunca lanza: prueba rembg -> grabcut -> threshold y siempre cae al umbral NumPy puro si los anteriores no estan disponibles o fallan. Forzar un motor concreto SI puede devolver status error (motor no instalado, fallo, o mascara degenerada).
- Mascara degenerada: si la fraccion de objeto resulta
< 0.01o> 0.995la mascara se descarta (casi todo fondo o casi todo objeto) y en modo auto se prueba el siguiente motor. - threshold:border es de baja calidad: asume objeto centrado con los bordes de la imagen siendo fondo (calcula la distancia al color medio de los bordes). Es el fallback de ultimo recurso.
- passthrough:alpha: si la imagen ya viene recortada (PNG RGBA con alfa por debajo de 128) se reutiliza su canal alfa como mascara, SOLO en modo auto. Si fuerzas un motor concreto se respeta esa eleccion e ignora el alfa existente.
- Import plano: importa el modulo directo (
sys.pathapython/functions/datascience+from remove_background import remove_background), NOfrom datascience import .... Eldatascience.__init__carga todo el dominio (scrapers con bs4, duckdb...) con deps ajenas a esta funcion que romperian el import del paquete en el venv de vision. - Nunca lanza: errores (ruta invalida, motor forzado no disponible, OOM) vuelven como
{status:'error', error:str}.