website color mapping update
This commit is contained in:
parent
ce963b2cf7
commit
9186bfd1c5
3 changed files with 113 additions and 43 deletions
37
app/main.py
37
app/main.py
|
|
@ -171,9 +171,10 @@ def initialize_models():
|
||||||
print("🔄 Configuration de MLflow...")
|
print("🔄 Configuration de MLflow...")
|
||||||
configure_mlflow()
|
configure_mlflow()
|
||||||
|
|
||||||
print("🔄 Chargement de la configuration Cityscapes...")
|
print("🔄 Chargement de la configuration Cityscapes avec couleurs WCAG...")
|
||||||
mapping_config = load_cityscapes_config(CITYSCAPES_CONFIG_PATH, verbose=False)
|
mapping_config = load_cityscapes_config(CITYSCAPES_CONFIG_PATH, verbose=False, use_wcag_colors=True)
|
||||||
print("✅ Configuration Cityscapes chargée")
|
print("✅ Configuration Cityscapes chargée avec couleurs WCAG")
|
||||||
|
|
||||||
|
|
||||||
print("🔄 Chargement du meilleur modèle...")
|
print("🔄 Chargement du meilleur modèle...")
|
||||||
best_model, best_run_id, best_encoder_name, best_img_size = load_model(
|
best_model, best_run_id, best_encoder_name, best_img_size = load_model(
|
||||||
|
|
@ -296,28 +297,34 @@ def get_models_info():
|
||||||
if best_model is None or second_best_model is None:
|
if best_model is None or second_best_model is None:
|
||||||
raise HTTPException(status_code=503, detail="Models not loaded")
|
raise HTTPException(status_code=503, detail="Models not loaded")
|
||||||
|
|
||||||
# Couleurs accessibles pour les classes
|
# NOUVELLE RÉPARTITION DES COULEURS selon votre mapping final
|
||||||
accessible_class_colors = [
|
wcag_accessible_colors = [
|
||||||
[0, 102, 204], # primary_blue
|
[102, 102, 102], # Flat: neutral_medium (gris moyen pour routes/trottoirs)
|
||||||
[204, 0, 0], # primary_red
|
[204, 0, 0], # Human: primary_red (rouge pour piétons/cyclistes)
|
||||||
[0, 102, 0], # primary_green
|
[102, 51, 153], # Vehicle: secondary_purple (violet pour véhicules)
|
||||||
[204, 102, 0], # primary_orange
|
[204, 102, 0], # Construction: primary_orange (orange pour bâtiments)
|
||||||
[102, 51, 153], # secondary_purple
|
[0, 102, 102], # Object: secondary_teal (teal pour objets/signalétique)
|
||||||
[0, 102, 102], # secondary_teal
|
[0, 102, 0], # Nature: primary_green (vert pour végétation)
|
||||||
[51, 51, 51], # neutral_dark
|
[0, 102, 204], # Sky: primary_blue (bleu pour ciel)
|
||||||
[102, 102, 102] # neutral_medium
|
[51, 51, 51] # Void: neutral_dark (gris foncé pour zones non-définies)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Mettre à jour la configuration avec les nouvelles couleurs
|
||||||
|
if mapping_config:
|
||||||
|
mapping_config['group_colors'] = np.array(wcag_accessible_colors, dtype=np.uint8)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"best_model": best_model_info,
|
"best_model": best_model_info,
|
||||||
"second_best_model": second_best_model_info,
|
"second_best_model": second_best_model_info,
|
||||||
"num_classes": mapping_config['num_classes'],
|
"num_classes": mapping_config['num_classes'],
|
||||||
"class_names": mapping_config['group_names'],
|
"class_names": mapping_config['group_names'],
|
||||||
"class_colors": accessible_class_colors,
|
"class_colors": wcag_accessible_colors,
|
||||||
"accessibility_info": get_accessibility_info(),
|
"accessibility_info": get_accessibility_info(),
|
||||||
"preprocessing_resolution": best_model_info.get("input_size", (512, 512)) # Ajout pour clarté
|
"preprocessing_resolution": best_model_info.get("input_size", (512, 512))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/dataset-info")
|
@app.get("/dataset-info")
|
||||||
def get_dataset_info():
|
def get_dataset_info():
|
||||||
"""Retourne les informations sur le dataset"""
|
"""Retourne les informations sur le dataset"""
|
||||||
|
|
|
||||||
|
|
@ -30,18 +30,37 @@ st.set_page_config(
|
||||||
|
|
||||||
# Palettes de couleurs conformes WCAG AA (ratio contraste ≥ 3:1)
|
# Palettes de couleurs conformes WCAG AA (ratio contraste ≥ 3:1)
|
||||||
WCAG_ACCESSIBLE_COLORS = {
|
WCAG_ACCESSIBLE_COLORS = {
|
||||||
'primary_blue': '#0066CC', # Contraste 4.5:1 avec blanc
|
'primary_blue': '#0066CC', # [0, 102, 204]
|
||||||
'primary_red': '#CC0000', # Contraste 5.7:1 avec blanc
|
'primary_red': '#CC0000', # [204, 0, 0]
|
||||||
'primary_green': '#006600', # Contraste 4.8:1 avec blanc
|
'primary_green': '#006600', # [0, 102, 0]
|
||||||
'primary_orange': '#CC6600', # Contraste 4.2:1 avec blanc
|
'primary_orange': '#CC6600', # [204, 102, 0]
|
||||||
'secondary_purple': '#663399', # Contraste 4.1:1 avec blanc
|
'secondary_purple': '#663399', # [102, 51, 153]
|
||||||
'secondary_teal': '#006666', # Contraste 4.4:1 avec blanc
|
'secondary_teal': '#006666', # [0, 102, 102]
|
||||||
'neutral_dark': '#333333', # Contraste 12.6:1 avec blanc
|
'neutral_dark': '#333333', # [51, 51, 51]
|
||||||
'neutral_medium': '#666666', # Contraste 5.7:1 avec blanc
|
'neutral_medium': '#666666', # [102, 102, 102]
|
||||||
'neutral_light': '#CCCCCC', # Pour éléments désactivés
|
'neutral_light': '#CCCCCC', # Pour éléments désactivés
|
||||||
'background_alt': '#F5F5F5' # Fond alternatif accessible
|
'background_alt': '#F5F5F5' # Fond alternatif accessible
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Convertir hex vers RGB
|
||||||
|
def hex_to_rgb(hex_color):
|
||||||
|
"""Convertit une couleur hex en tuple RGB"""
|
||||||
|
hex_color = hex_color.lstrip('#')
|
||||||
|
return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
|
||||||
|
|
||||||
|
# Couleurs RGB pour les masques (dans le même ordre que les classes)
|
||||||
|
WCAG_RGB_COLORS = [
|
||||||
|
hex_to_rgb(WCAG_ACCESSIBLE_COLORS['neutral_medium']), # Flat: gris moyen [102, 102, 102]
|
||||||
|
hex_to_rgb(WCAG_ACCESSIBLE_COLORS['primary_red']), # Human: rouge [204, 0, 0]
|
||||||
|
hex_to_rgb(WCAG_ACCESSIBLE_COLORS['secondary_purple']), # Vehicle: violet [102, 51, 153]
|
||||||
|
hex_to_rgb(WCAG_ACCESSIBLE_COLORS['primary_orange']), # Construction: orange [204, 102, 0]
|
||||||
|
hex_to_rgb(WCAG_ACCESSIBLE_COLORS['secondary_teal']), # Object: teal [0, 102, 102]
|
||||||
|
hex_to_rgb(WCAG_ACCESSIBLE_COLORS['primary_green']), # Nature: vert [0, 102, 0]
|
||||||
|
hex_to_rgb(WCAG_ACCESSIBLE_COLORS['primary_blue']), # Sky: bleu [0, 102, 204]
|
||||||
|
hex_to_rgb(WCAG_ACCESSIBLE_COLORS['neutral_dark']) # Void: gris foncé [51, 51, 51]
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
# Motifs pour différencier sans couleur uniquement
|
# Motifs pour différencier sans couleur uniquement
|
||||||
ACCESSIBILITY_PATTERNS = {
|
ACCESSIBILITY_PATTERNS = {
|
||||||
'solid': None,
|
'solid': None,
|
||||||
|
|
@ -598,14 +617,14 @@ def display_model_stats_chart(stats, models_info, title):
|
||||||
|
|
||||||
# Couleurs accessibles WCAG
|
# Couleurs accessibles WCAG
|
||||||
accessible_colors = [
|
accessible_colors = [
|
||||||
WCAG_ACCESSIBLE_COLORS['primary_blue'],
|
WCAG_ACCESSIBLE_COLORS['neutral_medium'], # Flat: gris moyen
|
||||||
WCAG_ACCESSIBLE_COLORS['primary_red'],
|
WCAG_ACCESSIBLE_COLORS['primary_red'], # Human: rouge
|
||||||
WCAG_ACCESSIBLE_COLORS['primary_green'],
|
WCAG_ACCESSIBLE_COLORS['secondary_purple'], # Vehicle: violet
|
||||||
WCAG_ACCESSIBLE_COLORS['primary_orange'],
|
WCAG_ACCESSIBLE_COLORS['primary_orange'], # Construction: orange
|
||||||
WCAG_ACCESSIBLE_COLORS['secondary_purple'],
|
WCAG_ACCESSIBLE_COLORS['secondary_teal'], # Object: teal
|
||||||
WCAG_ACCESSIBLE_COLORS['secondary_teal'],
|
WCAG_ACCESSIBLE_COLORS['primary_green'], # Nature: vert
|
||||||
WCAG_ACCESSIBLE_COLORS['neutral_dark'],
|
WCAG_ACCESSIBLE_COLORS['primary_blue'], # Sky: bleu
|
||||||
WCAG_ACCESSIBLE_COLORS['neutral_medium']
|
WCAG_ACCESSIBLE_COLORS['neutral_dark'] # Void: gris foncé
|
||||||
]
|
]
|
||||||
|
|
||||||
colors = accessible_colors[:len(ordered_class_names)]
|
colors = accessible_colors[:len(ordered_class_names)]
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,47 @@ import albumentations as A
|
||||||
from albumentations.pytorch import ToTensorV2
|
from albumentations.pytorch import ToTensorV2
|
||||||
|
|
||||||
|
|
||||||
def load_cityscapes_config(config_path="../cityscapes_config.json", verbose=True):
|
def update_colors_to_wcag(mapping_config):
|
||||||
|
"""
|
||||||
|
Met à jour les couleurs dans mapping_config pour utiliser les couleurs WCAG accessibles
|
||||||
|
avec redistribution sémantique intuitive finale
|
||||||
|
"""
|
||||||
|
# Redistribution sémantique finale :
|
||||||
|
# Flat → gris moyen, Human → rouge, Vehicle → violet, Construction → orange,
|
||||||
|
# Object → teal, Nature → vert, Sky → bleu, Void → gris foncé
|
||||||
|
wcag_colors = np.array([
|
||||||
|
[102, 102, 102], # Flat: gris moyen (routes, trottoirs)
|
||||||
|
[204, 0, 0], # Human: rouge (piétons, cyclistes)
|
||||||
|
[102, 51, 153], # Vehicle: violet (véhicules)
|
||||||
|
[204, 102, 0], # Construction: orange (bâtiments)
|
||||||
|
[0, 102, 102], # Object: teal (objets, signalétique)
|
||||||
|
[0, 102, 0], # Nature: vert (végétation)
|
||||||
|
[0, 102, 204], # Sky: bleu (ciel)
|
||||||
|
[51, 51, 51] # Void: gris foncé (zones non-définies)
|
||||||
|
], dtype=np.uint8)
|
||||||
|
|
||||||
|
# S'assurer qu'on a assez de couleurs pour le nombre de classes
|
||||||
|
num_classes = mapping_config['num_classes']
|
||||||
|
if len(wcag_colors) < num_classes:
|
||||||
|
print(f"⚠️ Attention: {num_classes} classes mais seulement {len(wcag_colors)} couleurs WCAG disponibles")
|
||||||
|
# Compléter avec les couleurs originales si nécessaire
|
||||||
|
original_colors = mapping_config['group_colors']
|
||||||
|
while len(wcag_colors) < num_classes:
|
||||||
|
wcag_colors = np.vstack([wcag_colors, original_colors[len(wcag_colors):len(wcag_colors)+1]])
|
||||||
|
|
||||||
|
mapping_config['group_colors'] = wcag_colors[:num_classes]
|
||||||
|
print(f"✅ Couleurs mises à jour vers WCAG pour {num_classes} classes")
|
||||||
|
return mapping_config
|
||||||
|
|
||||||
|
|
||||||
|
def load_cityscapes_config(config_path="../cityscapes_config.json", verbose=True, use_wcag_colors=False):
|
||||||
"""
|
"""
|
||||||
Charge la configuration Cityscapes depuis un fichier JSON.
|
Charge la configuration Cityscapes depuis un fichier JSON.
|
||||||
INCHANGÉ - Compatible PyTorch
|
|
||||||
|
Args:
|
||||||
|
config_path: Chemin vers le fichier de configuration
|
||||||
|
verbose: Affichage détaillé
|
||||||
|
use_wcag_colors: Utiliser les couleurs WCAG accessibles
|
||||||
"""
|
"""
|
||||||
with open(config_path, "r", encoding="utf-8") as f:
|
with open(config_path, "r", encoding="utf-8") as f:
|
||||||
config = json.load(f)
|
config = json.load(f)
|
||||||
|
|
@ -40,6 +77,20 @@ def load_cityscapes_config(config_path="../cityscapes_config.json", verbose=True
|
||||||
|
|
||||||
num_classes = len(group_names)
|
num_classes = len(group_names)
|
||||||
|
|
||||||
|
mapping_config = {
|
||||||
|
"class_groups": class_groups,
|
||||||
|
"cityscapes_mapping": cityscapes_mapping,
|
||||||
|
"id_to_label": id_to_label,
|
||||||
|
"group_colors": group_colors,
|
||||||
|
"group_names": group_names,
|
||||||
|
"id_to_group": id_to_group,
|
||||||
|
"num_classes": num_classes
|
||||||
|
}
|
||||||
|
|
||||||
|
# Appliquer les couleurs WCAG si demandé
|
||||||
|
if use_wcag_colors:
|
||||||
|
mapping_config = update_colors_to_wcag(mapping_config)
|
||||||
|
|
||||||
if verbose:
|
if verbose:
|
||||||
print("== Groupes de classes Cityscapes ==")
|
print("== Groupes de classes Cityscapes ==")
|
||||||
for group, classes in class_groups.items():
|
for group, classes in class_groups.items():
|
||||||
|
|
@ -52,20 +103,13 @@ def load_cityscapes_config(config_path="../cityscapes_config.json", verbose=True
|
||||||
print(f" ID {id_:2d} ('{label}') → groupe '{group_names[group_id]}' ({group_id})")
|
print(f" ID {id_:2d} ('{label}') → groupe '{group_names[group_id]}' ({group_id})")
|
||||||
|
|
||||||
print("\n== Liste des groupes et couleurs associées ==")
|
print("\n== Liste des groupes et couleurs associées ==")
|
||||||
for i, (name, color) in enumerate(zip(group_names, group_colors)):
|
for i, (name, color) in enumerate(zip(group_names, mapping_config['group_colors'])):
|
||||||
print(f" Groupe {i}: {name} - Couleur RGB : {color}")
|
print(f" Groupe {i}: {name} - Couleur RGB : {color}")
|
||||||
|
|
||||||
print(f"\nNombre total de groupes/classes : {num_classes}")
|
print(f"\nNombre total de groupes/classes : {num_classes}")
|
||||||
|
|
||||||
return {
|
return mapping_config
|
||||||
"class_groups": class_groups,
|
|
||||||
"cityscapes_mapping": cityscapes_mapping,
|
|
||||||
"id_to_label": id_to_label,
|
|
||||||
"group_colors": group_colors,
|
|
||||||
"group_names": group_names,
|
|
||||||
"id_to_group": id_to_group,
|
|
||||||
"num_classes": num_classes
|
|
||||||
}
|
|
||||||
|
|
||||||
def map_mask_ids(mask, id_to_group_mapping):
|
def map_mask_ids(mask, id_to_group_mapping):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue