Aller au contenu principal

Module 7 — Segmentation d'instances avec Mask R-CNN

Le module 6 a produit une carte de classes de la taille de l'image, sans distinguer deux voitures collées. Pour compter les véhicules au carrefour, il faut savoir que ce paquet de pixels appartient à la voiture n° 3 et pas simplement à la classe voiture. C'est la segmentation d'instances, et l'architecture qui l'a rendue accessible s'appelle Mask R-CNN.

Ajouter une troisième tête à Faster R-CNN

Mask R-CNN (2017) reprend Faster R-CNN et lui ajoute, à côté des têtes de classification et de régression de boîte, une tête de masque. Pour chaque proposition retenue, cette tête prédit un petit masque binaire — typiquement 28 × 28 — qui indique quels pixels de la boîte appartiennent à l'objet.

Le pipeline d'inférence se lit en cinq étapes :

  1. Le tronc extrait une carte de caractéristiques.
  2. Le RPN propose des régions candidates.
  3. RoI Align extrait un tenseur fixe par région.
  4. Trois têtes en parallèle prédisent classe, correction de boîte et masque.
  5. On assemble et on applique une NMS par classe.

Pour restituer un masque sur l'image d'origine, on redimensionne le masque 28 × 28 vers la boîte finale, puis on seuille à 0,5. Le résultat est un masque irrégulier, adapté à la forme de la voiture ou du piéton.

import torch
from torchvision.models.detection import maskrcnn_resnet50_fpn
from torchvision.models.detection.mask_rcnn import MaskRCNN_ResNet50_FPN_Weights

modele = maskrcnn_resnet50_fpn(
weights=MaskRCNN_ResNet50_FPN_Weights.COCO_V1
).eval()

image = torch.rand(3, 800, 800)
with torch.no_grad():
sortie = modele([image])[0]

boites = sortie["boxes"] # (N, 4)
classes = sortie["labels"] # (N,)
scores = sortie["scores"] # (N,)
masques = sortie["masks"] # (N, 1, H, W), probabilites entre 0 et 1

masques_binaires = masques > 0.5

Un point à ne pas oublier : masks sort en probabilités continues, pas en masque binaire. Le seuillage à 0,5 est de la responsabilité de l'appelant, comme le seuil de confiance sur scores.

Sémantique contre instances : le même pixel, deux réponses

Sur deux voitures qui se touchent :

  • La segmentation sémantique produit une seule zone d'étiquette « voiture », inséparable en deux.
  • La segmentation d'instances produit deux masques distincts, chacun avec sa boîte et sa classe. Le pixel de la frontière peut appartenir à l'une, à l'autre, ou aux deux.

C'est ce chevauchement possible qui distingue les instances : deux masques peuvent partager des pixels, ce qui reflète bien la réalité d'objets qui se touchent. La sémantique ne le peut pas, puisqu'un pixel a une classe unique.

Pour un système de comptage, la différence est catégorique : la sémantique donne « il y a de la voiture ici » ; les instances donnent « il y a trois voitures ». Sans un modèle d'instances ou un post-traitement de composantes connexes, aucun comptage n'est possible.

Perte de masque : entropie croisée binaire par pixel

La tête de masque de Mask R-CNN prédit un masque par classe. À l'entraînement, seul le masque de la classe vérité contribue à la perte — les 79 autres sortent, mais ne sont pas comparées.

Lmasque=1HWi,j[mi,jlogm^i,j+(1mi,j)log(1m^i,j)]\mathcal{L}_{\text{masque}} = -\frac{1}{H \cdot W} \sum_{i, j} \big[ m_{i,j} \log \hat{m}_{i,j} + (1 - m_{i,j}) \log (1 - \hat{m}_{i,j}) \big]

Cette astuce évite que les classes se concurrencent au niveau du masque : le choix de la classe se fait à la tête de classification, la tête de masque peaufine ensuite la forme. C'est aussi ce qui distingue Mask R-CNN d'un U-Net multi-classes.

Panoptique : un pixel, une seule entité

La segmentation panoptique (2018) unifie sémantique et instances. Elle distingue deux types de classes :

  • Les choses (things) : classes dénombrables — voitures, personnes, vélos.
  • Les fonds (stuff) : classes non dénombrables — route, ciel, herbe.

Chaque pixel appartient à une et une seule entité, identifiée par son type et par un identifiant unique si c'est une chose. La métrique standard est le PQ (Panoptic Quality), qui combine l'IoU moyen des vraies entités appariées et une pénalité pour les non-appariements.

PQ=(p,g)VPIoU(p,g)VPqualiteˊVPVP+12FP+12FNcouverture\mathrm{PQ} = \underbrace{\frac{\sum_{(p, g) \in \mathrm{VP}} \mathrm{IoU}(p, g)}{|\mathrm{VP}|}}_{\text{qualité}} \cdot \underbrace{\frac{|\mathrm{VP}|}{|\mathrm{VP}| + \frac{1}{2}|\mathrm{FP}| + \frac{1}{2}|\mathrm{FN}|}}_{\text{couverture}}

Le PQ est stricte : elle punit à la fois les segments manqués et les faux positifs. Sur Cityscapes, un modèle actuel atteint autour de 65 % de PQ. Mask2Former et OneFormer sont les architectures unifiées qui dominent le sujet aujourd'hui, mais leur coût dépasse celui d'un simple Mask R-CNN.

Segment Anything comme outil d'annotation

Meta a publié SAM (Segment Anything Model, 2023), un modèle préentraîné sur un milliard de masques capable de segmenter n'importe quel objet à partir d'un simple point ou d'une boîte. SAM ne prédit pas la classe — il produit uniquement le masque.

Pour un projet de segmentation d'instances, SAM est surtout précieux comme assistant d'annotation :

  • L'annotateur clique sur un objet, SAM propose un masque en une seconde.
  • L'annotateur valide, corrige aux endroits douteux, passe à l'objet suivant.
  • Le coût d'annotation par masque tombe de deux à cinq minutes à moins d'une trentaine de secondes.
from segment_anything import SamPredictor, sam_model_registry

sam = sam_model_registry["vit_b"](checkpoint="sam_vit_b.pth")
predicteur = SamPredictor(sam)
predicteur.set_image(image_np)

masques, scores, _ = predicteur.predict(
point_coords=[[520, 340]], # coordonnees d'un clic
point_labels=[1], # 1 = point sur l'objet
multimask_output=True,
)

L'appel renvoie trois masques candidats avec leurs scores. L'annotateur choisit le meilleur, ou passe à un autre point si aucun ne convient.

Le masque brut de Mask R-CNN a 28 × 28 pixels

Cette résolution minuscule, redimensionnée par bicubique vers la taille de la boîte, donne des bords escarpés sur les grandes voitures. C'est volontaire — un masque plus grand coûte trop en calcul et en mémoire. Les modèles récents comme PointRend et Mask2Former reprennent le masque avec un raffinement itératif sur les pixels à la frontière, ce qui rend les contours nettement plus fins sans réentraîner tout le tronc.

Compter avec un simple Faster R-CNN

Si votre besoin est de compter les voitures sans les délimiter, un Faster R-CNN suffit — le nombre de boîtes après NMS est le nombre d'objets. Ne payez le prix de Mask R-CNN que si vous avez réellement besoin de la forme (par exemple pour distinguer une camionnette d'un utilitaire, ou pour mesurer l'occupation d'une place de parking).

En résumé

  • Mask R-CNN ajoute une tête de masque à Faster R-CNN, qui prédit un masque 28 × 28 par proposition puis le redimensionne vers la boîte finale — c'est un détecteur avec une couche de segmentation en plus.
  • La segmentation d'instances distingue deux objets de même classe qui se touchent, ce que la sémantique ne peut pas faire. C'est ce qui rend le comptage possible.
  • La segmentation panoptique unifie choses et fonds sous la règle « un pixel, une seule entité », mesurée par le PQ. Mask2Former et OneFormer sont les architectures unifiées de référence aujourd'hui.
  • SAM ne remplace pas Mask R-CNN pour la production, mais divise par cinq à dix le coût d'annotation d'un jeu personnalisé.

Module suivant : le suivi multi-objets dans une vidéo, qui transforme des détections image par image en trajectoires cohérentes.