From 6780f2e25b38880c24f4e5ef269cd9bc6bc3f88a Mon Sep 17 00:00:00 2001 From: Antoine Jacquin Date: Wed, 16 Sep 2026 20:21:54 +0200 Subject: [PATCH] =?UTF-8?q?Compler=20les=20NaN=20du=20MNT=208x=20plus=20vi?= =?UTF-8?q?te=20via=20transform=C3=A9e=20de=20distance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remplace NearestNDInterpolator (cKDTree sur les 25 M de points valides, plusieurs secondes par dalle trouée en mode IGN pur) par distance_transform_edt : plus proche voisin en une passe O(n). Voisins équidistants arbitres differemment, sans effet sur les rendus. --- lidar_pipeline/visualizations.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/lidar_pipeline/visualizations.py b/lidar_pipeline/visualizations.py index 9ebb913..13e5390 100644 --- a/lidar_pipeline/visualizations.py +++ b/lidar_pipeline/visualizations.py @@ -214,22 +214,19 @@ def _fill_nans(arr): """Fill NaN values using nearest-neighbor interpolation. Returns (filled_array, nan_mask) so the caller can restore NaN after filtering. + + Via transformée de distance (O(n), vectorisé) : les indices du plus proche + voisin valides sortent en une passe. NearestNDInterpolator construisait un + cKDTree sur TOUS les points valides (25 M à 0,2 m) — plusieurs secondes + par dalle trouée, payées au premier accès de SharedDEM.filled. """ - from scipy.interpolate import NearestNDInterpolator nan_mask = np.isnan(arr) if not np.any(nan_mask): return arr, nan_mask - valid = ~nan_mask - y_coords, x_coords = np.where(valid) - if len(y_coords) == 0: - return np.zeros_like(arr), nan_mask - z_values = arr[valid] - interp = NearestNDInterpolator( - np.column_stack((y_coords, x_coords)), z_values - ) - y_missing, x_missing = np.where(nan_mask) + from scipy.ndimage import distance_transform_edt + _, (iy, ix) = distance_transform_edt(nan_mask, return_indices=True) filled = arr.copy() - filled[y_missing, x_missing] = interp(y_missing, x_missing) + filled[nan_mask] = arr[iy[nan_mask], ix[nan_mask]] return filled, nan_mask