Un clic sélectionne toujours la dalle sous le curseur (cadre sur la carte), générée ou non : emprise, rendu et recalage des passes s'affichent tout de suite ; la fiche IGN (date et heure du scan LiDAR, capteurs, mission, édition, nombre de points, lien de téléchargement du .copc.laz) arrive à part via /api/map/ign, mise en cache, sans jamais bloquer la sélection. Une rose des vents donne la couleur de chaque orientation de pente du relief orienté, avec la même formule CIELAB que le rendu. La génération impose la classification IGN (sol) et le raccord de 100 m avec les dalles voisines : plus de réglage dans la carte, défauts CLI alignés. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
287 lines
12 KiB
Markdown
287 lines
12 KiB
Markdown
# 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.
|
||
|
||
C'est la **seule couche produite et affichée par défaut** (`PANEL_VIZ` dans `index.py`) : un traitement sans `--only`, la génération lancée depuis la carte et la carte elle-même (panneau, tuiles XYZ, TileJSON, WMTS) se limitent au relief orienté. Les visualisations ci-dessous restent calculables explicitement (`--only slope aspect ...`).
|
||
|
||
### 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: ign, auto, smrf, csf (défaut: ign — imposé par la carte)
|
||
--edge-buffer M Raccord des bords avec les dalles voisines (défaut: 100 m — imposé par la carte)
|
||
--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` | ign | Méthode : ign, auto, smrf, csf (la carte impose ign) |
|
||
| 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. |