PointNet++ : La Puissance du Context Local

PointNet était myope. PointNet++ voit le détail. Comprendre les Set Abstraction Layers.
Expert
60 min
PyTorch, CUDA Sample, KNN
"Le défaut de PointNet ? Il traite le nuage globalement. PointNet++ introduit la hiérarchie : apprendre des features locales à petite échelle, puis les grouper, comme le fait un CNN avec ses champs réceptifs."

1. L'Architecture Hierarchique

PointNet++ divise le nuage en zones de plus en plus gandes. L'unité de base est le Set Abstraction Level (SA), composé de trois étapes :

  1. Sampling : Choisir des centroïdes représentatifs (FPS).
  2. Grouping : Trouver les voisins autour de ces centroïdes (Ball Query).
  3. PointNet : Encoder ces voisinages en vecteurs de features.

2. Furthest Point Sampling (FPS)

Pour couvrir tout le nuage efficacement, on ne tire pas au hasard. On utilise FPS : le prochain point choisi est toujours le plus éloigné de ceux déjà choisis.

fps_alg.py
def farthest_point_sample(xyz, npoint):
    # xyz: [B, N, 3]
    centroids = torch.zeros(B, npoint, dtype=torch.long).cuda()
    distance = torch.ones(B, N).cuda() * 1e10
    farthest = torch.randint(0, N, (B,), dtype=torch.long).cuda()
    
    for i in range(npoint):
        centroids[:, i] = farthest
        centroid = xyz[batch_indices, farthest, :].view(B, 1, 3)
        dist = torch.sum((xyz - centroid) ** 2, -1)
        mask = dist < distance
        distance[mask] = dist[mask]
        farthest = torch.max(distance, -1)[1]
        
    return centroids

Cet algorithme est gourmand (O(N^2)). En pratique, on utilise une version CUDA compilée pour traiter 1M points en temps réel.

3. Multi-Scale Grouping (MSG)

Les nuages de points on une densité variable (proche du scanner = dense, loin = épars). Si on fixe un rayon fixe pour le grouping, on risque d'avoir des boules vides ou trop pleines.

La solution PointNet++ : Regarder à plusieurs échelles (ex: rayon 0.1m et 0.4m) simultanément et concaténer les résultats. C'est le MSG, crucial pour la robustesse.

Scan Radius 1 (Low Detail) Scan Radius 2 (High Context)

4. Feature Propagation (Upsampling)

Dans un réseau de segmentation type U-Net, il faut revenir à la résolution originale (N points). Comme nous avons sous-échantillonné, nous devons interpoler.

On utilise une Interpolation IDW (Inverse Distance Weighted) basée sur les 3 plus proches voisins interpolés.

propagation.py
def feature_interpolate(points, centroids, feats):
    # Trouve les 3 plus proches centroides pour chaque point original
    dists, idx = k_nearest_neighbors(points, centroids, k=3)
    inv_dists = 1.0 / (dists + 1e-8)
    norm = torch.sum(inv_dists, dim=2, keepdim=True)
    weights = inv_dists / norm
    
    # Somme pondérée des features
    interpolated_feats = torch.sum(group_features * weights.view(B, N, 3, 1), dim=2)
    return interpolated_feats

Conclusion : L'État de l'Art

Modèle mIoU (S3DIS) Vitesse Inférence
PointNet 47.6% 150 fps (Ultra Fast)
PointNet++ 54.5% 35 fps (Fast)
RandLA-Net 62.4% 60 fps (Very Fast)
Point Transformer 70.1% 5 fps (Heavy)

PointNet++ reste un excellent équilibre performance/précision pour la plupart des applications industrielles en 2026.

🎓 Master Deep Learning 3D

Implémentez PointNet++ et KPConv sur des datasets urbains réels avec notre formation "AI Architect".

Rejoindre l'Elite (120h)