Files
lidar_rendu/README.md
Antoine Jacquin 0d3c3ba8bc Ajouter la couche relief orienté et une échelle d'openness fixe
Nouvelle visualisation relief_oriente : une image RGB unique qui fusionne
l'openness positive locale (MNT détendancé σ 10 m, rayons 5/10/20 m,
16 directions) portée par la clarté CIELAB et l'orientation des pentes
portée par la teinte. Échelle log fixe et support de 40 m sous la bande
de raccord de 100 m : dalles jointives. Calcul sur grille décimée à 0,8 m,
noyau dédié (CuPy RawKernel, numba parallèle, repli numpy) et colorisation
par table L* × teinte : ~8 s par dalle sur CPU au lieu de ~50 s.

L'openness positive et négative est normalisée par des références figées
mesurées sur 15 dalles au lieu d'un z-score par dalle, qui rendait
l'échelle de couleur non jointive.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 00:05:40 +02:00

284 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Pipeline LiDAR Archéologique
Workflow automatisé pour générer des visualisations exploitables à partir de données LiDAR HD (IGN) pour la détection de structures archéologiques. Tourne en Docker avec accélération GPU optionnelle (NVIDIA/CuPy).
## Visualisations (18 par fichier)
### Relief orienté (couche par défaut)
Une seule image fusionne le micro-relief et l'orientation des pentes : la **clarté** porte le relief local (openness positive sur MNT détendancé, rayons 5–20 m, plus un léger ombrage), la **teinte** porte l'orientation (aspect, cercle CIELAB à clarté constante : aucune couleur ne crée de faux relief). Échelle fixe : les dalles voisines se raccordent sans couture.
### Visualisations principales
| # | Visualisation | Utilité archéologique |
|---|--------------|----------------------|
| 1 | **Hillshade multidirectionnel** | Murs, terrasses, structures linéaires, routes |
| 2 | **Pente (Slope)** | Murs de soutènement, talus, changements brusques |
| 3 | **Aspect (Orientation)** | Direction des pentes, exposition |
| 4 | **Courbure (Curvature)** | Fossés, terrasses, talus, concavité/convexité |
| 5 | **Sky-View Factor** | Structures, tumulus, fondations (ray-tracing 16 azimuts) |
| 6 | **Local Relief Model** | Micro-reliefs, fossés, levées de terrain |
| 7 | **Positive Openness** | Élévations, tumulus, bâtiments (ray-tracing 8 directions) |
| 8 | **Negative Openness** | Cavités, fossés, souterrains (ray-tracing 8 directions) |
### Visualisations avancées
| # | Visualisation | Description | Détection |
|---|--------------|-------------|-----------|
| 9 | **MSRM** | Multi-Scale Relief Model (sigma 5/10/25/50/100m) | Tumulus, fossés, murs à toutes les échelles |
| 10 | **TPI multi-échelle** | Topographic Position Index (5m + 100m) | Crêtes, vallées, plateformes |
| 11 | **Dépressions** | Remplissage cuvettes + différence | Dolines, sinkholes, zones inondables |
| 12 | **SAILORE** | LRM adaptatif (noyau = f(pente)) | Terrain hétérogène, tout relief |
| 13 | **Rugosité** | Écart-type de l'élévation | Surfaces anthropiques vs naturelles |
| 14 | **Anomalies statistiques** | Z-score + Local Moran's I | Anomalies topographiques significatives |
| 15 | **Ondelette Mexican Hat** | CWT 2D multi-échelle | Tumulus, fossés circulaires |
| 16 | **Accumulation de flux** | Algorithme D8 hydrologique | Fossés d'enceinte, routes antiques |
### Cartes de référence IGN
| # | Visualisation | Source |
|---|--------------|--------|
| 17 | **Photographie aérienne IGN** | Orthophotographie WMTS |
| 18 | **Carte topographique IGN** | Plan IGN V2 WMTS |
## Classification du sol
Le pipeline classifie automatiquement les points sol à partir du nuage de points bruit. Le pré-traitement suit le workflow recommandé par PDAL :
1. **Filtre ReturnNumber** — élimine les points avec numéros de retour invalides
2. **Réinitialisation Classification** — remet toutes les classifications à 0
3. **ELM** (Extended Local Minimum) — marque les points bas aberrants comme bruit (Classification=7)
4. **Outlier statistique** — supprime les points isolés (mean_k=8, multiplier=3.0)
5. **Classification sol** — SMRF, PMF ou CSF
6. **Extraction** — ne conserve que les points Classification=2
### Méthodes de classification
| Méthode | Mode | Usage | Vitesse |
|---------|------|-------|---------|
| **SMRF** | Auto (défaut) | Terrain naturel, forêt, rocaille | Rapide |
| **PMF** | Auto (si urbain) | Zones urbaines, bâtiments, routes | Rapide |
| **CSF** | Manuel uniquement | Terrain très complexe, falaises | Lent |
L'auto-détection analyse le ratio de retours uniques du nuage de points : ratio > 0.6 = milieu urbain → PMF, sinon → SMRF.
### Pré-traitement ELM (terrain calcaire)
Les paramètres ELM sont adaptés au terrain calcaire rocailleux avec végétation basse :
- `cell=5.0m` — résolution fine pour capturer le relief rocheux
- `threshold=2.0m` — seuil élevé pour ne pas marquer les affleurements comme bruit
## Architecture modulaire
```
lidar_pipeline/
├── __init__.py # Exports publics
├── __main__.py # Point d'entrée: python -m lidar_pipeline
├── cli.py # argparse + logging + main()
├── gpu.py # CuPy/numpy abstraction (HAS_GPU, to_gpu, to_cpu, xp_*)
├── dtm.py # Classification PDAL (SMRF/PMF/CSF + auto) + génération DTM
├── visualizations.py # Fonctions generate_* (19 visualisations)
├── ign.py # Téléchargement tuiles IGN + overlay
├── rendering.py # Colormaps, tif_to_png, rapport PDF
├── pipeline.py # LidarArchaeoPipeline (orchestration + registry)
└── tests/ # Tests unitaires (pytest)
```
Ajouter une visualisation = 1 fonction + 1 entrée dans `VIZ_STEPS` + 1 entrée dans `COLORMAPS`.
## Installation Docker
```bash
cd /votre/dossier/lidar
mkdir -p input
# Copiez vos fichiers .laz dans input/
cp /chemin/vos/fichiers/*.laz input/
# Build l'image Docker
docker build -t lidar-lidar .
```
## Utilisation
### Traitement complet avec GPU (recommandé)
```bash
./run.sh -g
```
### Traitement standard (CPU seul)
```bash
./run.sh
```
### Options du script run.sh
```
./run.sh [options]
-r RESOLUTION Résolution en m/px (défaut: 0.5)
-w WORKERS Nombre de workers parallèles (défaut: 1)
-g Activer l'accélération GPU NVIDIA
-v Mode verbeux (timestamps + niveaux)
--debug Mode debug (détails internes fichier:ligne)
-f / --force Régénérer tous les fichiers même si les WebP existent
--force-classification Reclassifier le sol même si le fichier .las existe déjà
--ground-classification Méthode de classification: auto, smrf, pmf, csf (défaut: auto)
--file NOM... Traiter un ou plusieurs fichiers LAZ spécifiques
--test Exécuter les tests unitaires
-h Afficher l'aide
```
### Exemples
```bash
# Traitement standard avec GPU
./run.sh -g
# GPU + mode verbeux
./run.sh -g -v
# GPU + 4 workers parallèles
./run.sh -g -w 4
# Haute résolution (0.2m/px)
./run.sh -g -r 0.2
# Forcer la régénération de tous les fichiers
./run.sh -g --force
# Reclassifier le sol seulement (sans régénérer les visualisations)
./run.sh -g --force-classification
# Forcer la classification PMF au lieu de l'auto-détection
./run.sh -g --ground-classification pmf
# Forcer la classification CSF (lent mais robuste sur terrain complexe)
./run.sh -g --ground-classification csf
# Traiter un fichier spécifique (test rapide)
./run.sh -g --file LHD_FXX_1000_6882_PTS_LAMB93_IGN69.copc
# Traiter deux fichiers spécifiques
./run.sh -g --file LHD_FXX_1000_6881_PTS_LAMB93_IGN69.copc LHD_FXX_1000_6882_PTS_LAMB93_IGN69.copc
# Exécuter les tests unitaires
./run.sh --test
```
### Utilisation directe Docker
```bash
# Traitement standard
docker run --rm -v $(pwd)/input:/data/input:ro -v $(pwd)/output:/data/output lidar-lidar
# Avec GPU + classification forcée
docker run --rm --gpus all -v $(pwd)/input:/data/input:ro -v $(pwd)/output:/data/output \
lidar-lidar python3 -m lidar_pipeline /data/input -o /data/output \
--ground-classification pmf
# Forcer la reclassification du sol
docker run --rm --gpus all -v $(pwd)/input:/data/input:ro -v $(pwd)/output:/data/output \
lidar-lidar python3 -m lidar_pipeline /data/input -o /data/output \
--force-classification
# Mode verbeux
docker run --rm --gpus all -v $(pwd)/input:/data/input:ro -v $(pwd)/output:/data/output \
lidar-lidar python3 -m lidar_pipeline /data/input -o /data/output -v
```
## Structure des dossiers
```
.
├── input/ # Fichiers .laz (monté en read-only dans Docker)
├── output/ # Résultats générés
│ ├── DTM/ # Modèles numériques de terrain (GeoTIFF)
│ ├── temp/ # Fichiers temporaires (classification .las)
│ ├── visualisations/ # Images WebP par fichier LAZ
│ │ ├── fichier_6881/ # Un sous-dossier par fichier LAZ
│ │ │ ├── ..._hillshade_multi.webp
│ │ │ ├── ..._svf.webp
│ │ │ ├── ..._mslrm.webp
│ │ │ └── ... (19 visualisations)
│ │ └── fichier_6882/
│ │ └── ...
│ └── rapports/ # Rapports PDF A3 par fichier
│ ├── fichier_6881_rapport.pdf
│ └── fichier_6882_rapport.pdf
├── lidar_pipeline/ # Package Python modulaire
│ ├── cli.py # Arguments CLI + logging
│ ├── gpu.py # Abstraction CuPy/numpy
│ ├── dtm.py # Classification sol + DTM
│ ├── visualizations.py # 19 fonctions generate_*
│ ├── ign.py # Tuiles IGN
│ ├── rendering.py # Colormaps, WebP, PDF
│ ├── pipeline.py # Orchestration
│ └── tests/ # Tests unitaires
├── process_lidar.py # Point d'entrée compatible
├── Dockerfile
├── run.sh
└── README.md
```
## Paramètres
| Paramètre | Option | Défaut | Description |
|-----------|--------|--------|-------------|
| Résolution | `-r` | 0.5 | Résolution en mètres par pixel |
| Workers | `-w` | 1 | Nombre de CPU pour traitement parallèle |
| GPU | `-g` | off | Activer l'accélération NVIDIA GPU |
| Classification sol | `--ground-classification` | auto | Méthode : auto, smrf, pmf, csf |
| Forcer classification | `--force-classification` | off | Reclassifier le sol même si .las existe |
| Output | `-o` | /data/output | Dossier de sortie |
| Force | `-f/--force` | off | Régénérer même si les WebP existent |
| File | `--file` | tous | Traiter un ou plusieurs fichiers LAZ |
| Verbose | `-v` | off | Mode verbeux (timestamps + niveaux) |
| Debug | `--debug` | off | Mode debug (détails internes) |
### Résolution recommandée
- `0.2` — Très fine, bâtiments individuels (lent)
- `0.5` — Recommandée archéologie (équilibre vitesse/détail)
- `1.0` — Rapide, grandes structures uniquement
## Interprétation archéologique
### Pour détecter les cavités et souterrains
1. **Negative Openness** — Zones sombres = creux profonds
2. **Dépressions** — Carte spécifique des dolines et sinkholes
3. **Local Relief Model** — Zones bleues = dépressions
4. **Hillshade** — Ombres inhabituelles en forme de trous
### Pour détecter structures et bâtiments anciens
1. **MSRM** — Détection multi-échelle de tous les reliefs
2. **Sky-View Factor** — Structures géométriques claires
3. **SAILORE** — LRM adaptatif pour terrain hétérogène
4. **Anomalies statistiques** — Anomalies topographiques significatives
### Pour hydrologie et fossés
1. **Accumulation de flux** — Fossés d'enceinte, routes antiques
2. **Dépressions** — Zones de collecte d'eau, dolines
3. **Negative Openness** — Fossés et tranchées
## Tests
```bash
./run.sh --test
```
Les tests tournent dans le conteneur Docker et couvrent la classification du sol (SMRF/PMF/CSF), l'auto-détection, le rendu, et les visualisations.
## Dépannage
```bash
# Vérifier Docker
docker --version
# Shell dans le conteneur
docker run --rm -it -v $(pwd)/input:/data/input -v $(pwd)/output:/data/output \
--entrypoint bash lidar-lidar
# Reconstruire l'image
docker build --no-cache -t lidar-lidar .
# Nettoyer
docker system prune -a
```
### Erreur mémoire
Augmenter la mémoire Docker à 16Go+ pour les gros fichiers LiDAR HD.
### Données LiDAR HD (IGN)
Les fichiers COPC (.laz) de l'IGN sont supportés directement. Le pipeline détecte automatiquement la méthode de classification du sol (SMRF/PMF) en analysant le ratio de retours uniques du nuage de points.