Rendre l'échelle de rugosité jointive entre tuiles
Le z-score par tuile et le vmax au percentile 98 par tuile donnaient une échelle de couleur non jointive (écart-type variant de 0,05 a 0,58 m selon la dalle). Références de normalisation figées (médianes mesurées sur 20 dalles réelles) et vmax fixe 3,8 (p98 médian) : même rugosité physique = même couleur partout.
This commit is contained in:
@ -880,6 +880,15 @@ def _box_std_from_integral(Sx, Sx2, size):
|
||||
return xp.sqrt(xp.maximum(mean_sq - mean * mean, 0))
|
||||
|
||||
|
||||
# Références de normalisation de la rugosité (mètres d'écart-type local).
|
||||
# Médianes inter-tuiles mesurées sur 20 dalles réelles à 0,2 m : la
|
||||
# normalisation par tuile (z-score) rendait l'échelle non jointive — l'écart
|
||||
# variait de 0,05 à 0,58 m selon la tuile pour l'échelle fine. References
|
||||
# FIGÉES : même rugosité physique = même valeur sur toutes les tuiles.
|
||||
ROUGHNESS_FINE_REF_M = 0.156
|
||||
ROUGHNESS_BROAD_REF_M = 0.475
|
||||
|
||||
|
||||
def generate_roughness(dem_file, basename, vis_dir, resolution, shared=None):
|
||||
"""Surface roughness - multi-scale standard deviation (GPU-accelerated).
|
||||
|
||||
@ -889,6 +898,9 @@ def generate_roughness(dem_file, basename, vis_dir, resolution, shared=None):
|
||||
deux échelles, extraction par 4 coins — coût constant quelle que soit
|
||||
la fenêtre (un uniform_filter coûte proportionnellement à sa taille,
|
||||
75 px à 0,2 m pour l'échelle large).
|
||||
|
||||
Normalisation par références FIXÉES (médianes mesurées) et non par
|
||||
tuile : les mosaïques sont jointives, même valeur = même couleur.
|
||||
"""
|
||||
gpu_tag = " [GPU]" if _gpu_mod.HAS_GPU else ""
|
||||
logger.info(f" → Rugosité de surface{gpu_tag}...")
|
||||
@ -930,13 +942,10 @@ def generate_roughness(dem_file, basename, vis_dir, resolution, shared=None):
|
||||
roughness_fine[nan_mask] = np.nan
|
||||
roughness_broad[nan_mask] = np.nan
|
||||
|
||||
# Std normalization per scale then weighted combination
|
||||
fine_valid = roughness_fine[~nan_mask]
|
||||
broad_valid = roughness_broad[~nan_mask]
|
||||
fine_std = max(np.nanstd(fine_valid), 0.01) if len(fine_valid) > 0 else 0.01
|
||||
broad_std = max(np.nanstd(broad_valid), 0.01) if len(broad_valid) > 0 else 0.01
|
||||
|
||||
roughness = 0.7 * roughness_fine / fine_std + 0.3 * roughness_broad / broad_std
|
||||
# Combinaison pondérée, échelle physique commune (références fixées :
|
||||
# jointive entre tuiles — cf. constantes module)
|
||||
roughness = (0.7 * roughness_fine / ROUGHNESS_FINE_REF_M
|
||||
+ 0.3 * roughness_broad / ROUGHNESS_BROAD_REF_M)
|
||||
roughness[nan_mask] = np.nan
|
||||
|
||||
_save_tif(output, roughness, transform, crs)
|
||||
|
||||
Reference in New Issue
Block a user