|
|
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
# Architecture - Interactive AI-Augmented Sky Map (v1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Vue d'ensemble
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Le v1 est scopé en **pipelines indépendants**, volontairement non reliés entre eux. Le matching entre pipelines (faire correspondre une étoile détectée dans une image réelle avec une entrée du catalogue Hipparcos, ou un blob avec un objet Messier classifié) est **explicitement reporté** à une itération ultérieure (v2+).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Cette séparation permet de développer, tester et valider chaque pipeline isolément, sans dépendance croisée prématurée.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Pipeline A - Carte du ciel depuis le catalogue
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Objectif : générer une représentation visuelle du ciel à partir de données catalogue (coordonnées célestes), sans aucune image réelle en entrée.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1. **Chargement** du catalogue Hipparcos pré-traité (CSV, cf. modèle de données)
|
|
|
|
|
|
|
|
2. **Parsing** en structure exploitable (RA/Dec/magnitude/nom)
|
|
|
|
|
|
|
|
3. **Projection** des coordonnées célestes (RA/Dec) vers un plan 2D
|
|
|
|
|
|
|
|
4. **Rendu** de la carte du ciel dans Streamlit (overlay des points projetés)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Entrée : CSV Hipparcos pré-traité
|
|
|
|
|
|
|
|
Sortie : carte du ciel visuelle (image/rendu Streamlit)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Choix techniques
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- **Projection** : implémentation manuelle (pas de lib dédiée type WCS d'astropy) - choix pédagogique assumé, type de projection (stéréographique, orthographique...) à arrêter en phase de pseudo-code
|
|
|
|
|
|
|
|
- **Pré-traitement du catalogue** : `astropy` (parsing du format Hipparcos brut)
|
|
|
|
|
|
|
|
- **Rendu graphique** : `plotly` (via `st.plotly_chart`) - interactivité native (zoom, hover, pan) sans développement custom, adapté à un scatter plot de quelques centaines à quelques dizaines de milliers de points.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Pipeline B - Détection d'étoiles sur image réelle
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Objectif : identifier la position d'étoiles (blobs lumineux) dans une image test fixe, sans référence au catalogue.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1. **Input** : image test fournie
|
|
|
|
|
|
|
|
2. **Détection de blobs** (seuillage adaptatif, DoG)
|
|
|
|
|
|
|
|
3. **Clustering** pour nettoyer le bruit
|
|
|
|
|
|
|
|
4. **Déduction des coordonnées relatives** des étoiles détectées dans l'image
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Entrée : image test (fichier image)
|
|
|
|
|
|
|
|
Sortie : liste de coordonnées (x, y) des étoiles détectées dans l'image
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Choix techniques
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- **Détection de blobs** : `cv2.SimpleBlobDetector` (OpenCV) - filtrage qualité (taille, circularité, convexité, inertie) déjà géré nativement par le detector
|
|
|
|
|
|
|
|
- **Clustering de nettoyage de bruit** : retiré du scope v1. `SimpleBlobDetector` gère déjà l'essentiel du filtrage qualité en interne ; un clustering de déduplication spatiale (regrouper plusieurs détections voisines correspondant à la même étoile) ne sera réintroduit que si ce problème est observé concrètement en pratique sur des images de test réelles.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Pipeline C - Classification Messier / non-Messier
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Objectif : déterminer si une image donnée, cadrée sur un objet du ciel profond, représente un objet du catalogue Messier ou non. **Indépendant du pipeline B** : ne prend pas en entrée les blobs détectés dans une image de test, mais des vignettes dédiées, préparées et labellisées à l'avance.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### C0 - Acquisition du dataset
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- Scraping d'images labellisées positives (objets Messier, source : SEDS ou équivalent - vérifier conditions d'usage avant implémentation)
|
|
|
|
|
|
|
|
- Scraping d'images labellisées négatives (objets NGC hors-Messier, choisis comme négatifs "durs" pour un entraînement plus discriminant)
|
|
|
|
|
|
|
|
- Structuration du dataset (manifeste image - label)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### C1 - Entraînement du modèle
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1. Chargement du dataset de vignettes
|
|
|
|
|
|
|
|
2. Redimensionnement
|
|
|
|
|
|
|
|
3. Normalisation & filtrage (traitement d'image)
|
|
|
|
|
|
|
|
4. Fit du modèle (train/test split, fine-tuning léger MobileNet ou ViT-tiny)
|
|
|
|
|
|
|
|
5. **Evaluation** (métriques, matrice de confusion)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### C2 - Modèle opérationnel (inférence)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1. Chargement de l'input (nouvelle vignette)
|
|
|
|
|
|
|
|
2. Pré-traitement (redimensionnement, normalisation & filtrage) - symétrique à C1
|
|
|
|
|
|
|
|
3. Soumission au modèle entraîné
|
|
|
|
|
|
|
|
4. Output : réponse **booléenne** (Messier / non-Messier)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
> Note : l'identification formelle de l'objet (nom, caractéristiques) en cas de classification positive est explicitement hors scope v1. C'est une amélioration identifiée pour une itération ultérieure (passage à une classification multi-classe).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Choix techniques (C1/C2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- **Modèle** : `MobileNet` (fine-tuning) - préféré à ViT-tiny, ce dernier étant réputé plus gourmand en données ; le dataset attendu (scraping sur 110 objets Messier + négatifs NGC) restera probablement de taille modeste (centaines d'images), un CNN pré-entraîné avec biais inductifs adaptés aux images est donc plus robuste sur ce volume
|
|
|
|
|
|
|
|
- **Framework** : `PyTorch` - préféré à Keras/TensorFlow malgré une prise en main plus verbeuse (boucle d'entraînement explicite), choix motivé par la priorité de compréhension en profondeur du mécanisme de fine-tuning plutôt que la vitesse de mise en oeuvre.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Ce qui est explicitement hors scope v1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- Matching entre pipelines (A/B, B/C, A/C)
|
|
|
|
|
|
|
|
- Classification multi-classes (identification précise de l'objet Messier)
|
|
|
|
|
|
|
|
- Toute entrée caméra live (v1 = images statiques uniquement)
|
|
|
|
|
|
|
|
- Clustering de nettoyage du bruit en pipeline B (sauf besoin avéré en pratique)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Modèle de données - catalogue Hipparcos pré-traité
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
**Fichier** : `dataset_hipparcos.csv`
|
|
|
|
|
|
|
|
**Séparateur** : `;`
|
|
|
|
|
|
|
|
**Encodage** : UTF-8
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| Colonne | Type | Description |
|
|
|
|
|
|
|
|
|---------------|----------------|-----------------------------------------------------------------------------------------------------------|
|
|
|
|
|
|
|
|
| `hip_id` | int | Identifiant Hipparcos (clé unique) |
|
|
|
|
|
|
|
|
| `ra_deg` | float | Ascension droite, en degrés décimaux (converti depuis le format heures/minutes/secondes natif : 1h = 15°) |
|
|
|
|
|
|
|
|
| `dec_deg` | float | Déclinaison, en degrés décimaux (-90 à +90) |
|
|
|
|
|
|
|
|
| `magnitude` | float | Magnitude apparente (échelle inversée : plus la valeur est basse, plus l'objet est brillant) |
|
|
|
|
|
|
|
|
| `proper_name` | string ou NULL | Nom propre de l'étoile si disponible (absent pour la grande majorité des entrées du catalogue) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Exemple de ligne (Sirius / Alpha Canis Majoris) :
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
hip_id;ra_deg;dec_deg;magnitude;proper_name
|
|
|
|
|
|
|
|
32349;101.2875;-16.71611112;-1.46;Sirius
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
> Note d'implémentation : les valeurs décimales ci-dessus utilisent un point comme séparateur (format attendu par `float()` en Python / `pandas.read_csv` par défaut), à ne pas confondre avec la notation à virgule utilisée à l'oral pendant la conception.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Modèle de données - constellations
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
**Fichier** : `dataset_constellations.json`
|
|
|
|
|
|
|
|
**Format** : JSON, liste d'objets
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Chaque constellation référence ses étoiles via leur `hip_id` (clé commune avec `dataset_hipparcos.csv`), sans duplication des données d'étoiles. La structure ne conserve qu'une liste de `liaisons` (paires d'étoiles reliées) - la liste des étoiles composant la constellation est dérivable de cette liste, ce qui évite toute redondance/désynchronisation entre deux champs qui porteraient la même information.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
L'identifiant `id` suit la nomenclature standardisée de l'Union Astronomique Internationale (abréviation à 3 lettres, ex. `UMa` pour la Grande Ourse) plutôt qu'un identifiant arbitraire propre au projet, pour rester compatible avec toute source de données externe (Stellarium, autres catalogues) qui utiliserait la même convention.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
|
|
[
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"id": "UMa",
|
|
|
|
|
|
|
|
"nom": "Grande Ourse",
|
|
|
|
|
|
|
|
"liaisons": [
|
|
|
|
|
|
|
|
[54061, 53910],
|
|
|
|
|
|
|
|
[53910, 58001],
|
|
|
|
|
|
|
|
[58001, 59774],
|
|
|
|
|
|
|
|
[59774, 54061],
|
|
|
|
|
|
|
|
[59774, 62956],
|
|
|
|
|
|
|
|
[62956, 65378],
|
|
|
|
|
|
|
|
[65378, 67301]
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Arborescence du projet
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
data/
|
|
|
|
|
|
|
|
pictures_test/ # images de test, Pipeline B
|
|
|
|
|
|
|
|
messier_classifier/ # dataset C0/C1/C2
|
|
|
|
|
|
|
|
manifest.csv # colonnes : nom;label (label = "messier" ou "ngc")
|
|
|
|
|
|
|
|
dataset_hipparcos.csv
|
|
|
|
|
|
|
|
dataset_constellations.json
|
|
|
|
|
|
|
|
pipeline_a/
|
|
|
|
|
|
|
|
skymap_generator.py
|
|
|
|
|
|
|
|
pipeline_b/
|
|
|
|
|
|
|
|
star_detector.py
|
|
|
|
|
|
|
|
pipeline_c/
|
|
|
|
|
|
|
|
c0_dataset_acquisition.py
|
|
|
|
|
|
|
|
c1_model_training.py
|
|
|
|
|
|
|
|
c2_operational_model.py
|
|
|
|
|
|
|
|
tests/
|
|
|
|
|
|
|
|
tests_pipeline_a.py
|
|
|
|
|
|
|
|
tests_pipeline_b.py
|
|
|
|
|
|
|
|
tests_pipeline_c0.py
|
|
|
|
|
|
|
|
tests_pipeline_c1.py
|
|
|
|
|
|
|
|
tests_pipeline_c2.py
|
|
|
|
|
|
|
|
app.py
|
|
|
|
|
|
|
|
CONTRIBUTING.md
|
|
|
|
|
|
|
|
ARCHITECTURE.md
|
|
|
|
|
|
|
|
README.md
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Chaque pipeline (A/B/C) vit dans son propre dossier, reflétant l'indépendance actée en phase de Découpage. Le pipeline C conserve la séparation C0/C1/C2 jusque dans les fichiers de test, ces trois sous-étapes ayant des natures très différentes (scraping, entraînement, inférence). Pas de fichier `utils.py` créé par anticipation : le code partagé entre pipelines, s'il s'avère nécessaire, sera extrait au moment où un besoin concret de duplication apparaîtra, plutôt que par anticipation.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Décisions techniques actées
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- Catalogue source : Hipparcos, pré-traité offline via `astropy` en CSV propre (RA, Dec, magnitude, nom) plutôt que parsé à la volée dans l'application
|
|
|
|
|
|
|
|
- Git : workflow trunk-based, branche `main` protégée, branches courtes nommées par fonction (`feat/...`, `chore/...`), Conventional Commits, versioning via tags Git
|
|
|
|
|
|
|
|
- CI/CD : squelette actif dès le 3 août 2026 (déclenché sur PR), tests réels à introduire début septembre environ.
|