De la couleur des ruines à la mesure de l'homogénéisation chromatique des paysages

Constat visuel

Une idée m’est venue il y a quelques semaines, en écrivant l’article De Marioupol à Gaza, Google Maps et la mémoire des lieux meurtris par la guerre : comment quantifier la perte de diversité chromatique des paysages de guerre ?

Comme je l’écris dans l’article, en comparant les images satellites prises avant et après le début du conflit Israël-Gaza en octobre 2023, on s’aperçoit que la guerre et ses destructions font disparaître les couleurs du monde. Plusieurs mois après le début du conflit, les bombardements israéliens massifs ont détruit les toitures colorées et exhibé le béton, la poussière a recouvert les rues, la végétation a été détruite ou recouverte par les décombres, les véhicules individuels ont disparu, etc.

Une même portion de Gaza-ville en mai 2022 (à gauche) et en décembre 2024 (à droite). Captures d'écran Google Earth.

“En 2024, la plupart des bâtiments ont été rasés par les bombardements, la végétation est inexistante, les véhicules individuels ont disparu et les rues sont recouvertes de poussière. C’est un paysage de guerre.”

C’est une évidence, la guerre saccage les paysages urbains en même temps qu’elle détruit les vies humaines qui les habitent. Les destructions semblent se traduire par une perte de diversité ou une homogénéisation chromatique du paysage, visible depuis le ciel ou l’espace : les couleurs sont moins nombreuses, lissées, plus ternes. Poussières, cendres et gravats. La guerre rend le monde plus moche, et ça se voit à l’échelle macroscopique.

Mais comment peut-on vérifier cette forte intuition basée sur un simple constat visuel, afin d’y donner plus de poids ? Comment quantifier la perte de diversité chromatique ?

Quantification

Des couleurs aux données : les espaces de couleur

La couleur est un objet de recherche traité par plusieurs disciplines : l’histoire de l’art, bien évidemment, mais aussi le design, l’informatique ou l’ingénierie. Chez les géographes, les pratiquant·e·s de la télédétection et les cartographes s’y intéressent particulièrement. Toutes font appel au traitement numérique de la couleur. De quoi s’agit-il ?

Pour pouvoir être traitées par ordinateur, les couleurs doivent être traduites sous forme de valeurs numériques. C’est le rôle des espaces de couleur. Le plus connu est le modèle RVB (Rouge-Vert-Bleu), utilisé par les écrans. Chaque pixel y est défini par une combinaison de rouge, de vert et de bleu, dont l’intensité est codée entre 0 et 255 (soit 256³ couleurs possibles). Ainsi, une image satellite n’est finalement qu’une gigantesque matrice de valeurs numériques correspondant à des couleurs (les télédétecteur·rice·s vont me détester, mais je simplifie). Si vous souhaitez creuser le sujet, je vous renvoie vers les pages wikipédia suivantes : espace de couleur et image matricielle.

Pour analyser la diversité chromatique d’un paysage par satellite, le RVB n’est pas toujours le plus pratique. Dans ce travail, j’utilise principalement l’espace TSV ou HSV en anglais (pour Hue, Saturation, Value), qui sépare trois dimensions différentes de la couleur :

  • la teinte (Hue), c’est-à-dire la couleur elle-même (rouge, vert, bleu, etc.) ;
  • la saturation, qui mesure l’intensité ou la vivacité de la couleur ;
  • la valeur (Value), correspondant à la luminosité.

Travailler dans l’espace HSV permet donc de distinguer la diversité des couleurs de simples variations d’ombre ou de luminosité.

Espace de couleur HSV

Une fois les pixels convertis en HSV, il devient alors possible de quantifier la diversité chromatique d’une image en regroupant les pixels dans différentes classes de couleurs, puis en mesurant leur répartition statistique. J’utiliserai pour cela l’indice de Shannon et l’indice de Simpson, utilisés en écologie.

Mise en application avec le package R imager

Prenons les deux captures d’images satellites ci-dessus comme exemple. L’objectif est de quantifier la diversité chromatique de chacune des images, afin de vérifier (ou non) notre intuition : la guerre et ses destructions entraînent une perte de diversité chromatique des paysages.

Nous utiliserons pour cela uniquement le package R imager (lien CRAN), qui permet de manipuler et analyser des images numériques directement sous forme de matrices de pixels. Il offre notamment des fonctions pour convertir les images entre différents espaces de couleur (RVB, HSV…), extraire les valeurs chromatiques de chaque pixel ou encore appliquer des traitements simples de segmentation et de filtrage. Dans le cadre de ce travail, imager a principalement servi à transformer les images satellites en données exploitables statistiquement.

#1 : Retirer les ombres

Sur les images satellites, les ombres peuvent fausser la mesure de la diversité chromatique, car elles introduisent des variations de couleur dues à l’angle du soleil, à la hauteur des bâtiments ou aux conditions de prise de vue (heure) plutôt qu’à la structure réelle du paysage. Afin d’éviter ce biais, il convient donc de retirer les ombres de l’analyse.

Le code ci-dessous (commenté du mieux que j’ai pu… n’hésitez pas à me poser des questions !) applique un masque sur les ombres des deux images et permet donc de ne pas les prendre en compte dans la suite de l’analyse. Le résultat, plutôt satisfaisant mais bien évidemment perfectible, est présenté ensuite.

Note

La télédétection et la vision par ordinateur disposent aujourd’hui de techniques bien plus sophistiquées pour détecter et corriger les effets d’ombre, mobilisant par exemple la radiométrie, des séries temporelles d’images ou des approches d’apprentissage automatique.

L’objectif de cet article n’était cependant pas de développer une chaîne de traitement optimale, mais d’explorer rapidement la faisabilité d’une mesure de la diversité chromatique à partir d’outils simples et facilement reproductibles. Dans cette optique, j’ai fait le choix de travailler exclusivement avec le package imager sous R et d’utiliser une règle de filtrage élémentaire fondée sur la luminosité et la saturation des pixels. Cette approche présente évidemment des limites, mais elle permet de réduire une partie du biais introduit par les ombres tout en conservant un protocole léger et transparent.

La fonction prepare_pixels() prend en entrée le chemin d’une image. Elle charge d’abord l’image, puis vérifie qu’elle possède bien trois canaux de couleur. Si l’image contient un quatrième canal de transparence, celui-ci est supprimé. L’image est ensuite convertie de l’espace RVB vers l’espace HSV, afin de séparer la teinte (H), la saturation (S) et la luminosité (V) de chaque pixel.

Les trois composantes HSV sont ensuite transformées en vecteurs, ce qui permet de travailler non plus sur le fichier image, mais sur une matrice de pixels. Un masque d’ombre est alors créé : les pixels dont la luminosité est inférieure à un seuil donné (v_min) et dont la saturation est inférieure à un second seuil (s_min_shadow) sont considérés comme des pixels d’ombre.

Enfin, la fonction overlay_shadows() sert à contrôler visuellement la qualité du masque. Elle reprend l’image originale et colore en rouge tous les pixels identifiés comme des ombres. Les commandes overlay_shadows(avant) et overlay_shadows(apres) affichent donc les deux images avec les pixels exclus surlignés en rouge.

library(imager)

######### ENLEVER LES PIXELS D'OMBRE

prepare_pixels <- function(path, v_min = 0.20, s_min_shadow = 0.25) {
  img <- load.image(path)
  
  if (spectrum(img) == 4) img <- rm.alpha(img)
  if (spectrum(img) != 3) stop("Image non RGB")
  
  hsv <- RGBtoHSV(img)
  
  H <- as.vector(hsv[,,,1])
  S <- as.vector(hsv[,,,2])
  V <- as.vector(hsv[,,,3])
  
  # masque d'ombre
  shadow_mask <- (V < v_min) & (S < s_min_shadow)
  
  list(
    img = img,
    hsv = hsv,
    shadow_mask = shadow_mask,
    pixels_kept = data.frame( # pixels gardés
      H = H[!shadow_mask],
      S = S[!shadow_mask],
      V = V[!shadow_mask]
    ),
    pixels_removed = data.frame( # les pixels retirés
      H = H[shadow_mask],
      S = S[shadow_mask],
      V = V[shadow_mask]
    )
  )
}

avant <- prepare_pixels("resid1.png", v_min = 0.35, s_min_shadow = 0.99) # on applique la fonction à la première image
apres <- prepare_pixels("resid2.png", v_min = 0.35, s_min_shadow = 0.99) # puis à la seconde

sum(avant$shadow_mask) # permet de compter combien de pixels sont retirés de l'analyse
sum(apres$shadow_mask) # idem


overlay_shadows <- function(obj) { # fonction pour contrôler visuellement les pixels retirés
  img <- obj$img
  out <- img
  
  m <- obj$shadow_mask
  
  R <- as.vector(out[,,,1])
  G <- as.vector(out[,,,2])
  B <- as.vector(out[,,,3])
  
  R[m] <- 1 # on affiche en rouge les pixels retirés
  G[m] <- 0
  B[m] <- 0
  
  dim(R) <- dim(out[,,,1])
  dim(G) <- dim(out[,,,2])
  dim(B) <- dim(out[,,,3])
  
  out[,,,1] <- R
  out[,,,2] <- G
  out[,,,3] <- B
  
  plot(out, axes = FALSE)
}

overlay_shadows(avant)
overlay_shadows(apres)

Comme je l’ai dit, le résultat est perfectible (voir ci-dessous), car plusieurs pixels d’ombre ne sont pas détectés sur les images. Cependant, la majorité d’entre eux sont bien retirés de l’analyse et ce bout de code présente l’avantage de pouvoir être appliqué à l’identique à la plupart des images que nous traiterons par la suite.

Masquage des ombres sur les deux images satellites. Les pixels en rouge ne seront pas pris en compte dans l'analyse.

#2 : Mesure de la diversité chromatique avec l’indice de Shannon (entropie)

Pour mesurer la diversité chromatique des images, j’ai d’abord utilisé l’indice de Shannon, un indicateur employé en écologie pour quantifier la biodiversité (diversité spécifique) d’un milieu.

L’indice de Shannon s’écrit :

\[H' = - \sum_{i=1}^{S} p_i \log_2(p_i)\]

avec :

  • \(H'\) : indice de biodiversité de Shannon ;
  • \(i\) : une espèce du milieu d’étude ;
  • \(S\) : richesse spécifique ;
  • \(p_i\) : proportion de l’espèce (i) dans le milieu.
Note

Cet indice est directement dérivé de la notion d’entropie, développée dans la théorie de l’information par le mathématicien Claude Shannon à la fin des années 1940. Dans ce contexte, l’entropie mesure le degré d’incertitude ou d’imprévisibilité d’un système : plus les éléments qui le composent sont variés et répartis de manière équilibrée, plus son entropie est élevée.

L’utilisation de l’entropie de Shannon pour caractériser quantitativement des images ou des palettes de couleurs n’est pas nouvelle. Voir par exemple Sigaki et al., 2018.

L’idée est relativement simple. Imaginons deux forêts. Dans la première, dix espèces d’arbres sont présentes en proportions comparables. Dans la seconde, ces mêmes dix espèces existent également, mais 95% des arbres appartiennent à une seule espèce. Intuitivement, la première forêt paraît plus diversifiée que la seconde. L’indice de Shannon permet de le quantifier.

Cet indice ne mesure donc pas seulement la richesse spécifique (le nombre d’espèces présentes), mais également l’abondance relative de chaque espèce. Une communauté est considérée comme d’autant plus diverse que les espèces sont nombreuses et que leurs effectifs sont équilibrés, sans qu’une seule espèce ne domine largement les autres.

Cette logique peut être transposée aux couleurs d’une image. Les différentes classes de couleurs jouent alors le rôle des espèces, tandis que les pixels jouent le rôle des individus. On pourrait dire que la diversité chromatique d’une image est grande lorsqu’elle contient de nombreuses classes de couleurs représentées dans des proportions relativement équilibrées. À l’inverse, une image dominée par quelques couleurs seulement est moins diverse d’un point de vue chromatique.

Dans le cadre de cette analyse, les pixels sont regroupés en classes chromatiques à partir de leurs valeurs HSV, puis l’indice de Shannon est calculé à partir de la proportion de pixels appartenant à chaque classe.

Concrètement, comment on s’y prend ?

Voir le code ci-dessous : la fonction shannon_couleur() commence par récupérer les valeurs de teinte (H), de saturation (S) et de luminosité (V) de tous les pixels retenus pour l’analyse. Comme l’indice de Shannon nécessite de travailler sur des catégories discrètes plutôt que sur des valeurs continues, les composantes HSV sont ensuite découpées en classes. La teinte est ici divisée en 16 classes et la saturation en 8 classes. Chaque pixel est ainsi associé à une classe de teinte et à une classe de saturation.

Ces classes sont ensuite combinées grâce à la fonction interaction() afin de construire des classes chromatiques. Chaque combinaison teinte-saturation constitue alors une catégorie de couleur. Par exemple, tous les pixels appartenant à la même tranche de teinte et de saturation seront regroupés dans une même classe.

On compte ensuite le nombre de pixels présents dans chaque classe chromatique (voir ci-dessous).

########## INDICE DE SHANNON APPLIQUÉ AUX COULEURS

shannon_couleur <- function(obj, nb_h = 16, nb_s = 8, use_value = FALSE, nb_v = 8) {
  
  # on récupère les valeurs de teinte, saturation et luminosité de tous les pixels
  # retenus pour l'analyse
  
  H <- obj$pixels_kept$H
  S <- obj$pixels_kept$S
  V <- obj$pixels_kept$V
  
  h_bin <- cut(H, breaks = seq(0, 1, length.out = nb_h + 1), include.lowest = TRUE)
  s_bin <- cut(S, breaks = seq(0, 1, length.out = nb_s + 1), include.lowest = TRUE)
  
  if (use_value) {
    v_bin <- cut(V, breaks = seq(0, 1, length.out = nb_v + 1), include.lowest = TRUE)
    col_bin <- interaction(h_bin, s_bin, v_bin, drop = TRUE)
  } else {
    col_bin <- interaction(h_bin, s_bin, drop = TRUE)
  }
  
  counts <- table(col_bin) # décompte des pixels de chaque classe chromatique
  p <- counts / sum(counts) # calcul de la proportion de pixels appartenant à chaque classe
  
  # indice de Shannon
  H_shannon <- -sum(p * log(p))
  
  list(
    shannon = as.numeric(H_shannon)
  )
}

shannon_avant <- shannon_couleur(avant, use_value = FALSE)
shannon_apres <- shannon_couleur(apres, use_value = FALSE)

# afficher les résultats 

shannon_avant
shannon_apres

resultats_shannon <- data.frame(
  image = c("avant", "apres"),
  shannon = c(
    shannon_avant$shannon,
    shannon_apres$shannon
  )
)

resultats_shannon
Résultats

L’indice de Shannon passe de 0,41 sur la première image (avant la guerre) à 0,34 sur la deuxième image. Cette diminution d’environ 15% suggère une réduction de la diversité chromatique du paysage observé car les pixels de la deuxième image sont répartis dans un nombre plus limité de classes de couleurs : certaines deviennent plus dominantes après les desctructions.

Par sa construction mathématique, l’indice de Shannon est particulièrement sensible à la présence d’un grand nombre de classes de couleurs et à leur équilibre relatif. Il accorde une importance non négligeable aux classes peu représentées. Je choisis donc de l’interprêter ici comme un indicateur de diversité chromatique : plus l’indice est élevé, plus les couleurs sont nombreuses et réparties de manière équilibrée dans l’image.

#3 : Mesure de l’homogénéisation chromatique avec l’indice de Simpson

L’indice de Simpson est utilisé lui aussi en écologie pour mesurer la diversité d’un milieu. Il calcule la probabilité que deux individus sélectionnés au hasard appartiennent à la même espèce (source).

L’indice de Simpson s’écrit :

\[D = \sum_{i=1}^{S} p_i^2\]

avec :

  • \(D\) : indice de Simpson ;
  • \(S\) : nombre de classes chromatiques ;
  • \(p_i\) : proportion de pixels appartenant à la classe chromatique (i).

Comme pour l’indice de Shannon, l’idée consiste ici à considérer les différentes classes de couleurs comme des espèces et les pixels comme des individus. \(D\) représente donc la probabilité que deux pixels tirés au hasard dans l’image appartiennent à la même classe de couleur. Ainsi, si quelques couleurs dominent fortement, \(D\) est élevé, tandis qu’il sera faible si les couleurs sont nombreuses et équitablement réparties dans les différentes classes.

À la différence de l’indice de Shannon, l’indice de Simpson donne plus de poids aux classes dominantes. Il augmente lorsque quelques couleurs occupent une grande part de l’image. Il est moins sensible aux classes rares. Dans le cas des paysages de guerre, où les gravats, le béton et la poussière tendent à imposer quelques teintes dominantes, j’utilise l’indice de Simpson comme un indicateur d’homogénéisation chromatique, complémentaire à l’indice de Shannon.

On remet les mains dans le code

La méthode est la même que pour l’indice de Shannon : on conserve à l’identique la discrétisation en classes de l’espace HSV réalisée précédemment et on combine les classes de teinte et de saturation avec interaction() afin de construire des classes chromatiques (voir ci-dessous). On compte ensuite le nombre de pixels présents dans chaque classe et on calcule la proportion de pixels appartenant à chaque classe chromatique. L’indice \(D\) de Simpson est calculé d’après la formule présentée plus haut.

########## INDICE DE SIMPSON APPLIQUÉ AUX COULEURS

simpson_couleur <- function(obj, nb_h = 16, nb_s = 8, use_value = FALSE, nb_v = 8) {
  
  H <- obj$pixels_kept$H
  S <- obj$pixels_kept$S
  V <- obj$pixels_kept$V
  
  # Découpage des valeurs HSV en classes
  h_bin <- cut(H, breaks = seq(0, 1, length.out = nb_h + 1), include.lowest = TRUE)
  s_bin <- cut(S, breaks = seq(0, 1, length.out = nb_s + 1), include.lowest = TRUE)
  
  if (use_value) {
    v_bin <- cut(V, breaks = seq(0, 1, length.out = nb_v + 1), include.lowest = TRUE)
    col_bin <- interaction(h_bin, s_bin, v_bin, drop = TRUE)
  } else {
    col_bin <- interaction(h_bin, s_bin, drop = TRUE)
  }
  
  # Nombre de pixels par classe chromatique
  counts <- table(col_bin)
  
  # Proportions
  p <- counts / sum(counts)
  
  # Indice de Simpson
  D <- sum(p^2)
  
  return(as.numeric(D))
}

simpson_avant <- simpson_couleur(avant, use_value = FALSE)
simpson_apres <- simpson_couleur(apres, use_value = FALSE)

simpson_avant
simpson_apres
Résultats

L’indice de Simpson augmente légèrement entre les deux images, passant de 0,799 sur la première image à 0,821 sur la deuxième. Cette hausse indique que la probabilité que deux pixels choisis au hasard appartiennent à la même classe chromatique est plus élevée sur le paysage de guerre. Autrement dit, quelques classes de couleurs occupent une place plus importante dans l’image prise après les destructions et tendent à dominer davantage la palette chromatique.

Les variations observées sont relativement modestes, mais elles vont dans le même sens que celles mises en évidence précédemment par l’indice de Shannon. Alors que Shannon suggère une diminution de la diversité chromatique, Simpson indique que certaines classes de couleurs deviennent plus dominantes (on tend un peu plus vers l’homogénéisation chromatique sur la seconde image).

#4 : Réplication de l’analyse sur plusieurs sites à Gaza-ville

Les résultats obtenus sur cette première paire d’images de Gaza-ville sont intéressants, mais ils restent insuffisants pour tirer des conclusions générales. Une modification de la diversité et/ou de l’homogénéisation chromatiques observées sur une seule emprise spatiale pourrait en effet résulter de caractéristiques propres à la zone étudiée ou de biais liés aux images utilisées.

L’objectif de cette seconde étape est donc de tester très rapidement la robustesse de la méthode en l’appliquant à quelques autres couples d’images avant/après destruction. Il ne s’agit pas de constituer un échantillon statistiquement représentatif, mais de vérifier si les tendances observées sur le premier cas d’étude sont identiques sur d’autres extraits d’images satellites Google Earth à Gaza-ville. L’ensemble des biais seront discutés dans une dernière partie.

Les couples d’images avant/après octobre 2023 retenus pour l’analyse sont présentés ci-dessous, avant sélection et suppression des pixels d’ombre :

Paire 1 (déjà traitée plus haut)
Paire 2
Paire 3
Paire 4
Paire 5
Couples d'images satellites utilisés pour tester la robustesse de la méthode. Les images de gauche correspondent à la situation antérieure aux destructions, celles de droite à la situation postérieure. Captures d'écran Google Earth.
library(imager)

######### ENLEVER LES PIXELS D'OMBRE

prepare_pixels <- function(path, v_min = 0.20, s_min_shadow = 0.25) {
  img <- load.image(path)
  
  if (spectrum(img) == 4) img <- rm.alpha(img)
  if (spectrum(img) != 3) stop("Image non RGB")
  
  hsv <- RGBtoHSV(img)
  
  H <- as.vector(hsv[,,,1])
  S <- as.vector(hsv[,,,2])
  V <- as.vector(hsv[,,,3])
  
  shadow_mask <- (V < v_min) & (S < s_min_shadow)
  
  list(
    img = img,
    hsv = hsv,
    shadow_mask = shadow_mask,
    pixels_kept = data.frame(
      H = H[!shadow_mask],
      S = S[!shadow_mask],
      V = V[!shadow_mask]
    ),
    pixels_removed = data.frame(
      H = H[shadow_mask],
      S = S[shadow_mask],
      V = V[shadow_mask]
    )
  )
}

########## INDICE DE SHANNON APPLIQUÉ AUX COULEURS

shannon_couleur <- function(obj, nb_h = 16, nb_s = 8, use_value = FALSE, nb_v = 8) {
  H <- obj$pixels_kept$H
  S <- obj$pixels_kept$S
  V <- obj$pixels_kept$V
  
  h_bin <- cut(H, breaks = seq(0, 1, length.out = nb_h + 1), include.lowest = TRUE)
  s_bin <- cut(S, breaks = seq(0, 1, length.out = nb_s + 1), include.lowest = TRUE)
  
  if (use_value) {
    v_bin <- cut(V, breaks = seq(0, 1, length.out = nb_v + 1), include.lowest = TRUE)
    col_bin <- interaction(h_bin, s_bin, v_bin, drop = TRUE)
  } else {
    col_bin <- interaction(h_bin, s_bin, drop = TRUE)
  }
  
  counts <- table(col_bin)
  p <- counts / sum(counts)
  
  H_shannon <- -sum(p * log(p))
  
  list(
    shannon = as.numeric(H_shannon)
  )
}

########## INDICE DE SIMPSON APPLIQUÉ AUX COULEURS

simpson_couleur <- function(obj, nb_h = 16, nb_s = 8, use_value = FALSE, nb_v = 8) {
  H <- obj$pixels_kept$H
  S <- obj$pixels_kept$S
  V <- obj$pixels_kept$V
  
  h_bin <- cut(H, breaks = seq(0, 1, length.out = nb_h + 1), include.lowest = TRUE)
  s_bin <- cut(S, breaks = seq(0, 1, length.out = nb_s + 1), include.lowest = TRUE)
  
  if (use_value) {
    v_bin <- cut(V, breaks = seq(0, 1, length.out = nb_v + 1), include.lowest = TRUE)
    col_bin <- interaction(h_bin, s_bin, v_bin, drop = TRUE)
  } else {
    col_bin <- interaction(h_bin, s_bin, drop = TRUE)
  }
  
  counts <- table(col_bin)
  p <- counts / sum(counts)
  D <- sum(p^2)
  
  list(
    simpson_D = as.numeric(D),
    simpson_1_minus_D = as.numeric(1 - D),
    simpson_inverse = as.numeric(1 / D)
  )
}

########## FONCTION D'ANALYSE D'UNE PAIRE

analyse_paire <- function(nom_paire, fichier_avant, fichier_apres,
                          v_min = 0.35, s_min_shadow = 0.99,
                          nb_h = 16, nb_s = 8, use_value = FALSE, nb_v = 8) {
  
  
  
  avant <- prepare_pixels(fichier_avant, v_min = v_min, s_min_shadow = s_min_shadow)
  apres <- prepare_pixels(fichier_apres, v_min = v_min, s_min_shadow = s_min_shadow)
  
  shannon_avant <- shannon_couleur(avant, nb_h = nb_h, nb_s = nb_s, use_value = use_value, nb_v = nb_v)
  shannon_apres <- shannon_couleur(apres, nb_h = nb_h, nb_s = nb_s, use_value = use_value, nb_v = nb_v)
  
  simpson_avant <- simpson_couleur(avant, nb_h = nb_h, nb_s = nb_s, use_value = use_value, nb_v = nb_v)
  simpson_apres <- simpson_couleur(apres, nb_h = nb_h, nb_s = nb_s, use_value = use_value, nb_v = nb_v)
  
  data.frame(
    paire = c(nom_paire, nom_paire),
    image = c("avant", "apres"),
    fichier = c(fichier_avant, fichier_apres),
    pixels_ombre = c(sum(avant$shadow_mask), sum(apres$shadow_mask)),
    pixels_gardes = c(nrow(avant$pixels_kept), nrow(apres$pixels_kept)),
    shannon = c(shannon_avant$shannon, shannon_apres$shannon),
    simpson_D = c(simpson_avant$simpson_D, simpson_apres$simpson_D),
    simpson_1_minus_D = c(simpson_avant$simpson_1_minus_D, simpson_apres$simpson_1_minus_D),
    simpson_inverse = c(simpson_avant$simpson_inverse, simpson_apres$simpson_inverse),
  )
}


## DEF PAIRES IMAGES

paires <- list(
  list(nom = "paire_1", avant = "resid1.png", apres = "resid2.png"),
  list(nom = "paire_2", avant = "p2-1.png", apres = "p2-2.png"),
  list(nom = "paire_3", avant = "p3-1.png", apres = "p3-2.png"),
  list(nom = "paire_4", avant = "p4-1.png", apres = "p4-2.png"),
  list(nom = "paire_5", avant = "p5-1.png", apres = "p5-2.png")
)


## RESULTATS

resultats <- do.call(
  rbind,
  lapply(paires, function(p) {
    analyse_paire(
      nom_paire = p$nom,
      fichier_avant = p$avant,
      fichier_apres = p$apres,
      v_min = 0.35,
      s_min_shadow = 0.99
    )
  })
)

resultats

resume_paires <- do.call(
  rbind,
  lapply(split(resultats, resultats$paire), function(df) {
    data.frame(
      paire = unique(df$paire),
      delta_shannon = df$shannon[df$image == "apres"] - df$shannon[df$image == "avant"],
      delta_simpson_D = df$simpson_D[df$image == "apres"] - df$simpson_D[df$image == "avant"],
    )
  })
)

resume_paires

Le code ci-dessus reprend donc l’ensemble de la chaîne de traitement et y ajoute la liste de paires d’images avant/après. Pour chacune d’entre elles, les ombres sont supprimées, puis les indices de Shannon et de Simpson sont calculés à partir des classes chromatiques définies dans l’espace HSV. Les résultats sont ensuite regroupés dans un tableau unique facilitant les comparaisons. Le terme delta (Δ) désigne, dans le tableau, la différence entre les valeurs observées après destruction et celles observées avant destruction.

Résultats :
Paire Δ Shannon Δ Simpson
paire_1 -0.063 0.023
paire_2 0.154 -0.103
paire_3 -0.248 0.124
paire_4 -0.109 0.027
paire_5 -0.591 0.269

Les résultats vont majoritairement dans le sens de l’hypothèse initiale. En effet, dans quatre cas sur cinq, l’indice de Shannon diminue tandis que l’indice de Simpson augmente, ce qui suggère une perte de diversité chromatique et une homogénéisation des couleurs du paysage urbain après destruction. Une seule paire présente une évolution inverse, rappelant les limites de l’échantillon et la nécessité d’analyses complémentaires.

Discussion : limites et perspectives

Les deux indices utilisés ici sont ainsi complémentaires. Shannon renseigne sur la diversité et la répartition des couleurs au sein de la palette, tandis que Simpson met davantage en évidence la domination de certaines teintes. Dans le contexte des destructions urbaines, une diminution de Shannon accompagnée d’une augmentation de Simpson constitue donc un signal d’homogénéisation chromatique du paysage.

Plusieurs biais potentiels sont susceptibles d’influencer les mesures effectuées :

  1. Les images utilisées proviennent de Google Earth. Les dates d’acquisition, les capteurs mobilisés et les traitements appliqués aux images ne sont pas connus avec précision. Les résultats obtenus doivent donc être interprétés comme un test exploratoire plutôt que comme une démonstration rigoureuse au sens de la télédétection quantitative. Deux images provenant de satellites différents peuvent présenter des caractéristiques radiométriques distinctes : résolution spatiale, spectrale, compression ou traitement des couleurs. Dans un protocole plus rigoureux, il serait préférable d’utiliser des images acquises par un même capteur ou, à défaut, par des capteurs de caractéristiques comparables.
  2. Un second biais est lié à la saisonnalité. La végétation constitue souvent l’une des principales sources de diversité chromatique dans les paysages urbains. Une image acquise en été présentera généralement davantage de verts qu’une image acquise en hiver, indépendamment de toute destruction. Comparer des images prises à des périodes différentes de l’année peut donc introduire un biais important dans l’estimation de la diversité chromatique.
  3. Les conditions atmosphériques et d’éclairage constituent une troisième source d’incertitude. L’angle solaire, les poussières atmosphériques ou encore les différences d’exposition peuvent modifier l’apparence des couleurs observées sans que le paysage lui-même ait changé. Les praticien·nes de la télédétection disposent de nombreuses méthodes permettant de limiter ces effets.
  4. Un autre biais important concerne l’échelle des images. Les différents couples d’images utilisés dans cette analyse ne couvrent pas exactement la même superficie, car ils ne sont pas tous observés au même niveau de zoom. Or, la diversité chromatique mesurée dépend en partie des objets présents sur l’image et de leur poids relatif dans l’image. À grande échelle (fort niveau de zoom), les toitures, les véhicules, les arbres ou encore certains éléments du mobilier urbain occupent une proportion importante des pixels et contribuent fortement à la diversité des couleurs observées. À plus petite échelle, ces mêmes objets deviennent proportionnellement moins visibles, tandis que les grandes surfaces homogènes (routes, sols nus, quartiers entiers) prennent davantage de place dans l’image.
  5. Enfin, la méthode de suppression des ombres utilisée ici repose sur des seuils simples appliqués aux composantes HSV. Cette approche permet de réduire une partie du bruit lié à l’éclairage mais reste très éloignée des méthodes de détection d’ombres développées en télédétection.

Ces limites pourraient faire l’objet de développements méthodologiques plus importants. Par ailleurs, la diversité chromatique ne constitue qu’une dimension parmi d’autres de la couleur. D’autres indicateurs pourraient être mobilisés afin de caractériser plus finement les transformations des paysages, comme la saturation moyenne, la dispersion de la saturation, ou encore différentes mesures de contraste et de répartition des couleurs…

L’objectif de ce travail n’est pas de proposer une méthode opérationnelle de télédétection, mais d’explorer la faisabilité d’une mesure simple de la diversité et de l’homogénéisation chromatiques des paysages à partir d’images satellites librement accessibles.

Les indices de Shannon et de Simpson ont été développés pour mesurer la diversité (richesse spécifique) des écosystèmes. Leur mobilisation dans ce travail montre qu’il est possible de réutiliser des outils issus de l’écologie afin de quantifier certaines propriétés visuelles des paysages. En remplaçant les espèces par des classes de couleurs et les individus par des pixels, ces indicateurs deviennent capables de décrire statistiquement la diversité ou l’homogénéisation chromatique d’une image.

Car au-delà du cas des paysages de guerre, ce travail soulève une question plus générale : la couleur pourrait-elle devenir un indicateur géographique des transformations paysagères ? Les géographes s’intéressent depuis longtemps aux formes, aux usages, aux fonctions ou encore aux structures spatiales des territoires. Pourtant, la dimension chromatique des paysages reste relativement peu quantifiée. Il ne s’agit en effet pas ici d’utiliser la couleur pour détecter la végétation (NDVI), le bâti, l’eau ou un type particulier d’occupation du sol, mais bien de mesurer la diversité chromatique comme une propriété intrinsèque des paysages.