PointNet++ : La Puissance du Context Local
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 :
- Sampling : Choisir des centroïdes représentatifs (FPS).
- Grouping : Trouver les voisins autour de ces centroïdes (Ball Query).
- 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.
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.
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.
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)