# GroundingDINO

Detecta cualquier objeto usando descripciones de texto con GroundingDINO.

{% hint style="success" %}
Todos los ejemplos se pueden ejecutar en servidores GPU alquilados a través de [CLORE.AI Marketplace](https://clore.ai/marketplace).
{% endhint %}

{% hint style="info" %}
Todos los ejemplos en esta guía se pueden ejecutar en servidores GPU alquilados a través de [CLORE.AI Marketplace](https://clore.ai/marketplace) mercado.
{% endhint %}

## Alquilar en CLORE.AI

1. Visita [CLORE.AI Marketplace](https://clore.ai/marketplace)
2. Filtrar por tipo de GPU, VRAM y precio
3. Elegir **Bajo demanda** (tarifa fija) o **Spot** (precio de puja)
4. Configura tu pedido:
   * Selecciona imagen Docker
   * Establece puertos (TCP para SSH, HTTP para interfaces web)
   * Agrega variables de entorno si es necesario
   * Introduce el comando de inicio
5. Selecciona pago: **CLORE**, **BTC**, o **USDT/USDC**
6. Crea el pedido y espera el despliegue

### Accede a tu servidor

* Encuentra los detalles de conexión en **Mis Pedidos**
* Interfaces web: Usa la URL del puerto HTTP
* SSH: `ssh -p <port> root@<proxy-address>`

## ¿Qué es GroundingDINO?

GroundingDINO de IDEA-Research permite:

* Detección de objetos zero-shot con indicaciones de texto
* Detectar cualquier objeto sin entrenamiento
* Localización de cuadros delimitadores de alta precisión
* Combinar con SAM para segmentación automática

## Recursos

* **GitHub:** [IDEA-Research/GroundingDINO](https://github.com/IDEA-Research/GroundingDINO)
* **Artículo:** [Documento de GroundingDINO](https://arxiv.org/abs/2303.05499)
* **HuggingFace:** [IDEA-Research/grounding-dino](https://huggingface.co/IDEA-Research/grounding-dino-base)
* **Demostración:** [Espacio de HuggingFace](https://huggingface.co/spaces/IDEA-Research/Grounding_DINO_Demo)

## Hardware recomendado

| Componente     | Mínimo        | Recomendado   | Óptimo        |
| -------------- | ------------- | ------------- | ------------- |
| GPU            | RTX 3060 12GB | RTX 4080 16GB | RTX 4090 24GB |
| VRAM           | 6GB           | 12GB          | 16GB          |
| CPU            | 4 núcleos     | 8 núcleos     | 16 núcleos    |
| RAM            | 16GB          | 32GB          | 64GB          |
| Almacenamiento | SSD de 20 GB  | 50GB NVMe     | 100GB NVMe    |
| Internet       | 100 Mbps      | 500 Mbps      | 1 Gbps        |

## Despliegue rápido en CLORE.AI

**Imagen Docker:**

```
pytorch/pytorch:2.5.1-cuda12.4-cudnn9-devel
```

**Puertos:**

```
22/tcp
7860/http
```

**Comando:**

```bash
cd /workspace && \
git clone https://github.com/IDEA-Research/GroundingDINO.git && \
cd GroundingDINO && \
pip install -e . && \
python demo/gradio_demo.py
```

## Accediendo a tu servicio

Después del despliegue, encuentra tu `http_pub` URL en **Mis Pedidos**:

1. Ir a **Mis Pedidos** página
2. Haz clic en tu pedido
3. Encuentra la `http_pub` URL (por ejemplo, `abc123.clorecloud.net`)

Usa `https://TU_HTTP_PUB_URL` en lugar de `localhost` en los ejemplos abajo.

## Instalación

```bash
git clone https://github.com/IDEA-Research/GroundingDINO.git
cd GroundingDINO
pip install -e .

# Descargar pesos
mkdir weights
cd weights
wget https://github.com/IDEA-Research/GroundingDINO/releases/download/v0.1.0-alpha/groundingdino_swint_ogc.pth
```

## Lo que puedes crear

### Etiquetado automatizado

* Auto-anotar conjuntos de datos para entrenamiento de ML
* Generar cuadros delimitadores a partir de descripciones
* Acelerar las canalizaciones de etiquetado de datos

### Búsqueda visual

* Encontrar objetos específicos en bases de imágenes
* Sistemas de moderación de contenido
* Reconocimiento de productos en retail

### Robótica y automatización

* Localización de objetos para brazos robóticos
* Sistemas de gestión de inventario
* Inspección de control de calidad

### Aplicaciones creativas

* Recortar automáticamente sujetos de fotos
* Generar máscaras de objetos con SAM
* Edición de imágenes consciente del contenido

### Analítica

* Contar objetos en imágenes
* Rastrear inventario desde fotos
* Monitoreo de vida silvestre

## Uso básico

```python
from groundingdino.util.inference import load_model, load_image, predict, annotate
import cv2

# Cargar modelo
model = load_model(
    "groundingdino/config/GroundingDINO_SwinT_OGC.py",
    "weights/groundingdino_swint_ogc.pth"
)

# Cargar imagen
image_source, image = load_image("input.jpg")

# Detectar objetos
TEXT_PROMPT = "cat . dog . person"
BOX_THRESHOLD = 0.35
TEXT_THRESHOLD = 0.25

boxes, logits, phrases = predict(
    model=model,
    image=image,
    caption=TEXT_PROMPT,
    box_threshold=BOX_THRESHOLD,
    text_threshold=TEXT_THRESHOLD
)

# Anotar imagen
annotated_frame = annotate(
    image_source=image_source,
    boxes=boxes,
    logits=logits,
    phrases=phrases
)

cv2.imwrite("output.jpg", annotated_frame)
```

## GroundingDINO + SAM (Grounded-SAM)

Combinar detección con segmentación:

```python
import torch
import numpy as np
from groundingdino.util.inference import load_model, load_image, predict
from segment_anything import sam_model_registry, SamPredictor

# Cargar GroundingDINO
dino_model = load_model(
    "groundingdino/config/GroundingDINO_SwinT_OGC.py",
    "weights/groundingdino_swint_ogc.pth"
)

# Cargar SAM
sam = sam_model_registry["vit_h"](checkpoint="sam_vit_h_4b8939.pth")
sam.to(device="cuda")
sam_predictor = SamPredictor(sam)

# Cargar imagen
image_source, image = load_image("input.jpg")

# Detectar con GroundingDINO
boxes, logits, phrases = predict(
    model=dino_model,
    image=image,
    caption="person . car",
    box_threshold=0.35,
    text_threshold=0.25
)

# Segmentar con SAM
sam_predictor.set_image(image_source)

# Convertir cajas al formato de SAM
H, W = image_source.shape[:2]
boxes_xyxy = boxes * torch.tensor([W, H, W, H])

masks = []
for box in boxes_xyxy:
    mask, _, _ = sam_predictor.predict(
        box=box.numpy(),
        multimask_output=False
    )
    masks.append(mask)
```

## Procesamiento por lotes

```python
import os
from groundingdino.util.inference import load_model, load_image, predict, annotate
import cv2

model = load_model(
    "groundingdino/config/GroundingDINO_SwinT_OGC.py",
    "weights/groundingdino_swint_ogc.pth"
)

input_dir = "./images"
output_dir = "./detected"
os.makedirs(output_dir, exist_ok=True)

TEXT_PROMPT = "product . price tag . barcode"

for filename in os.listdir(input_dir):
    if not filename.endswith(('.jpg', '.png')):
        continue

    image_path = os.path.join(input_dir, filename)
    image_source, image = load_image(image_path)

    boxes, logits, phrases = predict(
        model=model,
        image=image,
        caption=TEXT_PROMPT,
        box_threshold=0.3,
        text_threshold=0.25
    )

    annotated = annotate(image_source, boxes, logits, phrases)
    cv2.imwrite(os.path.join(output_dir, filename), annotated)

    print(f"{filename}: Found {len(boxes)} objects")
```

## Canalización de detección personalizada

```python
from groundingdino.util.inference import load_model, load_image, predict
import json

model = load_model(
    "groundingdino/config/GroundingDINO_SwinT_OGC.py",
    "weights/groundingdino_swint_ogc.pth"
)

def detect_and_export(image_path, prompt, output_json):
    image_source, image = load_image(image_path)
    H, W = image_source.shape[:2]

    boxes, logits, phrases = predict(
        model=model,
        image=image,
        caption=prompt,
        box_threshold=0.35,
        text_threshold=0.25
    )

    # Convertir a coordenadas absolutas
    detections = []
    for box, logit, phrase in zip(boxes, logits, phrases):
        x1, y1, x2, y2 = box * torch.tensor([W, H, W, H])
        detections.append({
            "label": phrase,
            "confidence": float(logit),
            "bbox": {
                "x1": int(x1),
                "y1": int(y1),
                "x2": int(x2),
                "y2": int(y2)
            }
        })

    with open(output_json, "w") as f:
        json.dump(detections, f, indent=2)

    return detections

# Detectar autos y personas
results = detect_and_export(
    "street.jpg",
    "car . person . bicycle . traffic light",
    "detections.json"
)
```

## Interfaz Gradio

```python
import gradio as gr
import cv2
from groundingdino.util.inference import load_model, load_image, predict, annotate
import tempfile
import numpy as np

model = load_model(
    "groundingdino/config/GroundingDINO_SwinT_OGC.py",
    "weights/groundingdino_swint_ogc.pth"
)

def detect_objects(image, text_prompt, box_threshold, text_threshold):
    # Guardar imagen temporal
    with tempfile.NamedTemporaryFile(suffix=".jpg", delete=False) as f:
        cv2.imwrite(f.name, cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR))
        image_source, img = load_image(f.name)

    boxes, logits, phrases = predict(
        model=model,
        image=img,
        caption=text_prompt,
        box_threshold=box_threshold,
        text_threshold=text_threshold
    )

    annotated = annotate(image_source, boxes, logits, phrases)
    annotated_rgb = cv2.cvtColor(annotated, cv2.COLOR_BGR2RGB)

    return annotated_rgb, f"Found {len(boxes)} objects: {', '.join(phrases)}"

demo = gr.Interface(
    fn=detect_objects,
    inputs=[
        gr.Image(type="pil", label="Imagen de entrada"),
        gr.Textbox(label="Objects to Detect", value="person . car . dog", placeholder="object1 . object2 . object3"),
        gr.Slider(0.1, 0.9, value=0.35, label="Box Threshold"),
        gr.Slider(0.1, 0.9, value=0.25, label="Text Threshold")
    ],
    outputs=[
        gr.Image(label="Detection Result"),
        gr.Textbox(label="Summary")
    ],
    title="GroundingDINO - Detección de objetos de conjunto abierto",
    description="Detecta cualquier objeto describiéndolo en texto. Ejecutándose en servidores GPU de CLORE.AI."
)

demo.launch(server_name="0.0.0.0", server_port=7860)
```

## Rendimiento

| Tarea              | Resolución | GPU      | Velocidad |
| ------------------ | ---------- | -------- | --------- |
| Imagen única       | 800x600    | RTX 3090 | 120ms     |
| Imagen única       | 800x600    | RTX 4090 | 80ms      |
| Imagen única       | 1920x1080  | RTX 4090 | 150ms     |
| Lote (10 imágenes) | 800x600    | RTX 4090 | 600ms     |

## Problemas comunes y soluciones

### Baja precisión de detección

**Problema:** Objetos que no se detectan

**Soluciones:**

* Reduce `box_threshold` a 0.2-0.3
* Reduce `text_threshold` a 0.15-0.2
* Usar descripciones de objetos más específicas
* Separar objetos con " . " no con comas

```python

# Buen formato de indicación
TEXT_PROMPT = "red car . person wearing hat . wooden chair"

# Mal formato de indicación
TEXT_PROMPT = "red car, person wearing hat, wooden chair"
```

### Memoria insuficiente

**Problema:** CUDA OOM en imágenes grandes

**Soluciones:**

```python

# Redimensionar imágenes grandes antes de la detección
from PIL import Image

def resize_if_needed(image_path, max_size=1280):
    img = Image.open(image_path)
    if max(img.size) > max_size:
        ratio = max_size / max(img.size)
        new_size = (int(img.width * ratio), int(img.height * ratio))
        img = img.resize(new_size, Image.LANCZOS)
        img.save(image_path)
```

### Inferencia lenta

**Problema:** La detección toma demasiado tiempo

**Soluciones:**

* Usar imágenes de entrada más pequeñas
* Procesar múltiples imágenes por lotes
* Usar inferencia en FP16
* Alquilar GPU más rápida (RTX 4090, A100)

### Falsos positivos

**Problema:** Detectando objetos incorrectos

**Soluciones:**

* Aumente `box_threshold` a 0.4-0.5
* Ser más específico en las indicaciones
* Usar indicaciones negativas (filtrar resultados después de la detección)

```python

# Filtrar detecciones de baja confianza
filtered = [(b, l, p) for b, l, p in zip(boxes, logits, phrases) if l > 0.5]
```

## Solución de problemas

### Objetos no detectados

* Usar descripciones de texto más específicas
* Probar diferentes redacciones
* Bajar el umbral de confianza

### Cuadros delimitadores incorrectos

* Ser más específico en la indicación de texto
* Usar "." para separar múltiples objetos
* Comprobar la calidad de las imágenes

{% hint style="danger" %}
**Fuera de memoria**
{% endhint %}

* Reducir la resolución de la imagen
* Procesar imágenes una a la vez
* Usar una variante de modelo más pequeña

### Inferencia lenta

* Usar TensorRT para aceleración
* Agrupar imágenes de tamaño similar por lotes
* Habilitar inferencia FP16

## Estimación de costos

Tarifas típicas del marketplace de CLORE.AI (a fecha de 2024):

| GPU       | Tarifa por hora | Tarifa diaria | Sesión de 4 horas |
| --------- | --------------- | ------------- | ----------------- |
| RTX 3060  | \~$0.03         | \~$0.70       | \~$0.12           |
| RTX 3090  | \~$0.06         | \~$1.50       | \~$0.25           |
| RTX 4090  | \~$0.10         | \~$2.30       | \~$0.40           |
| A100 40GB | \~$0.17         | \~$4.00       | \~$0.70           |
| A100 80GB | \~$0.25         | \~$6.00       | \~$1.00           |

*Los precios varían según el proveedor y la demanda. Consulta* [*CLORE.AI Marketplace*](https://clore.ai/marketplace) *para las tarifas actuales.*

**Ahorra dinero:**

* Usa **Spot** market para cargas de trabajo flexibles (a menudo 30-50% más barato)
* Paga con **CLORE** tokens
* Compara precios entre diferentes proveedores

## Próximos pasos

* [SAM2](https://docs.clore.ai/guides/guides_v2-es/modelos-de-vision/sam2-video) - Segmentar objetos detectados
* [Florence-2](https://docs.clore.ai/guides/guides_v2-es/modelos-de-vision/florence2) - Más tareas de visión
* [YOLO](https://docs.clore.ai/guides/guides_v2-es/vision-por-computadora/yolov8-detection) - Detección más rápida para clases conocidas
