# GroundingDINO

Détectez n'importe quel objet en utilisant des descriptions textuelles avec GroundingDINO.

{% hint style="success" %}
Tous les exemples peuvent être exécutés sur des serveurs GPU loués via [CLORE.AI Marketplace](https://clore.ai/marketplace).
{% endhint %}

{% hint style="info" %}
Tous les exemples de ce guide peuvent être exécutés sur des serveurs GPU loués via [CLORE.AI Marketplace](https://clore.ai/marketplace) le marketplace.
{% endhint %}

## Location sur CLORE.AI

1. Visitez [CLORE.AI Marketplace](https://clore.ai/marketplace)
2. Filtrer par type de GPU, VRAM et prix
3. Choisir **À la demande** (tarif fixe) ou **Spot** (prix d'enchère)
4. Configurez votre commande :
   * Sélectionnez l'image Docker
   * Définissez les ports (TCP pour SSH, HTTP pour les interfaces web)
   * Ajoutez des variables d'environnement si nécessaire
   * Entrez la commande de démarrage
5. Sélectionnez le paiement : **CLORE**, **BTC**, ou **USDT/USDC**
6. Créez la commande et attendez le déploiement

### Accédez à votre serveur

* Trouvez les détails de connexion dans **Mes commandes**
* Interfaces Web : utilisez l'URL du port HTTP
* SSH : `ssh -p <port> root@<adresse-proxy>`

## Qu'est-ce que GroundingDINO ?

GroundingDINO par IDEA-Research permet :

* Détection d'objets zero-shot avec des invites textuelles
* Détecter n'importe quel objet sans entraînement
* Localisation de boîtes englobantes haute précision
* Combiner avec SAM pour la segmentation automatique

## Ressources

* **GitHub :** [IDEA-Research/GroundingDINO](https://github.com/IDEA-Research/GroundingDINO)
* **Article :** [Article GroundingDINO](https://arxiv.org/abs/2303.05499)
* **HuggingFace :** [IDEA-Research/grounding-dino](https://huggingface.co/IDEA-Research/grounding-dino-base)
* **Démo :** [Espace HuggingFace](https://huggingface.co/spaces/IDEA-Research/Grounding_DINO_Demo)

## Matériel recommandé

| Composant | Minimum       | Recommandé    | Optimal       |
| --------- | ------------- | ------------- | ------------- |
| GPU       | RTX 3060 12GB | RTX 4080 16GB | RTX 4090 24GB |
| VRAM      | 6 Go          | 12Go          | 16Go          |
| CPU       | 4 cœurs       | 8 cœurs       | 16 cœurs      |
| RAM       | 16Go          | 32Go          | 64Go          |
| Stockage  | SSD 20 Go     | 50Go NVMe     | 100Go NVMe    |
| Internet  | 100 Mbps      | 500 Mbps      | 1 Gbps        |

## Déploiement rapide sur CLORE.AI

**Image Docker :**

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

**Ports :**

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

**Commande :**

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

## Accéder à votre service

Après le déploiement, trouvez votre `http_pub` URL dans **Mes commandes**:

1. Aller à la **Mes commandes** page
2. Cliquez sur votre commande
3. Trouvez l' `http_pub` URL (par ex., `abc123.clorecloud.net`)

Utilisez `https://VOTRE_HTTP_PUB_URL` au lieu de `localhost` dans les exemples ci-dessous.

## Installation

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

# Télécharger les poids
mkdir weights
cd weights
wget https://github.com/IDEA-Research/GroundingDINO/releases/download/v0.1.0-alpha/groundingdino_swint_ogc.pth
```

## Ce que vous pouvez créer

### Étiquetage automatisé

* Auto-annoter des jeux de données pour l'entraînement ML
* Générer des boîtes englobantes à partir de descriptions
* Accélérer les pipelines d'étiquetage de données

### Recherche visuelle

* Trouver des objets spécifiques dans des bases d'images
* Systèmes de modération de contenu
* Reconnaissance de produits dans le commerce de détail

### Robotique et automatisation

* Localisation d'objets pour bras robotiques
* Systèmes de gestion des stocks
* Inspection de contrôle qualité

### Applications créatives

* Rogner automatiquement les sujets des photos
* Générer des masques d'objet avec SAM
* Édition d'image intelligente selon le contenu

### Analyse

* Compter les objets dans les images
* Suivre l'inventaire à partir de photos
* Surveillance de la faune

## Utilisation de base

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

# Charger le modèle
model = load_model(
    "groundingdino/config/GroundingDINO_SwinT_OGC.py",
    "weights/groundingdino_swint_ogc.pth"
)

# Charger l'image
image_source, image = load_image("input.jpg")

# Détecter des objets
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
)

# Annoter l'image
annotated_frame = annotate(
    image_source=image_source,
    boxes=boxes,
    logits=logits,
    phrases=phrases
)

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

## GroundingDINO + SAM (Grounded-SAM)

Combiner la détection avec la segmentation :

```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

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

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

# Charger l'image
image_source, image = load_image("input.jpg")

# Détecter avec GroundingDINO
boxes, logits, phrases = predict(
    model=dino_model,
    image=image,
    caption="person . car",
    box_threshold=0.35,
    text_threshold=0.25
)

# Segmenter avec SAM
sam_predictor.set_image(image_source)

# Convertir les boîtes au format 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)
```

## Traitement par lots

```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")
```

## Pipeline de détection personnalisé

```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 en coordonnées absolues
    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

# Détecter voitures et personnes
results = detect_and_export(
    "street.jpg",
    "car . person . bicycle . traffic light",
    "detections.json"
)
```

## Interface 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):
    # Sauvegarder l'image temporaire
    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="Image d'entrée"),
        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 - Open-Set Object Detection",
    description="Detect any object by describing it in text. Running on CLORE.AI GPU servers."
)

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

## Performances

| Tâche                          | Résolution | GPU      | Vitesse |
| ------------------------------ | ---------- | -------- | ------- |
| Image unique                   | 800x600    | RTX 3090 | 120ms   |
| Image unique                   | 800x600    | RTX 4090 | 80 ms   |
| Image unique                   | 1920x1080  | RTX 4090 | 150ms   |
| Traitement par lot (10 images) | 800x600    | RTX 4090 | 600ms   |

## Problèmes courants et solutions

### Faible précision de détection

**Problème :** Objets non détectés

**Solutions :**

* Plus bas `box_threshold` à 0.2-0.3
* Plus bas `text_threshold` à 0.15-0.2
* Utiliser des descriptions d'objet plus spécifiques
* Séparer les objets avec " . " et non des virgules

```python

# Bon format d'invite
TEXT_PROMPT = "red car . person wearing hat . wooden chair"

# Mauvais format d'invite
TEXT_PROMPT = "red car, person wearing hat, wooden chair"
```

### Mémoire insuffisante

**Problème :** OOM CUDA sur les grandes images

**Solutions :**

```python

# Redimensionner les grandes images avant la détection
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)
```

### Inférence lente

**Problème :** La détection prend trop de temps

**Solutions :**

* Utiliser des images d'entrée plus petites
* Traiter plusieurs images par lot
* Utiliser l'inférence FP16
* Louer un GPU plus rapide (RTX 4090, A100)

### Faux positifs

**Problème :** Détection d'objets incorrects

**Solutions :**

* Augmentez `box_threshold` à 0.4-0.5
* Être plus précis dans les invites
* Utiliser des invites négatives (filtrer les résultats après détection)

```python

# Filtrer les détections à faible confiance
filtered = [(b, l, p) for b, l, p in zip(boxes, logits, phrases) if l > 0.5]
```

## Dépannage

### Objets non détectés

* Utiliser des descriptions textuelles plus spécifiques
* Essayer différentes formulations
* Abaisser le seuil de confiance

### Boîtes englobantes incorrectes

* Être plus précis dans l'invite textuelle
* Utiliser "." pour séparer plusieurs objets
* Vérifier la qualité des images

{% hint style="danger" %}
**Mémoire insuffisante**
{% endhint %}

* Réduire la résolution de l'image
* Traiter les images une par une
* Utiliser une variante de modèle plus petite

### Inférence lente

* Utiliser TensorRT pour accélérer
* Traiter par lots des images de taille similaire
* Activer l'inférence FP16

## Estimation des coûts

Tarifs typiques du marché CLORE.AI (à partir de 2024) :

| GPU       | Tarif horaire | Tarif journalier | Session de 4 heures |
| --------- | ------------- | ---------------- | ------------------- |
| 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             |

*Les prix varient selon le fournisseur et la demande. Vérifiez* [*CLORE.AI Marketplace*](https://clore.ai/marketplace) *pour les tarifs actuels.*

**Économisez de l'argent :**

* Utilisez **Spot** market pour les charges de travail flexibles (souvent 30-50 % moins cher)
* Payer avec **CLORE** jetons
* Comparer les prix entre différents fournisseurs

## Prochaines étapes

* [SAM2](https://docs.clore.ai/guides/guides_v2-fr/modeles-de-vision/sam2-video) - Segmenter les objets détectés
* [Florence-2](https://docs.clore.ai/guides/guides_v2-fr/modeles-de-vision/florence2) - Plus de tâches de vision
* [YOLO](https://docs.clore.ai/guides/guides_v2-fr/vision-par-ordinateur/yolov8-detection) - Détection plus rapide pour des classes connues
