Spatial Transformer Networks : Guide Complet — Invariance Spatiale Apprise

151-spatial-transformer-network

Spatial Transformer Network : Guide Complet — Invariance Spatiale Apprise

Résumé

Les Spatial Transformer Networks (STN) constituent l’une des idées les plus élégantes du deep learning apparues ces dernières années. Introduits en 2015 par Max Jaderberg, Karen Simonyan, Andrew Zisserman et Koray Kavukcuoglu, ils offrent une solution fondamentale à un problème ancien de la vision par ordinateur : l’invariance spatiale.

Un réseau de neurones convolutif classique apprend très bien à reconnaître des motifs visuels, mais il est terriblement vulnérable aux transformations géométriques. Un même chiffre « 7 » légèrement tourné de trente degrés peut être classifié à tort par un CNN qui n’a jamais vu un « 7 » sous cet angle. Le Spatial Transformer Network résout ce problème en apprenant à transformer activement les données d’entrée avant de les traiter — de manière entièrement différentiable, directement dans la boucle d’entraînement du réseau.

Contrairement à des techniques de data augmentation qui se contentent de montrer des exemples variés au réseau, le STN lui apprend à s’adapter dynamiquement. Chaque image est transformée au cas par cas, selon ce que le réseau lui-même estime optimal pour la reconnaître. C’est une véritable invariance spatiale apprise, et non une augmentation passive des données d’entraînement.

Dans ce guide complet, nous explorerons le principe mathématique du Spatial Transformer Network, l’intuition derrière son fonctionnement, une implémentation détaillée en PyTorch, ainsi que ses cas d’usage pratiques.

Principe Mathématique

Le Spatial Transformer Network se compose de trois modules fonctionnels qui travaillent en séquence : le Réseau de Localisation, le Générateur de Grille et l’Échantillonneur. Ensemble, ces trois composants forment un bloc entièrement différentiable qui peut être inséré à n’importe quel endroit d’un réseau convolutif existant.

Architecture Générale

$$STN = \text{Réseau de Localisation} + \text{Générateur de Grille} + \text{Échantillonneur}$$

Chaque module joue un rôle précis dans la transformation de l’image d’entrée. Voyons-les en détail.

1. Réseau de Localisation (Localisation Network)

Le réseau de localisation est lui-même un petit réseau de neurones qui examine l’image d’entrée $X$ et produit les paramètres de transformation $\theta$. On note cette opération :

$$\theta = f_{loc}(X)$$

où $\theta$ est une matrice de transformation affine de dimension $2 \times 3$ :

$$\theta = \begin{bmatrix} a_{11} & a_{12} & b_1 \ a_{21} & a_{22} & b_2 \end{bmatrix}$$

Les six paramètres $a_{11}, a_{12}, a_{21}, a_{22}, b_1, b_2$ encodent les transformations géométriques à appliquer à l’image :

  • $a_{11}, a_{22}$ : facteurs d’échelle horizontale et verticale (zoom avant/arrière)
  • $a_{12}, a_{21}$ : composantes de cisaillement et de rotation
  • $b_1, b_2$ : translations horizontale et verticale

Par exemple, une rotation pure d’angle $\phi$ s’écrit :

$$\theta_{rotation} = \begin{bmatrix} \cos(\phi) & -\sin(\phi) & 0 \ \sin(\phi) & \cos(\phi) & 0 \end{bmatrix}$$

Une translation de $(t_x, t_y)$ en pixels s’écrit :

$$\theta_{translation} = \begin{bmatrix} 1 & 0 & t_x/H \ 0 & 1 & t_y/W \end{bmatrix}$$

Le réseau de localisation est typiquement constitué de couches convolutives suivies de couches entièrement connectées qui produisent finalement les six valeurs de $\theta$. L’astuce cruciale est que la dernière couche du localiseur n’utilise aucune fonction d’activation — les paramètres de transformation doivent pouvoir prendre n’importe quelle valeur réelle pour représenter toutes les transformations possibles.

2. Générateur de Grille (Grid Generator)

Le générateur de grille utilise la matrice $\theta$ pour créer une grille de coordonnées qui définit comment les pixels de l’image de sortie vont être mappés aux pixels de l’image d’entrée.

Pour chaque position $(x_i^t, y_i^t)$ dans l’image cible (l’image transformée qu’on souhaite produire), on calcule la position source correspondante $(x_i^s, y_i^s)$ dans l’image d’entrée :

$$\begin{bmatrix} x_i^s \ y_i^s \end{bmatrix} = \begin{bmatrix} a_{11} & a_{12} & b_1 \ a_{21} & a_{22} & b_2 \end{bmatrix} \begin{bmatrix} x_i^t \ y_i^t \ 1 \end{bmatrix}$$

Ce qui équivaut aux équations coordonnées :

$$x_i^s = a_{11} \cdot x_i^t + a_{12} \cdot y_i^t + b_1$$
$$y_i^s = a_{21} \cdot x_i^t + a_{22} \cdot y_i^t + b_2$$

Cette opération est effectuée pour chaque pixel de la grille de sortie. Le résultat est une grille de coordonnées $(x^s, y^s)$ de même dimension que l’image cible, où chaque cellule indique « d’où tirer la valeur de ce pixel dans l’image source ».

Cette approche — échantillonner en partant des coordonnées de la grille cible plutôt que des coordonnées de l’image source — est appelée échantillonnage inverse (inverse warping). Elle garantit que chaque pixel de la sortie reçoit exactement une valeur, sans trous ni superpositions.

3. Échantillonneur (Sampler)

La grille $(x_i^s, y_i^s)$ contient des coordonnées continues (à virgule flottante), mais les pixels de l’image d’entrée sont sur une grille discrète de coordonnées entières. L’échantillonneur doit résoudre ce problème.

On utilise l’interpolation bilinéaire, qui calcule la valeur d’un pixel cible comme une moyenne pondérée des quatre pixels les plus proches dans l’image source :

$$V_i^c = \sum_k \max(0, 1 – |x^s – x_k|) \cdot \max(0, 1 – |y^s – y_k|) \cdot U_{k}^c$$

où :
– $V_i^c$ est la valeur du canal $c$ au pixel $i$ de la sortie
– $U_{k}^c$ est la valeur du canal $c$ au pixel source $k$
– $x_k$ et $y_k$ sont les coordonnées entières des pixels voisins
– $\max(0, 1 – |x^s – x_k|)$ est le poids linéaire basé sur la distance horizontale
– $\max(0, 1 – |y^s – y_k|)$ est le poids linéaire basé sur la distance verticale

Concrètement, si une coordonnée source $(x^s, y^s)$ tombe à mi-chemin entre les pixels $(2,3)$, $(3,3)$, $(2,4)$ et $(3,4)$, le sampler interpole entre ces quatre pixels avec des poids de $0,25$ chacun. Si la coordonnée est plus proche du pixel $(3,3)$, ce dernier recevra le plus grand poids.

Différentiabilité Totale

Le point crucial — et ce qui distingue le Spatial Transformer Network d’une simple transformation d’image appliquée en prétraitement — est que toute l’opération est différentiable par rapport à $\theta$.

Le générateur de grille est une multiplication matricielle, donc différentiable. L’échantillonneur est une interpolation bilinéaire, également différentiable. Par conséquent, le gradient de la fonction de perte peut se propager à travers tout le bloc STN, jusqu’au réseau de localisation. Cela signifie que $f_{loc}$ apprend quelles transformations appliquer en fonction de la tâche finale, sans supervision explicite sur la forme des transformations.

Le STN s’intègre dans n’importe quel CNN comme un simple module interchangeable. On peut l’insérer entre deux couches convolutives, au début du réseau, ou même à plusieurs endroits.

Intuition

Pour comprendre pourquoi le Spatial Transformer Network est si puissant, il faut d’abord comprendre le problème des CNN classiques face aux transformations.

Un réseau convolutif classique apprend par cœur qu’un objet en haut à gauche de l’image est différent du même objet en bas à droite. Les filtres convolutifs détectent des motifs à des positions spécifiques dans l’image source. Bien que la convolution elle-même possède une forme de translation (un filtre détecte un motif quel que soit son emplacement local), le pooling et les couches entièrement connectées en aval ancrent les résultats à des régions spatiales spécifiques du réseau.

Cela signifie qu’un « 6 » écrit en haut à gauche et le même « 6 » écrit en bas à droite activent des neurones différents dans les couches profondes. Le réseau doit donc soit avoir vu les deux cas pendant l’entraînement (ce qui est impossible pour toutes les transformations possibles), soit généraliser de manière imparfaite.

Le Spatial Transformer agit comme les yeux qui recentrent automatiquement l’image sur la zone intéressante avant de la passer au cerveau du réseau. C’est exactement ce que font nos yeux lorsque nous lisons : ils effectuent des saccades rapides pour placer chaque mot au centre de la fovéa, la zone de vision nette de la rétine.

Pensez-y autrement : c’est comme un photographe professionnel qui recadre et redresse l’horizon avant d’envoyer la photo à l’éditeur. Le réseau en aval reçoit toujours une image « propre », centrée, avec l’orientation correcte. Il n’a pas besoin de gérer les variations de position, de rotation ou d’échelle parce que le STN s’en occupe pour lui.

Cette analogie révèle quelque chose de profond : le Spatial Transformer Network ajoute au CNN une capacité de conscience spatiale qui lui manque. Les yeux du photographe analysent la scène, trouvent le sujet intéressant, et ajustent le cadrage en conséquence. De manière similaire, le réseau de localisation analyse l’image, trouve la zone pertinente, et calcule les paramètres de transformation optimaux.

Implémentation Python avec PyTorch

Voici une implémentation complète d’un Spatial Transformer Network intégré dans un CNN pour la classification de chiffres MNIST, avec entraînement sur des images perturbées par des translations et rotations aléatoires.

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
import matplotlib.pyplot as plt
import numpy as np


class Localizer(nn.Module):
    """Réseau de localisation qui prédit les paramètres de la transformation affine."""

    def __init__(self, hidden_dim=64, num_fc_layers=3):
        super().__init__()

        # Couches convolutives pour extraire les caractéristiques
        self.conv1 = nn.Conv2d(1, 16, kernel_size=5, padding=2)
        self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)
        self.bn1 = nn.BatchNorm2d(16)
        self.bn2 = nn.BatchNorm2d(32)
        self.pool = nn.MaxPool2d(2, 2)

        # Calcul de la taille après convolutions + pooling
        # Entrée 28x28 -> conv(28) -> pool(14) -> conv(14) -> pool(7)
        self.flattened_size = 32 * 7 * 7

        # Couches entièrement connectées
        fc_layers = []
        in_dim = self.flattened_size
        for i in range(num_fc_layers - 1):
            fc_layers.append(nn.Linear(in_dim, hidden_dim))
            fc_layers.append(nn.ReLU())
            in_dim = hidden_dim
        self.fc = nn.Sequential(*fc_layers)

        # Couche finale vers les paramètres theta (2x3 = 6 valeurs)
        # Pas d'activation ! On veut une sortie linéaire
        self.fc_loc_final = nn.Linear(hidden_dim, 6)

        # Initialisation : identité par défaut pour commencer
        with torch.no_grad():
            self.fc_loc_final.weight.zero_()
            self.fc_loc_final.bias.copy_(
                torch.tensor([1.0, 0.0, 0.0, 0.0, 1.0, 0.0])
            )

    def forward(self, x):
        x = self.pool(F.relu(self.bn1(self.conv1(x))))
        x = self.pool(F.relu(self.bn2(self.conv2(x))))

        # Aplatissement
        x = x.view(-1, self.flattened_size)

        # Couches FC
        x = self.fc(x)

        # Prédiction des paramètres theta
        theta = self.fc_loc_final(x)
        theta = theta.view(-1, 2, 3)

        return theta


class STN_CNN(nn.Module):
    """CNN classique avec un module Spatial Transformer intégré."""

    def __init__(self, localizer_hidden_dim=64, localizer_fc_layers=3):
        super().__init__()

        # Module Spatial Transformer
        self.localizer = Localizer(
            hidden_dim=localizer_hidden_dim,
            num_fc_layers=localizer_fc_layers,
        )

        # CNN classique pour la classification
        self.classifier_conv = nn.Sequential(
            nn.Conv2d(1, 10, kernel_size=5),
            nn.MaxPool2d(2),
            nn.ReLU(),
            nn.Conv2d(10, 20, kernel_size=5),
            nn.Dropout2d(),
            nn.MaxPool2d(),
            nn.ReLU(),
        )

        # STN output 28x28 -> conv(24) -> pool(12) -> conv(8) -> pool(4)
        classif_size = 20 * 4 * 4
        self.classifier_fc = nn.Sequential(
            nn.Linear(classif_size, 50),
            nn.ReLU(),
            nn.Dropout(),
            nn.Linear(50, 10),
        )

    def spatial_transform(self, x):
        """Applique la transformation spatiale à l'entrée."""
        theta = self.localizer(x)
        grid = F.affine_grid(theta, x.size(), align_corners=False)
        x_transformed = F.grid_sample(x, grid, align_corners=False)
        return x_transformed, theta

    def forward(self, x):
        x_transformed, theta = self.spatial_transform(x)
        features = self.classifier_conv(x_transformed)
        features = features.view(features.size(0), -1)
        output = self.classifier_fc(features)
        return output, theta, x_transformed


def train_stn_on_mnist(
    epochs=20,
    batch_size=64,
    lr=0.01,
    hidden_dim=64,
    num_fc_layers=3,
):
    """Entraîne un STN sur MNIST avec perturbations."""

    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    print(f"Appareil : {device}")

    # Transformations : perturbation pour forcer l'apprentissage du STN
    train_transform = transforms.Compose([
        transforms.RandomAffine(
            degrees=30, translate=(0.2, 0.2), scale=(0.8, 1.2)
        ),
        transforms.ToTensor(),
        transforms.Normalize((0.1307,), (0.3081,)),
    ])

    test_transform = transforms.Compose([
        transforms.RandomAffine(degrees=30, translate=(0.2, 0.2)),
        transforms.ToTensor(),
        transforms.Normalize((0.1307,), (0.3081,)),
    ])

    train_dataset = datasets.MNIST(
        "./data", train=True, download=True, transform=train_transform
    )
    test_dataset = datasets.MNIST(
        "./data", train=False, transform=test_transform
    )

    train_loader = torch.utils.data.DataLoader(
        train_dataset, batch_size=batch_size, shuffle=True, num_workers=2
    )
    test_loader = torch.utils.data.DataLoader(
        test_dataset, batch_size=1000, shuffle=False, num_workers=2
    )

    model = STN_CNN(
        localizer_hidden_dim=hidden_dim,
        localizer_fc_layers=num_fc_layers,
    ).to(device)

    optimizer = optim.Adam(model.parameters(), lr=lr)
    scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.5)
    criterion = nn.CrossEntropyLoss()

    for epoch in range(epochs):
        model.train()
        total_loss = 0
        correct = 0
        total = 0

        for batch_idx, (data, target) in enumerate(train_loader):
            data, target = data.to(device), target.to(device)

            optimizer.zero_grad()
            output, theta, x_transformed = model(data)
            loss = criterion(output, target)
            loss.backward()
            optimizer.step()

            total_loss += loss.item()
            pred = output.argmax(dim=1)
            correct += pred.eq(target).sum().item()
            total += target.size(0)

        scheduler.step()

        model.eval()
        test_correct = 0
        test_total = 0
        with torch.no_grad():
            for data, target in test_loader:
                data, target = data.to(device), target.to(device)
                output, theta, x_transformed = model(data)
                pred = output.argmax(dim=1)
                test_correct += pred.eq(target).sum().item()
                test_total += target.size(0)

        train_acc = 100.0 * correct / total
        test_acc = 100.0 * test_correct / test_total
        avg_loss = total_loss / len(train_loader)

        print(
            f"Époque {epoch+1}/{epochs} | "
            f"Perte : {avg_loss:.4f} | "
            f"Précision entraînement : {train_acc:.1f}% | "
            f"Précision test : {test_acc:.1f}%"
        )

    return model


def visualize_transformations(model, num_samples=4):
    """Visualise les transformations appliquées par le STN."""

    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    test_transform = transforms.Compose([
        transforms.RandomAffine(degrees=30, translate=(0.2, 0.2)),
        transforms.ToTensor(),
        transforms.Normalize((0.1307,), (0.3081,)),
    ])
    test_dataset = datasets.MNIST(
        "./data", train=False, transform=test_transform
    )

    model.eval()
    fig, axes = plt.subplots(num_samples, 2, figsize=(6, 3 * num_samples))

    with torch.no_grad():
        for i in range(num_samples):
            img, label = test_dataset[i]
            img_tensor = img.unsqueeze(0).to(device)

            _, theta, transformed = model(img_tensor)

            ax1 = axes[i, 0]
            ax1.imshow(img.squeeze(), cmap="gray")
            ax1.set_title(f"Avant transformation (label={label.item()})")
            ax1.axis("off")

            ax2 = axes[i, 1]
            ax2.imshow(transformed.squeeze().cpu().numpy(), cmap="gray")

            theta_matrix = theta.squeeze().cpu().numpy()
            mat_str = "\\n".join([
                f"[{theta_matrix[0,0]:+.3f}, {theta_matrix[0,1]:+.3f}, {theta_matrix[0,2]:+.3f}]",
                f"[{theta_matrix[1,0]:+.3f}, {theta_matrix[1,1]:+.3f}, {theta_matrix[1,2]:+.3f}]",
            ])
            ax2.set_title(f"Après STN\\nθ =\\n{mat_str}")
            ax2.axis("off")

    plt.tight_layout()
    plt.savefig("stn_visualization.png", dpi=200)
    plt.show()
    print("Visualisation enregistrée : stn_visualization.png")


if __name__ == "__main__":
    model = train_stn_on_mnist(
        epochs=20,
        batch_size=64,
        lr=0.01,
        hidden_dim=64,
        num_fc_layers=3,
    )

    torch.save(model.state_dict(), "stn_mnist_model.pt")
    print("Modèle enregistré : stn_mnist_model.pt")

    visualize_transformations(model, num_samples=4)

Cette implémentation utilise F.affine_grid pour créer la grille de coordonnées et F.grid_sample pour l’interpolation bilinéaire — les deux fonctions clés de PyTorch pour l’échantillonnage spatial. Le réseau de localisation combine des couches convolutives pour l’extraction de caractéristiques et des couches entièrement connectées pour la régression des paramètres de transformation. L’initialisation vers la matrice identité garantit que le réseau de localisation commence par transformer l’image sans aucune altération, ce qui évite le problème de la transformation « cassée » dès le début de l’entraînement.

Hyperparamètres

Le choix des hyperparamètres du Spatial Transformer Network influence considérablement ses performances. Voici les paramètres les plus importants à considérer :

  • hidden_dim (Localizer) : La dimension cachée du réseau de localisation. Une valeur plus grande comme 128 ou 256 augmente la capacité d’approximation du localiseur mais augmente aussi le risque de surapprentissage. Pour des tâches simples comme MNIST, 64 est suffisant. Pour des tâches complexes avec des images naturelles, 128 à 256 est recommandé.
  • num_fc_layers : Le nombre de couches entièrement connectées dans le localiseur. Trois couches constituent un bon point de départ. Plus de couches permettent au réseau de localisation d’apprendre des relations plus complexes entre les caractéristiques de l’image et les paramètres de transformation, mais la profondeur accrue peut rendre l’entraînement plus instable.
  • Placement du STN dans le réseau : Un STN placé tôt dans le réseau opère sur les pixels bruts et apprend des transformations géométriques facilement interprétables (rotation, translation, mise à l’échelle). Un STN placé plus tard, après plusieurs couches convolutives, opère sur des cartes de caractéristiques de plus haute dimension et peut apprendre des transformations plus abstraites, mais moins interprétables visuellement.
  • Taille de la grille de sampling : Par défaut, la grille a la même dimension que l’image d’entrée. Modifier cette taille affecte la précision de l’interpolation et le coût computationnel.
  • Taux d’apprentissage du STN : Le Spatial Transformer Network peut utiliser un taux d’apprentissage différent de celui du classifieur. Un réseau de localisation avec un taux d’apprentissage plus bas apprend plus lentement les transformations, ce qui peut stabiliser l’entraînement dans les premières époques.

Avantages

  • Différentiabilité totale : le STN s’entraîne via la rétropropagation (backpropagation) standard, sans nécessiter de supervision explicite sur les transformations. Il apprend seul quelles transformations appliquer pour optimiser la tâche finale.
  • Amélioration significative de la robustesse spatiale : un CNN avec STN généralise beaucoup mieux à des images tournées, translatées, ou déformées que le même CNN sans STN, souvent avec un gain de plusieurs points de pourcentage en précision.
  • Généralité : le STN peut apprendre des transformations non rigides (au-delà de l’affine) si on lui donne une grille de déformation plus riche — on parle alors de STN dense pour des déformations locales qui affectent différentes régions de l’image de manière indépendante.
  • Composant modulaire : le Spatial Transformer Network s’insère comme un simple module dans n’importe quel réseau existant. On peut même en placer plusieurs à différents endroits du même réseau pour composer des transformations multi-échelles.
  • Interprétabilité : on peut visualiser la matrice $\theta$ produite par le réseau de localisation pour comprendre quelles transformations le réseau a apprises. C’est une fenêtre sur le raisonnement spatial du modèle, quelque chose de rare en deep learning.
  • Efficacité computationnelle : l’opération grid_sample est hautement optimisée sur GPU et ajoute un coût computationnel négligeable par rapport aux couches convolutives du classifieur principal.

Limites

  • Transformations affines uniquement : le STN de base ne peut représenter que des transformations affines (rotation, translation, mise à l’échelle, cisaillement). Pour des déformations locales non rigides, comme un visage qui sourit ou une feuille qui se plie, il faut utiliser des STN denses avec un paramétrage de grille plus riche et plus de paramètres à apprendre.
  • Dépendance à la tâche : le réseau de localisation apprend les transformations les plus utiles pour la tâche courante de classification. Si la tâche ne bénéficie pas d’un recadrage particulier, le STN peut ne pas apprendre de transformations significatives, rendant son ajout inutile pour ce cas particulier.
  • Risque de transformations dégénérées : sans régularisation appropriée ou sans initialisation vers l’identité, le réseau de localisation peut apprendre des transformations qui écrasent l’image vers zéro ou la projettent hors de l’écran, surtout au début de l’entraînement. C’est pourquoi l’initialisation vers la matrice identité est fortement recommandée.
  • Pas d’invariance totale : le STN atténue les effets des transformations spatiales, mais ne garantit pas une invariance parfaite. Il améliore la robustesse du réseau, mais ne remplace pas une bonne architecture ou une bonne augmentation des données pour les tâches exigeant une invariance absolue aux transformations géométriques.

4 Cas d’Usage Pratiques

1. OCR et Reconnaissance de Texte

En reconnaissance optique de caractères, les images de texte arrivent rarement parfaitement alignées : les pages sont légèrement tournées, les lignes sont incurvées, les lettres sont déformées par la perspective photographique. Un STN intégré dans un réseau de reconnaissance de caractères apprend à recadrer chaque mot, redresser les lignes, et corriger les déformations de perspective. C’est particulièrement utile pour la lecture de plaques d’immatriculation, la numérisation de documents manuscrits, ou la reconnaissance de caractères dans des conditions de prise de vue non contrôlées, comme celles rencontrées dans les applications mobiles de numérisation.

2. Détection et Localisation d’Objets

Dans un pipeline de détection d’objets en deux étages, un STN peut servir de module de recadrage attentionnel. Après une première passe de détection grossière qui identifie les régions d’intérêt, le réseau utilise le STN pour zoomer sur la région détectée et produire un recadrage centré sur l’objet. Cette approche permet de traiter chaque objet détecté à haute résolution sans avoir besoin de traiter l’image entière à haute résolution, ce qui réduit considérablement le coût computationnel tout en améliorant la précision de classification des objets détectés.

3. Imagerie Médicale

L’alignement d’images médicales est un problème fondamental en analyse d’images cliniques : une IRM du même patient prise à deux jours différents présente des déplacements et des déformations entre les deux acquisitions. L’utilisation de Spatial Transformer Networks pour l’alignement non rigide permet de recaler automatiquement les volumes tridimensionnels avec précision. Le STN apprend à appliquer des déformations locales pour aligner les structures anatomiques, ce qui facilite le suivi longitudinal de tumeurs, la comparaison avant et après traitement, et la segmentation assistée par ordinateur pour le planning chirurgical.

4. Réalité Augmentée et Vision Robotique

Pour les applications de réalité augmentée, il est essentiel de comprendre la géométrie de la scène : où sont les objets, sous quel angle, à quelle distance par rapport à la caméra. Un STN peut servir de module de normalisation géométrique pour prétraiter les images avant qu’elles ne soient analysées par d’autres composants du système. En vision robotique, un STN peut aider un bras robotisé à comprendre la position et l’orientation des objets à saisir, en transformant l’image pour placer l’objet cible dans un repère canonique que le planificateur de mouvement peut utiliser pour calculer la trajectoire de préhension optimale.

Voir Aussi

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur la façon dont les données de vos commentaires sont traitées.