diff --git a/lidar_pipeline/rendering.py b/lidar_pipeline/rendering.py index c66de4c..6fbed65 100644 --- a/lidar_pipeline/rendering.py +++ b/lidar_pipeline/rendering.py @@ -204,7 +204,7 @@ def _apply_colormap(data, tif_file): # Find matching colormap for key, info in COLORMAPS.items(): if key in name: - valid_data = np.asarray(data[~np.isnan(data)] if hasattr(data, 'compressed') else data.flatten()) + valid_data = np.asarray(data.compressed() if hasattr(data, 'compressed') else data.flatten()) valid_data = valid_data[~np.isnan(valid_data)] vmin = vmax = None @@ -239,7 +239,7 @@ def _apply_colormap(data, tif_file): return data, info['cmap'], info['title'], legend, info['description'], False # Default: terrain colormap with percentile stretch - valid_data = np.asarray(data[~np.isnan(data)] if hasattr(data, 'compressed') else data.flatten()) + valid_data = np.asarray(data.compressed() if hasattr(data, 'compressed') else data.flatten()) valid_data = valid_data[~np.isnan(valid_data)] p2, p98 = np.percentile(valid_data, (2, 98)) data = np.clip((data - p2) / (p98 - p2), 0, 1) @@ -324,6 +324,10 @@ def tif_to_png(tif_file, vis_dir, resolution): valid_data = np.asarray(data.compressed() if hasattr(data, 'compressed') else data.flatten()) valid_data = valid_data[~np.isnan(valid_data)] + # Convert MaskedArray to plain ndarray (NaN-filled) to avoid numpy warnings + if isinstance(data, np.ma.MaskedArray): + data = np.ma.filled(data, np.nan) + # Apply colormap data, cmap, title, legend_label, description, is_rgb_result = _apply_colormap(data, tif_file) diff --git a/lidar_pipeline/visualizations.py b/lidar_pipeline/visualizations.py index 45b73a8..5c2e3da 100644 --- a/lidar_pipeline/visualizations.py +++ b/lidar_pipeline/visualizations.py @@ -6,6 +6,7 @@ parameters and returns the path to the output GeoTIFF file, or None on error. import logging import time +import warnings from pathlib import Path import numpy as np @@ -391,8 +392,10 @@ def generate_mslrm(dem_file, basename, vis_dir, resolution): lrm_stack.append(lrm_norm.astype(np.float32)) lrm_array = np.array(lrm_stack) - with np.errstate(invalid='ignore'): - mslrm = np.sqrt(np.nanmean(lrm_array ** 2, axis=0)) + with np.errstate(invalid='ignore', divide='ignore'): + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', message='Mean of empty slice') + mslrm = np.sqrt(np.nanmean(lrm_array ** 2, axis=0)) mslrm[nan_mask] = np.nan _save_tif(output, mslrm.astype(np.float32), transform, crs) logger.info(f" ✓ MSRM terminé ({time.time()-t0:.1f}s){gpu_tag}") @@ -659,8 +662,10 @@ def generate_wavelet(dem_file, basename, vis_dir, resolution): response = response / std_val wavelet_stack.append(response) - with np.errstate(invalid='ignore'): - combined = np.sqrt(np.nanmean(np.array(wavelet_stack) ** 2, axis=0)) + with np.errstate(invalid='ignore', divide='ignore'): + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', message='Mean of empty slice') + combined = np.sqrt(np.nanmean(np.array(wavelet_stack) ** 2, axis=0)) combined[nan_mask] = np.nan _save_tif(output, combined.astype(np.float32), transform, crs)