Filtre matriciel pour un sous-échantillonnage parfait de nuages de points à 50 millions
Le filtre matriciel assure une couverture à 100 % et une fidélité visuelle parfaite lors du rendu de 50 millions de points de pression issus de puits pétroliers. Les algorithmes traditionnels comme LTTB perdent jusqu'à 59 % de la densité de données. Cette approche fonctionne en un seul passage sans tri, en limitant la sortie au nombre de pixels de l'écran.
Les nuages de points sont indispensables pour les données irrégulières avec des lacunes : les lignes déforment les interruptions et masquent les grappes. Les méthodes standards sont optimisées pour les courbes, ignorant la structure 2D.
Limites des algorithmes traditionnels
MinMax, M4, LTTB et hybrides binent l'axe X et sélectionnent 1 à 4 points Y par bin. Dans les colonnes denses, ils éliminent 96 à 99 % des données : les nuages se réduisent aux extrêmes.
- MinMax : min et max — capture les pics mais ignore la distribution.
- M4 : premier, dernier, min/max — parfait pour les lignes pixel par pixel.
- LTTB : plus grande aire de triangle — silhouette des courbes.
- MinMaxLTTB : verrouille les extrêmes, puis lisse.
Pour les nuages de points, c'est un défaut majeur : les algorithmes ignorent les coordonnées Y dans les bins.
Principe du filtre matriciel
Similaire au filtre Voxel Grid en infographie : projette les points sur une grille de pixels W×H. Un seul point est conservé par cellule, dans l'ordre de traversée.
public static void downsample(
double[] times, double[] values,
int width, int height,
List<double[]> result) {
int n = times.length;
if (n == 0) return;
// Étape 1 : bornes
double tMin = times[0], tMax = times[0];
double vMin = values[0], vMax = values[0];
for (int i = 1; i < n; i++) {
if (times[i] < tMin) tMin = times[i];
if (times[i] > tMax) tMax = times[i];
if (values[i] < vMin) vMin = values[i];
if (values[i] > vMax) vMax = values[i];
}
double tRange = Math.max(tMax - tMin, 1e-10);
double vRange = Math.max(vMax - vMin, 1e-10);
// Étape 2 : grille
boolean[] grid = new boolean[width * height];
// Étape 3 : filtrage
for (int i = 0; i < n; i++) {
int px = (int) Math.min(width - 1, (times[i] - tMin) / tRange * (width - 1));
int py = (int) Math.min(height - 1, (values[i] - vMin) / vRange * (height - 1));
int idx = py * width + px;
if (!grid[idx]) {
grid[idx] = true;
result.add(new double[]{times[i], values[i]});
}
}
}
Cette méthode imite le rendu : elle illumine les pixels qui brilleront avec l'ensemble complet. Elle est strictement pour la visualisation, pas pour les statistiques.
Méthodologie de test
~3000 ensembles de données de télémétrie de puits : de 19k à plus de 50M points. Comparaison pixel par pixel avec les originaux en mode nuage (2×2px) et lignes (1px).
Métriques :
- Couverture : % de pixels originaux couverts par l'algorithme.
- Précision : % de pixels de l'algorithme présents dans l'original.
- Score F1 : moyenne harmonique.
- Score visuel : F1 avec tolérance ±1px (prise en compte subpixel).
Algorithmes classiques budgetés pour égaler la sortie de MatrixFilter à 1920×1080. Benchmark : i7-7700K, Java 17, un seul thread.
Résultats sur données réelles
Régulières (~20k points, 2930 fichiers)
Nuages : MatrixFilter 1920×1080 — 100 % sur toutes les métriques. MatrixFilter 800×600 — Visuel 99,6 %, moitié des points. Classiques : Couverture 63–84 %, Visuel 76–95 %.
| Algorithme | Sortie moy. | ms total | Couv. | Préc. | F1 | Visuel |
|------------------|-------------|----------|-------|-------|------|--------|
| Matrix 1920×1080 | 4939 | 695 | 100% | 100% | 100% | 100% |
| Matrix 800×600 | 2867 | 497 | 84.6% | 100% | 91.5%| 99.6% |
| MinMaxLTTB x4 | 4932 | 494 | 84.1% | 100% | 90.9%| 95.2% |
Moyennes et grandes
Sur 500k–50M points, Matrix maintient 100 % Visuel en ~ms/10k points. LTTB chute à 16–40 % de Couverture sur données denses.
Enseignements clés
- Le filtre matriciel offre des nuages parfaits pixel par pixel sans tri, en O(n).
- Les algorithmes traditionnels perdent la structure des nuages denses, même avec budgets généreux.
- Le Score visuel ±1px correspond à la perception : Matrix 800×600 est indistinguable du rendu complet.
- Strictement pour la visualisation : utiliser d'autres méthodes pour lignes/stats.
- Testé sur données industrielles pétrolières avec lacunes irrégulières.
— Editorial Team
Aucun commentaire pour le moment.