Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
230 changes: 230 additions & 0 deletions README.es-ES.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@


# _vision_.cpp

Inferencia de IA/ML para Visión por Computador en C++

* Biblioteca C++ autocontenida
* Inferencia eficiente en CPUs y GPUs de consumo (NVIDIA, AMD, Intel)
* Despliegue ligero en múltiples plataformas (Windows, Linux, MacOS)
* Número creciente de modelos compatibles detrás de una API simple
* Diseño modular para control total e implementar tus propios modelos

Basado en [ggml](https://github.com/ggml-org/ggml) similar al proyecto [llama.cpp](https://github.com/ggml-org/llama.cpp).

### Características

| Modelo | Tarea | Backends |
| :--------------------------------------- | :----------------------- | :---------- |
| [**MobileSAM**](#mobilesam) | Segmentación con prompts | CPU, Vulkan |
| [**BiRefNet**](#birefnet) | Segmentación dicotómica | CPU, Vulkan |
| [**Depth-Anything**](#depth-anything-v2) | Estimación de profundidad | CPU, Vulkan |
| [**MI-GAN**](#mi-gan) | Inpainting | CPU, Vulkan |
| [**ESRGAN**](#real-esrgan) | Super-resolución | CPU, Vulkan |
| [_Implementar un modelo [**Guía**]_](docs/model-implementation-guide.md) | | |

**Backbones:** SWIN (v1), DINO (v2), TinyViT

## Primeros pasos

Obtén la biblioteca y los ejecutables:
* Descarga un [paquete de lanzamiento](https://github.com/Acly/vision.cpp/releases) y extráelo,
* o [compílalo desde el código fuente](#building).

### Ejemplo: Seleccionar un objeto en una imagen

Utilicemos MobileSAM para generar una máscara de segmentación del peluche a la derecha, pasando un recuadro que describa su ubicación aproximada.

<img width="400" height="256" alt="Example image showing box prompt at pixel location (420, 120) - (650, 430), and the output mask" src="https://github.com/user-attachments/assets/0b90ad96-c7d2-4c4c-b028-699433cef704" />

Puedes descargar el modelo y la imagen de entrada aquí: [MobileSAM-F16.gguf](https://huggingface.co/Acly/MobileSAM-GGUF/resolve/main/MobileSAM-F16.gguf) | [input.jpg](docs/media/input.jpg)


#### CLI

Busca el ejecutable `vision-cli` en la carpeta `bin` y ejecútalo para generar la máscara:

```sh
vision-cli -m MobileSAM-F16.gguf -i input.jpg -p 420 120 650 430 -o mask.png
```
Para combinar la entrada y la máscara, pasa `--composite output.png`. Usa `--help` para ver más opciones.

#### API

```c++
#include <visp/vision.h>
using namespace visp;

void main() {
backend_device cpu = backend_init(backend_type::cpu);
sam_model sam = sam_load_model("MobileSAM-F16.gguf", cpu);

image_data input_image = image_load("input.jpg");
sam_encode(sam, input_image);

image_data object_mask = sam_compute(sam, box_2d{{420, 120}, {650, 320}});
image_save(object_mask, "mask.png");
}
```
Esto muestra la API de alto nivel. Internamente, está compuesta por múltiples funciones más pequeñas que manejan la carga del modelo, el preprocesamiento de entradas, la transferencia de datos a los dispositivos backend, el postprocesamiento de la salida, etc. Estas pueden usarse como bloques de construcción para funciones flexibles que se integren con tus fuentes de datos e infraestructura existentes.



## Modelos

#### MobileSAM

<img width="400" height="256" alt="example-sam" src="https://github.com/user-attachments/assets/9c0fe151-9990-4bb1-b954-7caff560b110" />

[Descarga del modelo](https://huggingface.co/Acly/MobileSAM-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/pdf/2306.14289.pdf) | [Repositorio (GitHub)](https://github.com/ChaoningZhang/MobileSAM) | [Segment-Anything-Model](https://segment-anything.com/) | Licencia: Apache-2

```sh
vision-cli sam -m MobileSAM-F16.gguf -i input.png -p 300 200 -o mask.png --composite comp.png
```

#### BiRefNet

<img width="400" height="256" alt="example-birefnet" src="https://github.com/user-attachments/assets/6fce086d-cb89-4717-92a6-9f4a20532b3c" />

[Descarga del modelo](https://huggingface.co/Acly/BiRefNet-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/pdf/2401.03407) | [Repositorio (GitHub)](https://github.com/ZhengPeng7/BiRefNet) | Licencia: MIT

```sh
vision-cli birefnet -m BiRefNet-lite-F16.gguf -i input.png -o mask.png --composite comp.png
```

#### Depth-Anything V2

<img width="400" height="256" alt="example-depth-anything" src="https://github.com/user-attachments/assets/62bde481-b898-4c46-a298-644198716953" />

[Descarga del modelo](https://huggingface.co/Acly/Depth-Anything-V2-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/abs/2406.09414) | [Repositorio (GitHub)](https://github.com/DepthAnything/Depth-Anything-V2) | Licencia: Apache-2 / CC-BY-NC-4

```sh
vision-cli depth-anything -m Depth-Anything-V2-Small-F16.gguf -i input.png -o depth.png
```

#### MI-GAN

<img width="400" height="256" alt="example-migan" src="https://github.com/user-attachments/assets/cadf1994-7677-4822-94e5-a2ee6c07621f" />

[Descarga del modelo](https://huggingface.co/Acly/MIGAN-GGUF/tree/main) | [Artículo (thecvf.com)](https://openaccess.thecvf.com/content/ICCV2023/papers/Sargsyan_MI-GAN_A_Simple_Baseline_for_Image_Inpainting_on_Mobile_Devices_ICCV_2023_paper.pdf) | [Repositorio (GitHub)](https://github.com/Picsart-AI-Research/MI-GAN) | Licencia: MIT

```sh
vision-cli migan -m MIGAN-512-places2-F16.gguf -i image.png mask.png -o output.png
```

#### Real-ESRGAN

<img width="400" height="256" alt="example-esrgan" src="https://github.com/user-attachments/assets/a41312d6-836c-4b11-ab5d-2e299ffee10c" />

[Descarga del modelo](https://huggingface.co/Acly/Real-ESRGAN-GGUF) | [Artículo (arXiv)](https://arxiv.org/abs/2107.10833) | [Repositorio (GitHub)](https://github.com/xinntao/Real-ESRGAN) | Licencia: BSD-3-Clause

```sh
vision-cli esrgan -m ESRGAN-4x-foolhardy_Remacri-F16.gguf -i input.png -o output.png
```


### Conversión de modelos

Los modelos deben convertirse a GGUF antes de poder usarse. Esto también reorganizará o precomputará tensores para una inferencia más óptima.

Para convertir un modelo, instala [uv](https://docs.astral.sh/uv/) y ejecuta:
```sh
uv run scripts/convert.py <arch> MyModel.pth
```
donde `<arch>` es uno de `sam, birefnet, esrgan, ...`.

Esto creará `models/MyModel.gguf`. Consulta `convert.py --help` para ver más opciones.

## Compilación

La compilación requiere CMake y un compilador con soporte para C++20.

**Obtener el código fuente**
```sh
git clone https://github.com/Acly/vision.cpp.git --recursive
cd vision.cpp
```

**Configurar y compilar**
```sh
cmake . -B build
cmake --build build --config Release
```

### Vulkan _(Opcional)_

Compilar con soporte para GPU Vulkan requiere que esté instalado el [Vulkan SDK](https://www.lunarg.com/vulkan-sdk/).

```sh
cmake . -B build -D VISP_VULKAN=ON
```

### Pruebas _(Opcional)_

Compila con `-DVISP_TESTS=ON`. Ejecuta todas las pruebas de C++ con el siguiente comando:
```sh
cd build
ctest -C Release
```

Algunas pruebas requieren un entorno de Python. Puede configurarse con [uv](https://docs.astral.sh/uv/):
```sh
# Setup venv and install dependencies (once only)
uv sync --dev

# Run python tests
uv run pytest
```

## Rendimiento

La optimización del rendimiento es un proceso continuo. El objetivo es estar en el mismo rango que otros frameworks en velocidad de inferencia, pero con:
* tiempos de inicialización y carga de modelos mucho más rápidos (<100 ms)
* menor sobrecarga de memoria
* tamaño de despliegue mínimo (<5 MB para CPU, +30 MB para GPU)

### Velocidad de inferencia

* CPU: AMD Ryzen 5 5600X (6 núcleos)
* GPU: NVIDIA GeForce RTX 4070

#### MobileSAM, 1024x1024

| | | _vision.cpp_ | PyTorch | ONNX Runtime |
| :--- | :--- | -----------: | ------: | -----------: |
| cpu | f32 | 669 ms | 601 ms | 805 ms |
| gpu | f16 | 19 ms | 16 ms | |

#### BiRefNet, 1024x1024

| Modelo | | | _vision.cpp_ | PyTorch | ONNX Runtime |
| :---- | :--- | :--- | -----------: | -------: | -----------: |
| Full | cpu | f32 | 16333 ms | 18290 ms | |
| Full | gpu | f16 | 208 ms | 190 ms | |
| Lite | cpu | f32 | 4505 ms | 10900 ms | 6978 ms |
| Lite | gpu | f16 | 85 ms | 84 ms | |

#### Depth-Anything, 518x714

| Modelo | | | _vision.cpp_ | PyTorch |
| :---- | :--- | :--- | -----------: | ------: |
| Small | gpu | f16 | 11 ms | 10 ms |
| Base | gpu | f16 | 24 ms | 22 ms |

#### MI-GAN, 512x512

| Modelo | | | _vision.cpp_ | PyTorch |
| :---------- | :--- | :--- | -----------: | ------: |
| 512-places2 | cpu | f32 | 523 ms | 637 ms |
| 512-places2 | gpu | f16 | 21 ms | 17 ms |

#### Configuración

* vision.cpp: usando vision-bench, GPU vía Vulkan, p. ej. `vision-bench -m sam`
* PyTorch: v2.7.1+cu128, evaluación eager, GPU vía CUDA, promedio de n iteraciones después del calentamiento (warm-up)

## Dependencias (integradas)

* [ggml](https://github.com/ggml-org/ggml) - Biblioteca de tensores para ML | MIT
* [stb-image](https://github.com/nothings/stb) - Carga/guardado/redimensionado de imágenes | Dominio Público
* [fmt](https://github.com/fmtlib/fmt) - Formateo de cadenas _(solo si el compilador no soporta &lt;format&gt;)_ | MIT
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
230 changes: 230 additions & 0 deletions README.es-ES.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@


# _vision_.cpp

Inferencia de IA/ML para Visión por Computador en C++

* Biblioteca C++ autocontenida
* Inferencia eficiente en CPUs y GPUs de consumo (NVIDIA, AMD, Intel)
* Despliegue ligero en múltiples plataformas (Windows, Linux, MacOS)
* Número creciente de modelos compatibles detrás de una API simple
* Diseño modular para control total e implementar tus propios modelos

Basado en [ggml](https://github.com/ggml-org/ggml) similar al proyecto [llama.cpp](https://github.com/ggml-org/llama.cpp).

### Características

| Modelo | Tarea | Backends |
| :--------------------------------------- | :----------------------- | :---------- |
| [**MobileSAM**](#mobilesam) | Segmentación con prompts | CPU, Vulkan |
| [**BiRefNet**](#birefnet) | Segmentación dicotómica | CPU, Vulkan |
| [**Depth-Anything**](#depth-anything-v2) | Estimación de profundidad | CPU, Vulkan |
| [**MI-GAN**](#mi-gan) | Inpainting | CPU, Vulkan |
| [**ESRGAN**](#real-esrgan) | Super-resolución | CPU, Vulkan |
| [_Implementar un modelo [**Guía**]_](docs/model-implementation-guide.md) | | |

**Backbones:** SWIN (v1), DINO (v2), TinyViT

## Primeros pasos

Obtén la biblioteca y los ejecutables:
* Descarga un [paquete de lanzamiento](https://github.com/Acly/vision.cpp/releases) y extráelo,
* o [compílalo desde el código fuente](#building).

### Ejemplo: Seleccionar un objeto en una imagen

Utilicemos MobileSAM para generar una máscara de segmentación del peluche a la derecha, pasando un recuadro que describa su ubicación aproximada.

<img width="400" height="256" alt="Example image showing box prompt at pixel location (420, 120) - (650, 430), and the output mask" src="https://github.com/user-attachments/assets/0b90ad96-c7d2-4c4c-b028-699433cef704" />

Puedes descargar el modelo y la imagen de entrada aquí: [MobileSAM-F16.gguf](https://huggingface.co/Acly/MobileSAM-GGUF/resolve/main/MobileSAM-F16.gguf) | [input.jpg](docs/media/input.jpg)


#### CLI

Busca el ejecutable `vision-cli` en la carpeta `bin` y ejecútalo para generar la máscara:

```sh
vision-cli -m MobileSAM-F16.gguf -i input.jpg -p 420 120 650 430 -o mask.png
```
Para combinar la entrada y la máscara, pasa `--composite output.png`. Usa `--help` para ver más opciones.

#### API

```c++
#include <visp/vision.h>
using namespace visp;

void main() {
backend_device cpu = backend_init(backend_type::cpu);
sam_model sam = sam_load_model("MobileSAM-F16.gguf", cpu);

image_data input_image = image_load("input.jpg");
sam_encode(sam, input_image);

image_data object_mask = sam_compute(sam, box_2d{{420, 120}, {650, 320}});
image_save(object_mask, "mask.png");
}
```
Esto muestra la API de alto nivel. Internamente, está compuesta por múltiples funciones más pequeñas que manejan la carga del modelo, el preprocesamiento de entradas, la transferencia de datos a los dispositivos backend, el postprocesamiento de la salida, etc. Estas pueden usarse como bloques de construcción para funciones flexibles que se integren con tus fuentes de datos e infraestructura existentes.



## Modelos

#### MobileSAM

<img width="400" height="256" alt="example-sam" src="https://github.com/user-attachments/assets/9c0fe151-9990-4bb1-b954-7caff560b110" />

[Descarga del modelo](https://huggingface.co/Acly/MobileSAM-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/pdf/2306.14289.pdf) | [Repositorio (GitHub)](https://github.com/ChaoningZhang/MobileSAM) | [Segment-Anything-Model](https://segment-anything.com/) | Licencia: Apache-2

```sh
vision-cli sam -m MobileSAM-F16.gguf -i input.png -p 300 200 -o mask.png --composite comp.png
```

#### BiRefNet

<img width="400" height="256" alt="example-birefnet" src="https://github.com/user-attachments/assets/6fce086d-cb89-4717-92a6-9f4a20532b3c" />

[Descarga del modelo](https://huggingface.co/Acly/BiRefNet-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/pdf/2401.03407) | [Repositorio (GitHub)](https://github.com/ZhengPeng7/BiRefNet) | Licencia: MIT

```sh
vision-cli birefnet -m BiRefNet-lite-F16.gguf -i input.png -o mask.png --composite comp.png
```

#### Depth-Anything V2

<img width="400" height="256" alt="example-depth-anything" src="https://github.com/user-attachments/assets/62bde481-b898-4c46-a298-644198716953" />

[Descarga del modelo](https://huggingface.co/Acly/Depth-Anything-V2-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/abs/2406.09414) | [Repositorio (GitHub)](https://github.com/DepthAnything/Depth-Anything-V2) | Licencia: Apache-2 / CC-BY-NC-4

```sh
vision-cli depth-anything -m Depth-Anything-V2-Small-F16.gguf -i input.png -o depth.png
```

#### MI-GAN

<img width="400" height="256" alt="example-migan" src="https://github.com/user-attachments/assets/cadf1994-7677-4822-94e5-a2ee6c07621f" />

[Descarga del modelo](https://huggingface.co/Acly/MIGAN-GGUF/tree/main) | [Artículo (thecvf.com)](https://openaccess.thecvf.com/content/ICCV2023/papers/Sargsyan_MI-GAN_A_Simple_Baseline_for_Image_Inpainting_on_Mobile_Devices_ICCV_2023_paper.pdf) | [Repositorio (GitHub)](https://github.com/Picsart-AI-Research/MI-GAN) | Licencia: MIT

```sh
vision-cli migan -m MIGAN-512-places2-F16.gguf -i image.png mask.png -o output.png
```

#### Real-ESRGAN

<img width="400" height="256" alt="example-esrgan" src="https://github.com/user-attachments/assets/a41312d6-836c-4b11-ab5d-2e299ffee10c" />

[Descarga del modelo](https://huggingface.co/Acly/Real-ESRGAN-GGUF) | [Artículo (arXiv)](https://arxiv.org/abs/2107.10833) | [Repositorio (GitHub)](https://github.com/xinntao/Real-ESRGAN) | Licencia: BSD-3-Clause

```sh
vision-cli esrgan -m ESRGAN-4x-foolhardy_Remacri-F16.gguf -i input.png -o output.png
```


### Conversión de modelos

Los modelos deben convertirse a GGUF antes de poder usarse. Esto también reorganizará o precomputará tensores para una inferencia más óptima.

Para convertir un modelo, instala [uv](https://docs.astral.sh/uv/) y ejecuta:
```sh
uv run scripts/convert.py <arch> MyModel.pth
```
donde `<arch>` es uno de `sam, birefnet, esrgan, ...`.

Esto creará `models/MyModel.gguf`. Consulta `convert.py --help` para ver más opciones.

## Compilación

La compilación requiere CMake y un compilador con soporte para C++20.

**Obtener el código fuente**
```sh
git clone https://github.com/Acly/vision.cpp.git --recursive
cd vision.cpp
```

**Configurar y compilar**
```sh
cmake . -B build
cmake --build build --config Release
```

### Vulkan _(Opcional)_

Compilar con soporte para GPU Vulkan requiere que esté instalado el [Vulkan SDK](https://www.lunarg.com/vulkan-sdk/).

```sh
cmake . -B build -D VISP_VULKAN=ON
```

### Pruebas _(Opcional)_

Compila con `-DVISP_TESTS=ON`. Ejecuta todas las pruebas de C++ con el siguiente comando:
```sh
cd build
ctest -C Release
```

Algunas pruebas requieren un entorno de Python. Puede configurarse con [uv](https://docs.astral.sh/uv/):
```sh
# Setup venv and install dependencies (once only)
uv sync --dev

# Run python tests
uv run pytest
```

## Rendimiento

La optimización del rendimiento es un proceso continuo. El objetivo es estar en el mismo rango que otros frameworks en velocidad de inferencia, pero con:
* tiempos de inicialización y carga de modelos mucho más rápidos (<100 ms)
* menor sobrecarga de memoria
* tamaño de despliegue mínimo (<5 MB para CPU, +30 MB para GPU)

### Velocidad de inferencia

* CPU: AMD Ryzen 5 5600X (6 núcleos)
* GPU: NVIDIA GeForce RTX 4070

#### MobileSAM, 1024x1024

| | | _vision.cpp_ | PyTorch | ONNX Runtime |
| :--- | :--- | -----------: | ------: | -----------: |
| cpu | f32 | 669 ms | 601 ms | 805 ms |
| gpu | f16 | 19 ms | 16 ms | |

#### BiRefNet, 1024x1024

| Modelo | | | _vision.cpp_ | PyTorch | ONNX Runtime |
| :---- | :--- | :--- | -----------: | -------: | -----------: |
| Full | cpu | f32 | 16333 ms | 18290 ms | |
| Full | gpu | f16 | 208 ms | 190 ms | |
| Lite | cpu | f32 | 4505 ms | 10900 ms | 6978 ms |
| Lite | gpu | f16 | 85 ms | 84 ms | |

#### Depth-Anything, 518x714

| Modelo | | | _vision.cpp_ | PyTorch |
| :---- | :--- | :--- | -----------: | ------: |
| Small | gpu | f16 | 11 ms | 10 ms |
| Base | gpu | f16 | 24 ms | 22 ms |

#### MI-GAN, 512x512

| Modelo | | | _vision.cpp_ | PyTorch |
| :---------- | :--- | :--- | -----------: | ------: |
| 512-places2 | cpu | f32 | 523 ms | 637 ms |
| 512-places2 | gpu | f16 | 21 ms | 17 ms |

#### Configuración

* vision.cpp: usando vision-bench, GPU vía Vulkan, p. ej. `vision-bench -m sam`
* PyTorch: v2.7.1+cu128, evaluación eager, GPU vía CUDA, promedio de n iteraciones después del calentamiento (warm-up)

## Dependencias (integradas)

* [ggml](https://github.com/ggml-org/ggml) - Biblioteca de tensores para ML | MIT
* [stb-image](https://github.com/nothings/stb) - Carga/guardado/redimensionado de imágenes | Dominio Público
* [fmt](https://github.com/fmtlib/fmt) - Formateo de cadenas _(solo si el compilador no soporta &lt;format&gt;)_ | MIT
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
230 changes: 230 additions & 0 deletions README.es-ES.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@


# _vision_.cpp

Inferencia de IA/ML para Visión por Computador en C++

* Biblioteca C++ autocontenida
* Inferencia eficiente en CPUs y GPUs de consumo (NVIDIA, AMD, Intel)
* Despliegue ligero en múltiples plataformas (Windows, Linux, MacOS)
* Número creciente de modelos compatibles detrás de una API simple
* Diseño modular para control total e implementar tus propios modelos

Basado en [ggml](https://github.com/ggml-org/ggml) similar al proyecto [llama.cpp](https://github.com/ggml-org/llama.cpp).

### Características

| Modelo | Tarea | Backends |
| :--------------------------------------- | :----------------------- | :---------- |
| [**MobileSAM**](#mobilesam) | Segmentación con prompts | CPU, Vulkan |
| [**BiRefNet**](#birefnet) | Segmentación dicotómica | CPU, Vulkan |
| [**Depth-Anything**](#depth-anything-v2) | Estimación de profundidad | CPU, Vulkan |
| [**MI-GAN**](#mi-gan) | Inpainting | CPU, Vulkan |
| [**ESRGAN**](#real-esrgan) | Super-resolución | CPU, Vulkan |
| [_Implementar un modelo [**Guía**]_](docs/model-implementation-guide.md) | | |

**Backbones:** SWIN (v1), DINO (v2), TinyViT

## Primeros pasos

Obtén la biblioteca y los ejecutables:
* Descarga un [paquete de lanzamiento](https://github.com/Acly/vision.cpp/releases) y extráelo,
* o [compílalo desde el código fuente](#building).

### Ejemplo: Seleccionar un objeto en una imagen

Utilicemos MobileSAM para generar una máscara de segmentación del peluche a la derecha, pasando un recuadro que describa su ubicación aproximada.

<img width="400" height="256" alt="Example image showing box prompt at pixel location (420, 120) - (650, 430), and the output mask" src="https://github.com/user-attachments/assets/0b90ad96-c7d2-4c4c-b028-699433cef704" />

Puedes descargar el modelo y la imagen de entrada aquí: [MobileSAM-F16.gguf](https://huggingface.co/Acly/MobileSAM-GGUF/resolve/main/MobileSAM-F16.gguf) | [input.jpg](docs/media/input.jpg)


#### CLI

Busca el ejecutable `vision-cli` en la carpeta `bin` y ejecútalo para generar la máscara:

```sh
vision-cli -m MobileSAM-F16.gguf -i input.jpg -p 420 120 650 430 -o mask.png
```
Para combinar la entrada y la máscara, pasa `--composite output.png`. Usa `--help` para ver más opciones.

#### API

```c++
#include <visp/vision.h>
using namespace visp;

void main() {
backend_device cpu = backend_init(backend_type::cpu);
sam_model sam = sam_load_model("MobileSAM-F16.gguf", cpu);

image_data input_image = image_load("input.jpg");
sam_encode(sam, input_image);

image_data object_mask = sam_compute(sam, box_2d{{420, 120}, {650, 320}});
image_save(object_mask, "mask.png");
}
```
Esto muestra la API de alto nivel. Internamente, está compuesta por múltiples funciones más pequeñas que manejan la carga del modelo, el preprocesamiento de entradas, la transferencia de datos a los dispositivos backend, el postprocesamiento de la salida, etc. Estas pueden usarse como bloques de construcción para funciones flexibles que se integren con tus fuentes de datos e infraestructura existentes.



## Modelos

#### MobileSAM

<img width="400" height="256" alt="example-sam" src="https://github.com/user-attachments/assets/9c0fe151-9990-4bb1-b954-7caff560b110" />

[Descarga del modelo](https://huggingface.co/Acly/MobileSAM-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/pdf/2306.14289.pdf) | [Repositorio (GitHub)](https://github.com/ChaoningZhang/MobileSAM) | [Segment-Anything-Model](https://segment-anything.com/) | Licencia: Apache-2

```sh
vision-cli sam -m MobileSAM-F16.gguf -i input.png -p 300 200 -o mask.png --composite comp.png
```

#### BiRefNet

<img width="400" height="256" alt="example-birefnet" src="https://github.com/user-attachments/assets/6fce086d-cb89-4717-92a6-9f4a20532b3c" />

[Descarga del modelo](https://huggingface.co/Acly/BiRefNet-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/pdf/2401.03407) | [Repositorio (GitHub)](https://github.com/ZhengPeng7/BiRefNet) | Licencia: MIT

```sh
vision-cli birefnet -m BiRefNet-lite-F16.gguf -i input.png -o mask.png --composite comp.png
```

#### Depth-Anything V2

<img width="400" height="256" alt="example-depth-anything" src="https://github.com/user-attachments/assets/62bde481-b898-4c46-a298-644198716953" />

[Descarga del modelo](https://huggingface.co/Acly/Depth-Anything-V2-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/abs/2406.09414) | [Repositorio (GitHub)](https://github.com/DepthAnything/Depth-Anything-V2) | Licencia: Apache-2 / CC-BY-NC-4

```sh
vision-cli depth-anything -m Depth-Anything-V2-Small-F16.gguf -i input.png -o depth.png
```

#### MI-GAN

<img width="400" height="256" alt="example-migan" src="https://github.com/user-attachments/assets/cadf1994-7677-4822-94e5-a2ee6c07621f" />

[Descarga del modelo](https://huggingface.co/Acly/MIGAN-GGUF/tree/main) | [Artículo (thecvf.com)](https://openaccess.thecvf.com/content/ICCV2023/papers/Sargsyan_MI-GAN_A_Simple_Baseline_for_Image_Inpainting_on_Mobile_Devices_ICCV_2023_paper.pdf) | [Repositorio (GitHub)](https://github.com/Picsart-AI-Research/MI-GAN) | Licencia: MIT

```sh
vision-cli migan -m MIGAN-512-places2-F16.gguf -i image.png mask.png -o output.png
```

#### Real-ESRGAN

<img width="400" height="256" alt="example-esrgan" src="https://github.com/user-attachments/assets/a41312d6-836c-4b11-ab5d-2e299ffee10c" />

[Descarga del modelo](https://huggingface.co/Acly/Real-ESRGAN-GGUF) | [Artículo (arXiv)](https://arxiv.org/abs/2107.10833) | [Repositorio (GitHub)](https://github.com/xinntao/Real-ESRGAN) | Licencia: BSD-3-Clause

```sh
vision-cli esrgan -m ESRGAN-4x-foolhardy_Remacri-F16.gguf -i input.png -o output.png
```


### Conversión de modelos

Los modelos deben convertirse a GGUF antes de poder usarse. Esto también reorganizará o precomputará tensores para una inferencia más óptima.

Para convertir un modelo, instala [uv](https://docs.astral.sh/uv/) y ejecuta:
```sh
uv run scripts/convert.py <arch> MyModel.pth
```
donde `<arch>` es uno de `sam, birefnet, esrgan, ...`.

Esto creará `models/MyModel.gguf`. Consulta `convert.py --help` para ver más opciones.

## Compilación

La compilación requiere CMake y un compilador con soporte para C++20.

**Obtener el código fuente**
```sh
git clone https://github.com/Acly/vision.cpp.git --recursive
cd vision.cpp
```

**Configurar y compilar**
```sh
cmake . -B build
cmake --build build --config Release
```

### Vulkan _(Opcional)_

Compilar con soporte para GPU Vulkan requiere que esté instalado el [Vulkan SDK](https://www.lunarg.com/vulkan-sdk/).

```sh
cmake . -B build -D VISP_VULKAN=ON
```

### Pruebas _(Opcional)_

Compila con `-DVISP_TESTS=ON`. Ejecuta todas las pruebas de C++ con el siguiente comando:
```sh
cd build
ctest -C Release
```

Algunas pruebas requieren un entorno de Python. Puede configurarse con [uv](https://docs.astral.sh/uv/):
```sh
# Setup venv and install dependencies (once only)
uv sync --dev

# Run python tests
uv run pytest
```

## Rendimiento

La optimización del rendimiento es un proceso continuo. El objetivo es estar en el mismo rango que otros frameworks en velocidad de inferencia, pero con:
* tiempos de inicialización y carga de modelos mucho más rápidos (<100 ms)
* menor sobrecarga de memoria
* tamaño de despliegue mínimo (<5 MB para CPU, +30 MB para GPU)

### Velocidad de inferencia

* CPU: AMD Ryzen 5 5600X (6 núcleos)
* GPU: NVIDIA GeForce RTX 4070

#### MobileSAM, 1024x1024

| | | _vision.cpp_ | PyTorch | ONNX Runtime |
| :--- | :--- | -----------: | ------: | -----------: |
| cpu | f32 | 669 ms | 601 ms | 805 ms |
| gpu | f16 | 19 ms | 16 ms | |

#### BiRefNet, 1024x1024

| Modelo | | | _vision.cpp_ | PyTorch | ONNX Runtime |
| :---- | :--- | :--- | -----------: | -------: | -----------: |
| Full | cpu | f32 | 16333 ms | 18290 ms | |
| Full | gpu | f16 | 208 ms | 190 ms | |
| Lite | cpu | f32 | 4505 ms | 10900 ms | 6978 ms |
| Lite | gpu | f16 | 85 ms | 84 ms | |

#### Depth-Anything, 518x714

| Modelo | | | _vision.cpp_ | PyTorch |
| :---- | :--- | :--- | -----------: | ------: |
| Small | gpu | f16 | 11 ms | 10 ms |
| Base | gpu | f16 | 24 ms | 22 ms |

#### MI-GAN, 512x512

| Modelo | | | _vision.cpp_ | PyTorch |
| :---------- | :--- | :--- | -----------: | ------: |
| 512-places2 | cpu | f32 | 523 ms | 637 ms |
| 512-places2 | gpu | f16 | 21 ms | 17 ms |

#### Configuración

* vision.cpp: usando vision-bench, GPU vía Vulkan, p. ej. `vision-bench -m sam`
* PyTorch: v2.7.1+cu128, evaluación eager, GPU vía CUDA, promedio de n iteraciones después del calentamiento (warm-up)

## Dependencias (integradas)

* [ggml](https://github.com/ggml-org/ggml) - Biblioteca de tensores para ML | MIT
* [stb-image](https://github.com/nothings/stb) - Carga/guardado/redimensionado de imágenes | Dominio Público
* [fmt](https://github.com/fmtlib/fmt) - Formateo de cadenas _(solo si el compilador no soporta &lt;format&gt;)_ | MIT
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
230 changes: 230 additions & 0 deletions README.es-ES.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@


# _vision_.cpp

Inferencia de IA/ML para Visión por Computador en C++

* Biblioteca C++ autocontenida
* Inferencia eficiente en CPUs y GPUs de consumo (NVIDIA, AMD, Intel)
* Despliegue ligero en múltiples plataformas (Windows, Linux, MacOS)
* Número creciente de modelos compatibles detrás de una API simple
* Diseño modular para control total e implementar tus propios modelos

Basado en [ggml](https://github.com/ggml-org/ggml) similar al proyecto [llama.cpp](https://github.com/ggml-org/llama.cpp).

### Características

| Modelo | Tarea | Backends |
| :--------------------------------------- | :----------------------- | :---------- |
| [**MobileSAM**](#mobilesam) | Segmentación con prompts | CPU, Vulkan |
| [**BiRefNet**](#birefnet) | Segmentación dicotómica | CPU, Vulkan |
| [**Depth-Anything**](#depth-anything-v2) | Estimación de profundidad | CPU, Vulkan |
| [**MI-GAN**](#mi-gan) | Inpainting | CPU, Vulkan |
| [**ESRGAN**](#real-esrgan) | Super-resolución | CPU, Vulkan |
| [_Implementar un modelo [**Guía**]_](docs/model-implementation-guide.md) | | |

**Backbones:** SWIN (v1), DINO (v2), TinyViT

## Primeros pasos

Obtén la biblioteca y los ejecutables:
* Descarga un [paquete de lanzamiento](https://github.com/Acly/vision.cpp/releases) y extráelo,
* o [compílalo desde el código fuente](#building).

### Ejemplo: Seleccionar un objeto en una imagen

Utilicemos MobileSAM para generar una máscara de segmentación del peluche a la derecha, pasando un recuadro que describa su ubicación aproximada.

<img width="400" height="256" alt="Example image showing box prompt at pixel location (420, 120) - (650, 430), and the output mask" src="https://github.com/user-attachments/assets/0b90ad96-c7d2-4c4c-b028-699433cef704" />

Puedes descargar el modelo y la imagen de entrada aquí: [MobileSAM-F16.gguf](https://huggingface.co/Acly/MobileSAM-GGUF/resolve/main/MobileSAM-F16.gguf) | [input.jpg](docs/media/input.jpg)


#### CLI

Busca el ejecutable `vision-cli` en la carpeta `bin` y ejecútalo para generar la máscara:

```sh
vision-cli -m MobileSAM-F16.gguf -i input.jpg -p 420 120 650 430 -o mask.png
```
Para combinar la entrada y la máscara, pasa `--composite output.png`. Usa `--help` para ver más opciones.

#### API

```c++
#include <visp/vision.h>
using namespace visp;

void main() {
backend_device cpu = backend_init(backend_type::cpu);
sam_model sam = sam_load_model("MobileSAM-F16.gguf", cpu);

image_data input_image = image_load("input.jpg");
sam_encode(sam, input_image);

image_data object_mask = sam_compute(sam, box_2d{{420, 120}, {650, 320}});
image_save(object_mask, "mask.png");
}
```
Esto muestra la API de alto nivel. Internamente, está compuesta por múltiples funciones más pequeñas que manejan la carga del modelo, el preprocesamiento de entradas, la transferencia de datos a los dispositivos backend, el postprocesamiento de la salida, etc. Estas pueden usarse como bloques de construcción para funciones flexibles que se integren con tus fuentes de datos e infraestructura existentes.



## Modelos

#### MobileSAM

<img width="400" height="256" alt="example-sam" src="https://github.com/user-attachments/assets/9c0fe151-9990-4bb1-b954-7caff560b110" />

[Descarga del modelo](https://huggingface.co/Acly/MobileSAM-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/pdf/2306.14289.pdf) | [Repositorio (GitHub)](https://github.com/ChaoningZhang/MobileSAM) | [Segment-Anything-Model](https://segment-anything.com/) | Licencia: Apache-2

```sh
vision-cli sam -m MobileSAM-F16.gguf -i input.png -p 300 200 -o mask.png --composite comp.png
```

#### BiRefNet

<img width="400" height="256" alt="example-birefnet" src="https://github.com/user-attachments/assets/6fce086d-cb89-4717-92a6-9f4a20532b3c" />

[Descarga del modelo](https://huggingface.co/Acly/BiRefNet-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/pdf/2401.03407) | [Repositorio (GitHub)](https://github.com/ZhengPeng7/BiRefNet) | Licencia: MIT

```sh
vision-cli birefnet -m BiRefNet-lite-F16.gguf -i input.png -o mask.png --composite comp.png
```

#### Depth-Anything V2

<img width="400" height="256" alt="example-depth-anything" src="https://github.com/user-attachments/assets/62bde481-b898-4c46-a298-644198716953" />

[Descarga del modelo](https://huggingface.co/Acly/Depth-Anything-V2-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/abs/2406.09414) | [Repositorio (GitHub)](https://github.com/DepthAnything/Depth-Anything-V2) | Licencia: Apache-2 / CC-BY-NC-4

```sh
vision-cli depth-anything -m Depth-Anything-V2-Small-F16.gguf -i input.png -o depth.png
```

#### MI-GAN

<img width="400" height="256" alt="example-migan" src="https://github.com/user-attachments/assets/cadf1994-7677-4822-94e5-a2ee6c07621f" />

[Descarga del modelo](https://huggingface.co/Acly/MIGAN-GGUF/tree/main) | [Artículo (thecvf.com)](https://openaccess.thecvf.com/content/ICCV2023/papers/Sargsyan_MI-GAN_A_Simple_Baseline_for_Image_Inpainting_on_Mobile_Devices_ICCV_2023_paper.pdf) | [Repositorio (GitHub)](https://github.com/Picsart-AI-Research/MI-GAN) | Licencia: MIT

```sh
vision-cli migan -m MIGAN-512-places2-F16.gguf -i image.png mask.png -o output.png
```

#### Real-ESRGAN

<img width="400" height="256" alt="example-esrgan" src="https://github.com/user-attachments/assets/a41312d6-836c-4b11-ab5d-2e299ffee10c" />

[Descarga del modelo](https://huggingface.co/Acly/Real-ESRGAN-GGUF) | [Artículo (arXiv)](https://arxiv.org/abs/2107.10833) | [Repositorio (GitHub)](https://github.com/xinntao/Real-ESRGAN) | Licencia: BSD-3-Clause

```sh
vision-cli esrgan -m ESRGAN-4x-foolhardy_Remacri-F16.gguf -i input.png -o output.png
```


### Conversión de modelos

Los modelos deben convertirse a GGUF antes de poder usarse. Esto también reorganizará o precomputará tensores para una inferencia más óptima.

Para convertir un modelo, instala [uv](https://docs.astral.sh/uv/) y ejecuta:
```sh
uv run scripts/convert.py <arch> MyModel.pth
```
donde `<arch>` es uno de `sam, birefnet, esrgan, ...`.

Esto creará `models/MyModel.gguf`. Consulta `convert.py --help` para ver más opciones.

## Compilación

La compilación requiere CMake y un compilador con soporte para C++20.

**Obtener el código fuente**
```sh
git clone https://github.com/Acly/vision.cpp.git --recursive
cd vision.cpp
```

**Configurar y compilar**
```sh
cmake . -B build
cmake --build build --config Release
```

### Vulkan _(Opcional)_

Compilar con soporte para GPU Vulkan requiere que esté instalado el [Vulkan SDK](https://www.lunarg.com/vulkan-sdk/).

```sh
cmake . -B build -D VISP_VULKAN=ON
```

### Pruebas _(Opcional)_

Compila con `-DVISP_TESTS=ON`. Ejecuta todas las pruebas de C++ con el siguiente comando:
```sh
cd build
ctest -C Release
```

Algunas pruebas requieren un entorno de Python. Puede configurarse con [uv](https://docs.astral.sh/uv/):
```sh
# Setup venv and install dependencies (once only)
uv sync --dev

# Run python tests
uv run pytest
```

## Rendimiento

La optimización del rendimiento es un proceso continuo. El objetivo es estar en el mismo rango que otros frameworks en velocidad de inferencia, pero con:
* tiempos de inicialización y carga de modelos mucho más rápidos (<100 ms)
* menor sobrecarga de memoria
* tamaño de despliegue mínimo (<5 MB para CPU, +30 MB para GPU)

### Velocidad de inferencia

* CPU: AMD Ryzen 5 5600X (6 núcleos)
* GPU: NVIDIA GeForce RTX 4070

#### MobileSAM, 1024x1024

| | | _vision.cpp_ | PyTorch | ONNX Runtime |
| :--- | :--- | -----------: | ------: | -----------: |
| cpu | f32 | 669 ms | 601 ms | 805 ms |
| gpu | f16 | 19 ms | 16 ms | |

#### BiRefNet, 1024x1024

| Modelo | | | _vision.cpp_ | PyTorch | ONNX Runtime |
| :---- | :--- | :--- | -----------: | -------: | -----------: |
| Full | cpu | f32 | 16333 ms | 18290 ms | |
| Full | gpu | f16 | 208 ms | 190 ms | |
| Lite | cpu | f32 | 4505 ms | 10900 ms | 6978 ms |
| Lite | gpu | f16 | 85 ms | 84 ms | |

#### Depth-Anything, 518x714

| Modelo | | | _vision.cpp_ | PyTorch |
| :---- | :--- | :--- | -----------: | ------: |
| Small | gpu | f16 | 11 ms | 10 ms |
| Base | gpu | f16 | 24 ms | 22 ms |

#### MI-GAN, 512x512

| Modelo | | | _vision.cpp_ | PyTorch |
| :---------- | :--- | :--- | -----------: | ------: |
| 512-places2 | cpu | f32 | 523 ms | 637 ms |
| 512-places2 | gpu | f16 | 21 ms | 17 ms |

#### Configuración

* vision.cpp: usando vision-bench, GPU vía Vulkan, p. ej. `vision-bench -m sam`
* PyTorch: v2.7.1+cu128, evaluación eager, GPU vía CUDA, promedio de n iteraciones después del calentamiento (warm-up)

## Dependencias (integradas)

* [ggml](https://github.com/ggml-org/ggml) - Biblioteca de tensores para ML | MIT
* [stb-image](https://github.com/nothings/stb) - Carga/guardado/redimensionado de imágenes | Dominio Público
* [fmt](https://github.com/fmtlib/fmt) - Formateo de cadenas _(solo si el compilador no soporta &lt;format&gt;)_ | MIT
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
230 changes: 230 additions & 0 deletions README.es-ES.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@


# _vision_.cpp

Inferencia de IA/ML para Visión por Computador en C++

* Biblioteca C++ autocontenida
* Inferencia eficiente en CPUs y GPUs de consumo (NVIDIA, AMD, Intel)
* Despliegue ligero en múltiples plataformas (Windows, Linux, MacOS)
* Número creciente de modelos compatibles detrás de una API simple
* Diseño modular para control total e implementar tus propios modelos

Basado en [ggml](https://github.com/ggml-org/ggml) similar al proyecto [llama.cpp](https://github.com/ggml-org/llama.cpp).

### Características

| Modelo | Tarea | Backends |
| :--------------------------------------- | :----------------------- | :---------- |
| [**MobileSAM**](#mobilesam) | Segmentación con prompts | CPU, Vulkan |
| [**BiRefNet**](#birefnet) | Segmentación dicotómica | CPU, Vulkan |
| [**Depth-Anything**](#depth-anything-v2) | Estimación de profundidad | CPU, Vulkan |
| [**MI-GAN**](#mi-gan) | Inpainting | CPU, Vulkan |
| [**ESRGAN**](#real-esrgan) | Super-resolución | CPU, Vulkan |
| [_Implementar un modelo [**Guía**]_](docs/model-implementation-guide.md) | | |

**Backbones:** SWIN (v1), DINO (v2), TinyViT

## Primeros pasos

Obtén la biblioteca y los ejecutables:
* Descarga un [paquete de lanzamiento](https://github.com/Acly/vision.cpp/releases) y extráelo,
* o [compílalo desde el código fuente](#building).

### Ejemplo: Seleccionar un objeto en una imagen

Utilicemos MobileSAM para generar una máscara de segmentación del peluche a la derecha, pasando un recuadro que describa su ubicación aproximada.

<img width="400" height="256" alt="Example image showing box prompt at pixel location (420, 120) - (650, 430), and the output mask" src="https://github.com/user-attachments/assets/0b90ad96-c7d2-4c4c-b028-699433cef704" />

Puedes descargar el modelo y la imagen de entrada aquí: [MobileSAM-F16.gguf](https://huggingface.co/Acly/MobileSAM-GGUF/resolve/main/MobileSAM-F16.gguf) | [input.jpg](docs/media/input.jpg)


#### CLI

Busca el ejecutable `vision-cli` en la carpeta `bin` y ejecútalo para generar la máscara:

```sh
vision-cli -m MobileSAM-F16.gguf -i input.jpg -p 420 120 650 430 -o mask.png
```
Para combinar la entrada y la máscara, pasa `--composite output.png`. Usa `--help` para ver más opciones.

#### API

```c++
#include <visp/vision.h>
using namespace visp;

void main() {
backend_device cpu = backend_init(backend_type::cpu);
sam_model sam = sam_load_model("MobileSAM-F16.gguf", cpu);

image_data input_image = image_load("input.jpg");
sam_encode(sam, input_image);

image_data object_mask = sam_compute(sam, box_2d{{420, 120}, {650, 320}});
image_save(object_mask, "mask.png");
}
```
Esto muestra la API de alto nivel. Internamente, está compuesta por múltiples funciones más pequeñas que manejan la carga del modelo, el preprocesamiento de entradas, la transferencia de datos a los dispositivos backend, el postprocesamiento de la salida, etc. Estas pueden usarse como bloques de construcción para funciones flexibles que se integren con tus fuentes de datos e infraestructura existentes.



## Modelos

#### MobileSAM

<img width="400" height="256" alt="example-sam" src="https://github.com/user-attachments/assets/9c0fe151-9990-4bb1-b954-7caff560b110" />

[Descarga del modelo](https://huggingface.co/Acly/MobileSAM-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/pdf/2306.14289.pdf) | [Repositorio (GitHub)](https://github.com/ChaoningZhang/MobileSAM) | [Segment-Anything-Model](https://segment-anything.com/) | Licencia: Apache-2

```sh
vision-cli sam -m MobileSAM-F16.gguf -i input.png -p 300 200 -o mask.png --composite comp.png
```

#### BiRefNet

<img width="400" height="256" alt="example-birefnet" src="https://github.com/user-attachments/assets/6fce086d-cb89-4717-92a6-9f4a20532b3c" />

[Descarga del modelo](https://huggingface.co/Acly/BiRefNet-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/pdf/2401.03407) | [Repositorio (GitHub)](https://github.com/ZhengPeng7/BiRefNet) | Licencia: MIT

```sh
vision-cli birefnet -m BiRefNet-lite-F16.gguf -i input.png -o mask.png --composite comp.png
```

#### Depth-Anything V2

<img width="400" height="256" alt="example-depth-anything" src="https://github.com/user-attachments/assets/62bde481-b898-4c46-a298-644198716953" />

[Descarga del modelo](https://huggingface.co/Acly/Depth-Anything-V2-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/abs/2406.09414) | [Repositorio (GitHub)](https://github.com/DepthAnything/Depth-Anything-V2) | Licencia: Apache-2 / CC-BY-NC-4

```sh
vision-cli depth-anything -m Depth-Anything-V2-Small-F16.gguf -i input.png -o depth.png
```

#### MI-GAN

<img width="400" height="256" alt="example-migan" src="https://github.com/user-attachments/assets/cadf1994-7677-4822-94e5-a2ee6c07621f" />

[Descarga del modelo](https://huggingface.co/Acly/MIGAN-GGUF/tree/main) | [Artículo (thecvf.com)](https://openaccess.thecvf.com/content/ICCV2023/papers/Sargsyan_MI-GAN_A_Simple_Baseline_for_Image_Inpainting_on_Mobile_Devices_ICCV_2023_paper.pdf) | [Repositorio (GitHub)](https://github.com/Picsart-AI-Research/MI-GAN) | Licencia: MIT

```sh
vision-cli migan -m MIGAN-512-places2-F16.gguf -i image.png mask.png -o output.png
```

#### Real-ESRGAN

<img width="400" height="256" alt="example-esrgan" src="https://github.com/user-attachments/assets/a41312d6-836c-4b11-ab5d-2e299ffee10c" />

[Descarga del modelo](https://huggingface.co/Acly/Real-ESRGAN-GGUF) | [Artículo (arXiv)](https://arxiv.org/abs/2107.10833) | [Repositorio (GitHub)](https://github.com/xinntao/Real-ESRGAN) | Licencia: BSD-3-Clause

```sh
vision-cli esrgan -m ESRGAN-4x-foolhardy_Remacri-F16.gguf -i input.png -o output.png
```


### Conversión de modelos

Los modelos deben convertirse a GGUF antes de poder usarse. Esto también reorganizará o precomputará tensores para una inferencia más óptima.

Para convertir un modelo, instala [uv](https://docs.astral.sh/uv/) y ejecuta:
```sh
uv run scripts/convert.py <arch> MyModel.pth
```
donde `<arch>` es uno de `sam, birefnet, esrgan, ...`.

Esto creará `models/MyModel.gguf`. Consulta `convert.py --help` para ver más opciones.

## Compilación

La compilación requiere CMake y un compilador con soporte para C++20.

**Obtener el código fuente**
```sh
git clone https://github.com/Acly/vision.cpp.git --recursive
cd vision.cpp
```

**Configurar y compilar**
```sh
cmake . -B build
cmake --build build --config Release
```

### Vulkan _(Opcional)_

Compilar con soporte para GPU Vulkan requiere que esté instalado el [Vulkan SDK](https://www.lunarg.com/vulkan-sdk/).

```sh
cmake . -B build -D VISP_VULKAN=ON
```

### Pruebas _(Opcional)_

Compila con `-DVISP_TESTS=ON`. Ejecuta todas las pruebas de C++ con el siguiente comando:
```sh
cd build
ctest -C Release
```

Algunas pruebas requieren un entorno de Python. Puede configurarse con [uv](https://docs.astral.sh/uv/):
```sh
# Setup venv and install dependencies (once only)
uv sync --dev

# Run python tests
uv run pytest
```

## Rendimiento

La optimización del rendimiento es un proceso continuo. El objetivo es estar en el mismo rango que otros frameworks en velocidad de inferencia, pero con:
* tiempos de inicialización y carga de modelos mucho más rápidos (<100 ms)
* menor sobrecarga de memoria
* tamaño de despliegue mínimo (<5 MB para CPU, +30 MB para GPU)

### Velocidad de inferencia

* CPU: AMD Ryzen 5 5600X (6 núcleos)
* GPU: NVIDIA GeForce RTX 4070

#### MobileSAM, 1024x1024

| | | _vision.cpp_ | PyTorch | ONNX Runtime |
| :--- | :--- | -----------: | ------: | -----------: |
| cpu | f32 | 669 ms | 601 ms | 805 ms |
| gpu | f16 | 19 ms | 16 ms | |

#### BiRefNet, 1024x1024

| Modelo | | | _vision.cpp_ | PyTorch | ONNX Runtime |
| :---- | :--- | :--- | -----------: | -------: | -----------: |
| Full | cpu | f32 | 16333 ms | 18290 ms | |
| Full | gpu | f16 | 208 ms | 190 ms | |
| Lite | cpu | f32 | 4505 ms | 10900 ms | 6978 ms |
| Lite | gpu | f16 | 85 ms | 84 ms | |

#### Depth-Anything, 518x714

| Modelo | | | _vision.cpp_ | PyTorch |
| :---- | :--- | :--- | -----------: | ------: |
| Small | gpu | f16 | 11 ms | 10 ms |
| Base | gpu | f16 | 24 ms | 22 ms |

#### MI-GAN, 512x512

| Modelo | | | _vision.cpp_ | PyTorch |
| :---------- | :--- | :--- | -----------: | ------: |
| 512-places2 | cpu | f32 | 523 ms | 637 ms |
| 512-places2 | gpu | f16 | 21 ms | 17 ms |

#### Configuración

* vision.cpp: usando vision-bench, GPU vía Vulkan, p. ej. `vision-bench -m sam`
* PyTorch: v2.7.1+cu128, evaluación eager, GPU vía CUDA, promedio de n iteraciones después del calentamiento (warm-up)

## Dependencias (integradas)

* [ggml](https://github.com/ggml-org/ggml) - Biblioteca de tensores para ML | MIT
* [stb-image](https://github.com/nothings/stb) - Carga/guardado/redimensionado de imágenes | Dominio Público
* [fmt](https://github.com/fmtlib/fmt) - Formateo de cadenas _(solo si el compilador no soporta &lt;format&gt;)_ | MIT
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
230 changes: 230 additions & 0 deletions README.es-ES.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@


# _vision_.cpp

Inferencia de IA/ML para Visión por Computador en C++

* Biblioteca C++ autocontenida
* Inferencia eficiente en CPUs y GPUs de consumo (NVIDIA, AMD, Intel)
* Despliegue ligero en múltiples plataformas (Windows, Linux, MacOS)
* Número creciente de modelos compatibles detrás de una API simple
* Diseño modular para control total e implementar tus propios modelos

Basado en [ggml](https://github.com/ggml-org/ggml) similar al proyecto [llama.cpp](https://github.com/ggml-org/llama.cpp).

### Características

| Modelo | Tarea | Backends |
| :--------------------------------------- | :----------------------- | :---------- |
| [**MobileSAM**](#mobilesam) | Segmentación con prompts | CPU, Vulkan |
| [**BiRefNet**](#birefnet) | Segmentación dicotómica | CPU, Vulkan |
| [**Depth-Anything**](#depth-anything-v2) | Estimación de profundidad | CPU, Vulkan |
| [**MI-GAN**](#mi-gan) | Inpainting | CPU, Vulkan |
| [**ESRGAN**](#real-esrgan) | Super-resolución | CPU, Vulkan |
| [_Implementar un modelo [**Guía**]_](docs/model-implementation-guide.md) | | |

**Backbones:** SWIN (v1), DINO (v2), TinyViT

## Primeros pasos

Obtén la biblioteca y los ejecutables:
* Descarga un [paquete de lanzamiento](https://github.com/Acly/vision.cpp/releases) y extráelo,
* o [compílalo desde el código fuente](#building).

### Ejemplo: Seleccionar un objeto en una imagen

Utilicemos MobileSAM para generar una máscara de segmentación del peluche a la derecha, pasando un recuadro que describa su ubicación aproximada.

<img width="400" height="256" alt="Example image showing box prompt at pixel location (420, 120) - (650, 430), and the output mask" src="https://github.com/user-attachments/assets/0b90ad96-c7d2-4c4c-b028-699433cef704" />

Puedes descargar el modelo y la imagen de entrada aquí: [MobileSAM-F16.gguf](https://huggingface.co/Acly/MobileSAM-GGUF/resolve/main/MobileSAM-F16.gguf) | [input.jpg](docs/media/input.jpg)


#### CLI

Busca el ejecutable `vision-cli` en la carpeta `bin` y ejecútalo para generar la máscara:

```sh
vision-cli -m MobileSAM-F16.gguf -i input.jpg -p 420 120 650 430 -o mask.png
```
Para combinar la entrada y la máscara, pasa `--composite output.png`. Usa `--help` para ver más opciones.

#### API

```c++
#include <visp/vision.h>
using namespace visp;

void main() {
backend_device cpu = backend_init(backend_type::cpu);
sam_model sam = sam_load_model("MobileSAM-F16.gguf", cpu);

image_data input_image = image_load("input.jpg");
sam_encode(sam, input_image);

image_data object_mask = sam_compute(sam, box_2d{{420, 120}, {650, 320}});
image_save(object_mask, "mask.png");
}
```
Esto muestra la API de alto nivel. Internamente, está compuesta por múltiples funciones más pequeñas que manejan la carga del modelo, el preprocesamiento de entradas, la transferencia de datos a los dispositivos backend, el postprocesamiento de la salida, etc. Estas pueden usarse como bloques de construcción para funciones flexibles que se integren con tus fuentes de datos e infraestructura existentes.



## Modelos

#### MobileSAM

<img width="400" height="256" alt="example-sam" src="https://github.com/user-attachments/assets/9c0fe151-9990-4bb1-b954-7caff560b110" />

[Descarga del modelo](https://huggingface.co/Acly/MobileSAM-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/pdf/2306.14289.pdf) | [Repositorio (GitHub)](https://github.com/ChaoningZhang/MobileSAM) | [Segment-Anything-Model](https://segment-anything.com/) | Licencia: Apache-2

```sh
vision-cli sam -m MobileSAM-F16.gguf -i input.png -p 300 200 -o mask.png --composite comp.png
```

#### BiRefNet

<img width="400" height="256" alt="example-birefnet" src="https://github.com/user-attachments/assets/6fce086d-cb89-4717-92a6-9f4a20532b3c" />

[Descarga del modelo](https://huggingface.co/Acly/BiRefNet-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/pdf/2401.03407) | [Repositorio (GitHub)](https://github.com/ZhengPeng7/BiRefNet) | Licencia: MIT

```sh
vision-cli birefnet -m BiRefNet-lite-F16.gguf -i input.png -o mask.png --composite comp.png
```

#### Depth-Anything V2

<img width="400" height="256" alt="example-depth-anything" src="https://github.com/user-attachments/assets/62bde481-b898-4c46-a298-644198716953" />

[Descarga del modelo](https://huggingface.co/Acly/Depth-Anything-V2-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/abs/2406.09414) | [Repositorio (GitHub)](https://github.com/DepthAnything/Depth-Anything-V2) | Licencia: Apache-2 / CC-BY-NC-4

```sh
vision-cli depth-anything -m Depth-Anything-V2-Small-F16.gguf -i input.png -o depth.png
```

#### MI-GAN

<img width="400" height="256" alt="example-migan" src="https://github.com/user-attachments/assets/cadf1994-7677-4822-94e5-a2ee6c07621f" />

[Descarga del modelo](https://huggingface.co/Acly/MIGAN-GGUF/tree/main) | [Artículo (thecvf.com)](https://openaccess.thecvf.com/content/ICCV2023/papers/Sargsyan_MI-GAN_A_Simple_Baseline_for_Image_Inpainting_on_Mobile_Devices_ICCV_2023_paper.pdf) | [Repositorio (GitHub)](https://github.com/Picsart-AI-Research/MI-GAN) | Licencia: MIT

```sh
vision-cli migan -m MIGAN-512-places2-F16.gguf -i image.png mask.png -o output.png
```

#### Real-ESRGAN

<img width="400" height="256" alt="example-esrgan" src="https://github.com/user-attachments/assets/a41312d6-836c-4b11-ab5d-2e299ffee10c" />

[Descarga del modelo](https://huggingface.co/Acly/Real-ESRGAN-GGUF) | [Artículo (arXiv)](https://arxiv.org/abs/2107.10833) | [Repositorio (GitHub)](https://github.com/xinntao/Real-ESRGAN) | Licencia: BSD-3-Clause

```sh
vision-cli esrgan -m ESRGAN-4x-foolhardy_Remacri-F16.gguf -i input.png -o output.png
```


### Conversión de modelos

Los modelos deben convertirse a GGUF antes de poder usarse. Esto también reorganizará o precomputará tensores para una inferencia más óptima.

Para convertir un modelo, instala [uv](https://docs.astral.sh/uv/) y ejecuta:
```sh
uv run scripts/convert.py <arch> MyModel.pth
```
donde `<arch>` es uno de `sam, birefnet, esrgan, ...`.

Esto creará `models/MyModel.gguf`. Consulta `convert.py --help` para ver más opciones.

## Compilación

La compilación requiere CMake y un compilador con soporte para C++20.

**Obtener el código fuente**
```sh
git clone https://github.com/Acly/vision.cpp.git --recursive
cd vision.cpp
```

**Configurar y compilar**
```sh
cmake . -B build
cmake --build build --config Release
```

### Vulkan _(Opcional)_

Compilar con soporte para GPU Vulkan requiere que esté instalado el [Vulkan SDK](https://www.lunarg.com/vulkan-sdk/).

```sh
cmake . -B build -D VISP_VULKAN=ON
```

### Pruebas _(Opcional)_

Compila con `-DVISP_TESTS=ON`. Ejecuta todas las pruebas de C++ con el siguiente comando:
```sh
cd build
ctest -C Release
```

Algunas pruebas requieren un entorno de Python. Puede configurarse con [uv](https://docs.astral.sh/uv/):
```sh
# Setup venv and install dependencies (once only)
uv sync --dev

# Run python tests
uv run pytest
```

## Rendimiento

La optimización del rendimiento es un proceso continuo. El objetivo es estar en el mismo rango que otros frameworks en velocidad de inferencia, pero con:
* tiempos de inicialización y carga de modelos mucho más rápidos (<100 ms)
* menor sobrecarga de memoria
* tamaño de despliegue mínimo (<5 MB para CPU, +30 MB para GPU)

### Velocidad de inferencia

* CPU: AMD Ryzen 5 5600X (6 núcleos)
* GPU: NVIDIA GeForce RTX 4070

#### MobileSAM, 1024x1024

| | | _vision.cpp_ | PyTorch | ONNX Runtime |
| :--- | :--- | -----------: | ------: | -----------: |
| cpu | f32 | 669 ms | 601 ms | 805 ms |
| gpu | f16 | 19 ms | 16 ms | |

#### BiRefNet, 1024x1024

| Modelo | | | _vision.cpp_ | PyTorch | ONNX Runtime |
| :---- | :--- | :--- | -----------: | -------: | -----------: |
| Full | cpu | f32 | 16333 ms | 18290 ms | |
| Full | gpu | f16 | 208 ms | 190 ms | |
| Lite | cpu | f32 | 4505 ms | 10900 ms | 6978 ms |
| Lite | gpu | f16 | 85 ms | 84 ms | |

#### Depth-Anything, 518x714

| Modelo | | | _vision.cpp_ | PyTorch |
| :---- | :--- | :--- | -----------: | ------: |
| Small | gpu | f16 | 11 ms | 10 ms |
| Base | gpu | f16 | 24 ms | 22 ms |

#### MI-GAN, 512x512

| Modelo | | | _vision.cpp_ | PyTorch |
| :---------- | :--- | :--- | -----------: | ------: |
| 512-places2 | cpu | f32 | 523 ms | 637 ms |
| 512-places2 | gpu | f16 | 21 ms | 17 ms |

#### Configuración

* vision.cpp: usando vision-bench, GPU vía Vulkan, p. ej. `vision-bench -m sam`
* PyTorch: v2.7.1+cu128, evaluación eager, GPU vía CUDA, promedio de n iteraciones después del calentamiento (warm-up)

## Dependencias (integradas)

* [ggml](https://github.com/ggml-org/ggml) - Biblioteca de tensores para ML | MIT
* [stb-image](https://github.com/nothings/stb) - Carga/guardado/redimensionado de imágenes | Dominio Público
* [fmt](https://github.com/fmtlib/fmt) - Formateo de cadenas _(solo si el compilador no soporta &lt;format&gt;)_ | MIT
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
230 changes: 230 additions & 0 deletions README.es-ES.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@


# _vision_.cpp

Inferencia de IA/ML para Visión por Computador en C++

* Biblioteca C++ autocontenida
* Inferencia eficiente en CPUs y GPUs de consumo (NVIDIA, AMD, Intel)
* Despliegue ligero en múltiples plataformas (Windows, Linux, MacOS)
* Número creciente de modelos compatibles detrás de una API simple
* Diseño modular para control total e implementar tus propios modelos

Basado en [ggml](https://github.com/ggml-org/ggml) similar al proyecto [llama.cpp](https://github.com/ggml-org/llama.cpp).

### Características

| Modelo | Tarea | Backends |
| :--------------------------------------- | :----------------------- | :---------- |
| [**MobileSAM**](#mobilesam) | Segmentación con prompts | CPU, Vulkan |
| [**BiRefNet**](#birefnet) | Segmentación dicotómica | CPU, Vulkan |
| [**Depth-Anything**](#depth-anything-v2) | Estimación de profundidad | CPU, Vulkan |
| [**MI-GAN**](#mi-gan) | Inpainting | CPU, Vulkan |
| [**ESRGAN**](#real-esrgan) | Super-resolución | CPU, Vulkan |
| [_Implementar un modelo [**Guía**]_](docs/model-implementation-guide.md) | | |

**Backbones:** SWIN (v1), DINO (v2), TinyViT

## Primeros pasos

Obtén la biblioteca y los ejecutables:
* Descarga un [paquete de lanzamiento](https://github.com/Acly/vision.cpp/releases) y extráelo,
* o [compílalo desde el código fuente](#building).

### Ejemplo: Seleccionar un objeto en una imagen

Utilicemos MobileSAM para generar una máscara de segmentación del peluche a la derecha, pasando un recuadro que describa su ubicación aproximada.

<img width="400" height="256" alt="Example image showing box prompt at pixel location (420, 120) - (650, 430), and the output mask" src="https://github.com/user-attachments/assets/0b90ad96-c7d2-4c4c-b028-699433cef704" />

Puedes descargar el modelo y la imagen de entrada aquí: [MobileSAM-F16.gguf](https://huggingface.co/Acly/MobileSAM-GGUF/resolve/main/MobileSAM-F16.gguf) | [input.jpg](docs/media/input.jpg)


#### CLI

Busca el ejecutable `vision-cli` en la carpeta `bin` y ejecútalo para generar la máscara:

```sh
vision-cli -m MobileSAM-F16.gguf -i input.jpg -p 420 120 650 430 -o mask.png
```
Para combinar la entrada y la máscara, pasa `--composite output.png`. Usa `--help` para ver más opciones.

#### API

```c++
#include <visp/vision.h>
using namespace visp;

void main() {
backend_device cpu = backend_init(backend_type::cpu);
sam_model sam = sam_load_model("MobileSAM-F16.gguf", cpu);

image_data input_image = image_load("input.jpg");
sam_encode(sam, input_image);

image_data object_mask = sam_compute(sam, box_2d{{420, 120}, {650, 320}});
image_save(object_mask, "mask.png");
}
```
Esto muestra la API de alto nivel. Internamente, está compuesta por múltiples funciones más pequeñas que manejan la carga del modelo, el preprocesamiento de entradas, la transferencia de datos a los dispositivos backend, el postprocesamiento de la salida, etc. Estas pueden usarse como bloques de construcción para funciones flexibles que se integren con tus fuentes de datos e infraestructura existentes.



## Modelos

#### MobileSAM

<img width="400" height="256" alt="example-sam" src="https://github.com/user-attachments/assets/9c0fe151-9990-4bb1-b954-7caff560b110" />

[Descarga del modelo](https://huggingface.co/Acly/MobileSAM-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/pdf/2306.14289.pdf) | [Repositorio (GitHub)](https://github.com/ChaoningZhang/MobileSAM) | [Segment-Anything-Model](https://segment-anything.com/) | Licencia: Apache-2

```sh
vision-cli sam -m MobileSAM-F16.gguf -i input.png -p 300 200 -o mask.png --composite comp.png
```

#### BiRefNet

<img width="400" height="256" alt="example-birefnet" src="https://github.com/user-attachments/assets/6fce086d-cb89-4717-92a6-9f4a20532b3c" />

[Descarga del modelo](https://huggingface.co/Acly/BiRefNet-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/pdf/2401.03407) | [Repositorio (GitHub)](https://github.com/ZhengPeng7/BiRefNet) | Licencia: MIT

```sh
vision-cli birefnet -m BiRefNet-lite-F16.gguf -i input.png -o mask.png --composite comp.png
```

#### Depth-Anything V2

<img width="400" height="256" alt="example-depth-anything" src="https://github.com/user-attachments/assets/62bde481-b898-4c46-a298-644198716953" />

[Descarga del modelo](https://huggingface.co/Acly/Depth-Anything-V2-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/abs/2406.09414) | [Repositorio (GitHub)](https://github.com/DepthAnything/Depth-Anything-V2) | Licencia: Apache-2 / CC-BY-NC-4

```sh
vision-cli depth-anything -m Depth-Anything-V2-Small-F16.gguf -i input.png -o depth.png
```

#### MI-GAN

<img width="400" height="256" alt="example-migan" src="https://github.com/user-attachments/assets/cadf1994-7677-4822-94e5-a2ee6c07621f" />

[Descarga del modelo](https://huggingface.co/Acly/MIGAN-GGUF/tree/main) | [Artículo (thecvf.com)](https://openaccess.thecvf.com/content/ICCV2023/papers/Sargsyan_MI-GAN_A_Simple_Baseline_for_Image_Inpainting_on_Mobile_Devices_ICCV_2023_paper.pdf) | [Repositorio (GitHub)](https://github.com/Picsart-AI-Research/MI-GAN) | Licencia: MIT

```sh
vision-cli migan -m MIGAN-512-places2-F16.gguf -i image.png mask.png -o output.png
```

#### Real-ESRGAN

<img width="400" height="256" alt="example-esrgan" src="https://github.com/user-attachments/assets/a41312d6-836c-4b11-ab5d-2e299ffee10c" />

[Descarga del modelo](https://huggingface.co/Acly/Real-ESRGAN-GGUF) | [Artículo (arXiv)](https://arxiv.org/abs/2107.10833) | [Repositorio (GitHub)](https://github.com/xinntao/Real-ESRGAN) | Licencia: BSD-3-Clause

```sh
vision-cli esrgan -m ESRGAN-4x-foolhardy_Remacri-F16.gguf -i input.png -o output.png
```


### Conversión de modelos

Los modelos deben convertirse a GGUF antes de poder usarse. Esto también reorganizará o precomputará tensores para una inferencia más óptima.

Para convertir un modelo, instala [uv](https://docs.astral.sh/uv/) y ejecuta:
```sh
uv run scripts/convert.py <arch> MyModel.pth
```
donde `<arch>` es uno de `sam, birefnet, esrgan, ...`.

Esto creará `models/MyModel.gguf`. Consulta `convert.py --help` para ver más opciones.

## Compilación

La compilación requiere CMake y un compilador con soporte para C++20.

**Obtener el código fuente**
```sh
git clone https://github.com/Acly/vision.cpp.git --recursive
cd vision.cpp
```

**Configurar y compilar**
```sh
cmake . -B build
cmake --build build --config Release
```

### Vulkan _(Opcional)_

Compilar con soporte para GPU Vulkan requiere que esté instalado el [Vulkan SDK](https://www.lunarg.com/vulkan-sdk/).

```sh
cmake . -B build -D VISP_VULKAN=ON
```

### Pruebas _(Opcional)_

Compila con `-DVISP_TESTS=ON`. Ejecuta todas las pruebas de C++ con el siguiente comando:
```sh
cd build
ctest -C Release
```

Algunas pruebas requieren un entorno de Python. Puede configurarse con [uv](https://docs.astral.sh/uv/):
```sh
# Setup venv and install dependencies (once only)
uv sync --dev

# Run python tests
uv run pytest
```

## Rendimiento

La optimización del rendimiento es un proceso continuo. El objetivo es estar en el mismo rango que otros frameworks en velocidad de inferencia, pero con:
* tiempos de inicialización y carga de modelos mucho más rápidos (<100 ms)
* menor sobrecarga de memoria
* tamaño de despliegue mínimo (<5 MB para CPU, +30 MB para GPU)

### Velocidad de inferencia

* CPU: AMD Ryzen 5 5600X (6 núcleos)
* GPU: NVIDIA GeForce RTX 4070

#### MobileSAM, 1024x1024

| | | _vision.cpp_ | PyTorch | ONNX Runtime |
| :--- | :--- | -----------: | ------: | -----------: |
| cpu | f32 | 669 ms | 601 ms | 805 ms |
| gpu | f16 | 19 ms | 16 ms | |

#### BiRefNet, 1024x1024

| Modelo | | | _vision.cpp_ | PyTorch | ONNX Runtime |
| :---- | :--- | :--- | -----------: | -------: | -----------: |
| Full | cpu | f32 | 16333 ms | 18290 ms | |
| Full | gpu | f16 | 208 ms | 190 ms | |
| Lite | cpu | f32 | 4505 ms | 10900 ms | 6978 ms |
| Lite | gpu | f16 | 85 ms | 84 ms | |

#### Depth-Anything, 518x714

| Modelo | | | _vision.cpp_ | PyTorch |
| :---- | :--- | :--- | -----------: | ------: |
| Small | gpu | f16 | 11 ms | 10 ms |
| Base | gpu | f16 | 24 ms | 22 ms |

#### MI-GAN, 512x512

| Modelo | | | _vision.cpp_ | PyTorch |
| :---------- | :--- | :--- | -----------: | ------: |
| 512-places2 | cpu | f32 | 523 ms | 637 ms |
| 512-places2 | gpu | f16 | 21 ms | 17 ms |

#### Configuración

* vision.cpp: usando vision-bench, GPU vía Vulkan, p. ej. `vision-bench -m sam`
* PyTorch: v2.7.1+cu128, evaluación eager, GPU vía CUDA, promedio de n iteraciones después del calentamiento (warm-up)

## Dependencias (integradas)

* [ggml](https://github.com/ggml-org/ggml) - Biblioteca de tensores para ML | MIT
* [stb-image](https://github.com/nothings/stb) - Carga/guardado/redimensionado de imágenes | Dominio Público
* [fmt](https://github.com/fmtlib/fmt) - Formateo de cadenas _(solo si el compilador no soporta &lt;format&gt;)_ | MIT
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
230 changes: 230 additions & 0 deletions README.es-ES.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@


# _vision_.cpp

Inferencia de IA/ML para Visión por Computador en C++

* Biblioteca C++ autocontenida
* Inferencia eficiente en CPUs y GPUs de consumo (NVIDIA, AMD, Intel)
* Despliegue ligero en múltiples plataformas (Windows, Linux, MacOS)
* Número creciente de modelos compatibles detrás de una API simple
* Diseño modular para control total e implementar tus propios modelos

Basado en [ggml](https://github.com/ggml-org/ggml) similar al proyecto [llama.cpp](https://github.com/ggml-org/llama.cpp).

### Características

| Modelo | Tarea | Backends |
| :--------------------------------------- | :----------------------- | :---------- |
| [**MobileSAM**](#mobilesam) | Segmentación con prompts | CPU, Vulkan |
| [**BiRefNet**](#birefnet) | Segmentación dicotómica | CPU, Vulkan |
| [**Depth-Anything**](#depth-anything-v2) | Estimación de profundidad | CPU, Vulkan |
| [**MI-GAN**](#mi-gan) | Inpainting | CPU, Vulkan |
| [**ESRGAN**](#real-esrgan) | Super-resolución | CPU, Vulkan |
| [_Implementar un modelo [**Guía**]_](docs/model-implementation-guide.md) | | |

**Backbones:** SWIN (v1), DINO (v2), TinyViT

## Primeros pasos

Obtén la biblioteca y los ejecutables:
* Descarga un [paquete de lanzamiento](https://github.com/Acly/vision.cpp/releases) y extráelo,
* o [compílalo desde el código fuente](#building).

### Ejemplo: Seleccionar un objeto en una imagen

Utilicemos MobileSAM para generar una máscara de segmentación del peluche a la derecha, pasando un recuadro que describa su ubicación aproximada.

<img width="400" height="256" alt="Example image showing box prompt at pixel location (420, 120) - (650, 430), and the output mask" src="https://github.com/user-attachments/assets/0b90ad96-c7d2-4c4c-b028-699433cef704" />

Puedes descargar el modelo y la imagen de entrada aquí: [MobileSAM-F16.gguf](https://huggingface.co/Acly/MobileSAM-GGUF/resolve/main/MobileSAM-F16.gguf) | [input.jpg](docs/media/input.jpg)


#### CLI

Busca el ejecutable `vision-cli` en la carpeta `bin` y ejecútalo para generar la máscara:

```sh
vision-cli -m MobileSAM-F16.gguf -i input.jpg -p 420 120 650 430 -o mask.png
```
Para combinar la entrada y la máscara, pasa `--composite output.png`. Usa `--help` para ver más opciones.

#### API

```c++
#include <visp/vision.h>
using namespace visp;

void main() {
backend_device cpu = backend_init(backend_type::cpu);
sam_model sam = sam_load_model("MobileSAM-F16.gguf", cpu);

image_data input_image = image_load("input.jpg");
sam_encode(sam, input_image);

image_data object_mask = sam_compute(sam, box_2d{{420, 120}, {650, 320}});
image_save(object_mask, "mask.png");
}
```
Esto muestra la API de alto nivel. Internamente, está compuesta por múltiples funciones más pequeñas que manejan la carga del modelo, el preprocesamiento de entradas, la transferencia de datos a los dispositivos backend, el postprocesamiento de la salida, etc. Estas pueden usarse como bloques de construcción para funciones flexibles que se integren con tus fuentes de datos e infraestructura existentes.



## Modelos

#### MobileSAM

<img width="400" height="256" alt="example-sam" src="https://github.com/user-attachments/assets/9c0fe151-9990-4bb1-b954-7caff560b110" />

[Descarga del modelo](https://huggingface.co/Acly/MobileSAM-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/pdf/2306.14289.pdf) | [Repositorio (GitHub)](https://github.com/ChaoningZhang/MobileSAM) | [Segment-Anything-Model](https://segment-anything.com/) | Licencia: Apache-2

```sh
vision-cli sam -m MobileSAM-F16.gguf -i input.png -p 300 200 -o mask.png --composite comp.png
```

#### BiRefNet

<img width="400" height="256" alt="example-birefnet" src="https://github.com/user-attachments/assets/6fce086d-cb89-4717-92a6-9f4a20532b3c" />

[Descarga del modelo](https://huggingface.co/Acly/BiRefNet-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/pdf/2401.03407) | [Repositorio (GitHub)](https://github.com/ZhengPeng7/BiRefNet) | Licencia: MIT

```sh
vision-cli birefnet -m BiRefNet-lite-F16.gguf -i input.png -o mask.png --composite comp.png
```

#### Depth-Anything V2

<img width="400" height="256" alt="example-depth-anything" src="https://github.com/user-attachments/assets/62bde481-b898-4c46-a298-644198716953" />

[Descarga del modelo](https://huggingface.co/Acly/Depth-Anything-V2-GGUF/tree/main) | [Artículo (arXiv)](https://arxiv.org/abs/2406.09414) | [Repositorio (GitHub)](https://github.com/DepthAnything/Depth-Anything-V2) | Licencia: Apache-2 / CC-BY-NC-4

```sh
vision-cli depth-anything -m Depth-Anything-V2-Small-F16.gguf -i input.png -o depth.png
```

#### MI-GAN

<img width="400" height="256" alt="example-migan" src="https://github.com/user-attachments/assets/cadf1994-7677-4822-94e5-a2ee6c07621f" />

[Descarga del modelo](https://huggingface.co/Acly/MIGAN-GGUF/tree/main) | [Artículo (thecvf.com)](https://openaccess.thecvf.com/content/ICCV2023/papers/Sargsyan_MI-GAN_A_Simple_Baseline_for_Image_Inpainting_on_Mobile_Devices_ICCV_2023_paper.pdf) | [Repositorio (GitHub)](https://github.com/Picsart-AI-Research/MI-GAN) | Licencia: MIT

```sh
vision-cli migan -m MIGAN-512-places2-F16.gguf -i image.png mask.png -o output.png
```

#### Real-ESRGAN

<img width="400" height="256" alt="example-esrgan" src="https://github.com/user-attachments/assets/a41312d6-836c-4b11-ab5d-2e299ffee10c" />

[Descarga del modelo](https://huggingface.co/Acly/Real-ESRGAN-GGUF) | [Artículo (arXiv)](https://arxiv.org/abs/2107.10833) | [Repositorio (GitHub)](https://github.com/xinntao/Real-ESRGAN) | Licencia: BSD-3-Clause

```sh
vision-cli esrgan -m ESRGAN-4x-foolhardy_Remacri-F16.gguf -i input.png -o output.png
```


### Conversión de modelos

Los modelos deben convertirse a GGUF antes de poder usarse. Esto también reorganizará o precomputará tensores para una inferencia más óptima.

Para convertir un modelo, instala [uv](https://docs.astral.sh/uv/) y ejecuta:
```sh
uv run scripts/convert.py <arch> MyModel.pth
```
donde `<arch>` es uno de `sam, birefnet, esrgan, ...`.

Esto creará `models/MyModel.gguf`. Consulta `convert.py --help` para ver más opciones.

## Compilación

La compilación requiere CMake y un compilador con soporte para C++20.

**Obtener el código fuente**
```sh
git clone https://github.com/Acly/vision.cpp.git --recursive
cd vision.cpp
```

**Configurar y compilar**
```sh
cmake . -B build
cmake --build build --config Release
```

### Vulkan _(Opcional)_

Compilar con soporte para GPU Vulkan requiere que esté instalado el [Vulkan SDK](https://www.lunarg.com/vulkan-sdk/).

```sh
cmake . -B build -D VISP_VULKAN=ON
```

### Pruebas _(Opcional)_

Compila con `-DVISP_TESTS=ON`. Ejecuta todas las pruebas de C++ con el siguiente comando:
```sh
cd build
ctest -C Release
```

Algunas pruebas requieren un entorno de Python. Puede configurarse con [uv](https://docs.astral.sh/uv/):
```sh
# Setup venv and install dependencies (once only)
uv sync --dev

# Run python tests
uv run pytest
```

## Rendimiento

La optimización del rendimiento es un proceso continuo. El objetivo es estar en el mismo rango que otros frameworks en velocidad de inferencia, pero con:
* tiempos de inicialización y carga de modelos mucho más rápidos (<100 ms)
* menor sobrecarga de memoria
* tamaño de despliegue mínimo (<5 MB para CPU, +30 MB para GPU)

### Velocidad de inferencia

* CPU: AMD Ryzen 5 5600X (6 núcleos)
* GPU: NVIDIA GeForce RTX 4070

#### MobileSAM, 1024x1024

| | | _vision.cpp_ | PyTorch | ONNX Runtime |
| :--- | :--- | -----------: | ------: | -----------: |
| cpu | f32 | 669 ms | 601 ms | 805 ms |
| gpu | f16 | 19 ms | 16 ms | |

#### BiRefNet, 1024x1024

| Modelo | | | _vision.cpp_ | PyTorch | ONNX Runtime |
| :---- | :--- | :--- | -----------: | -------: | -----------: |
| Full | cpu | f32 | 16333 ms | 18290 ms | |
| Full | gpu | f16 | 208 ms | 190 ms | |
| Lite | cpu | f32 | 4505 ms | 10900 ms | 6978 ms |
| Lite | gpu | f16 | 85 ms | 84 ms | |

#### Depth-Anything, 518x714

| Modelo | | | _vision.cpp_ | PyTorch |
| :---- | :--- | :--- | -----------: | ------: |
| Small | gpu | f16 | 11 ms | 10 ms |
| Base | gpu | f16 | 24 ms | 22 ms |

#### MI-GAN, 512x512

| Modelo | | | _vision.cpp_ | PyTorch |
| :---------- | :--- | :--- | -----------: | ------: |
| 512-places2 | cpu | f32 | 523 ms | 637 ms |
| 512-places2 | gpu | f16 | 21 ms | 17 ms |

#### Configuración

* vision.cpp: usando vision-bench, GPU vía Vulkan, p. ej. `vision-bench -m sam`
* PyTorch: v2.7.1+cu128, evaluación eager, GPU vía CUDA, promedio de n iteraciones después del calentamiento (warm-up)

## Dependencias (integradas)

* [ggml](https://github.com/ggml-org/ggml) - Biblioteca de tensores para ML | MIT
* [stb-image](https://github.com/nothings/stb) - Carga/guardado/redimensionado de imágenes | Dominio Público
* [fmt](https://github.com/fmtlib/fmt) - Formateo de cadenas _(solo si el compilador no soporta &lt;format&gt;)_ | MIT