Les tons sépia et les dégradés de gris des vieilles photographies possèdent un charme unique, capturant des moments figés dans le temps. Pourtant, il leur manque souvent l’immédiateté vibrante de la scène originale. Imaginez insuffler les teintes de la vie à ces souvenirs chéris, transformant un portrait en noir et blanc délavé en une fenêtre révélant le monde du sujet en couleur. Ce processus transformateur, connu sous le nom de colorisation d’images, captive depuis longtemps les artistes et les historiens. Aujourd’hui, propulsée par les avancées de l’intelligence artificielle, en particulier le deep learning, la colorisation automatisée atteint des résultats qui relevaient autrefois de la science-fiction.
Apporter de la couleur à une image en niveaux de gris présente un défi fascinant. Une quantité significative d’informations – les données chromatiques originales – est intrinsèquement perdue lorsqu’une image est rendue en monochrome. Comment un algorithme peut-il connaître la vraie couleur d’une fleur, d’une robe ou du ciel à partir des seules valeurs de luminance ? La réponse réside dans les indices subtils intégrés dans l’image en niveaux de gris elle-même : textures, formes, contexte et jeu d’ombre et de lumière. Bien qu’il soit impossible de déterminer la couleur originale exacte (cette rose était-elle vraiment cramoisie, ou peut-être une nuance de rose ?), l’objectif se déplace vers la création d’une colorisation plausible et esthétiquement convaincante. Le but est de produire une image qu’un observateur humain trouverait crédible, voire potentiellement indiscernable d’une photographie couleur originale.
Les modèles de deep learning excellent dans la découverte de motifs complexes et de relations statistiques au sein de vastes ensembles de données. En entraînant ces modèles sur des millions d’images, en comparant les versions en niveaux de gris à leurs homologues couleur d’origine, les algorithmes apprennent à associer des textures et des structures spécifiques à des couleurs probables. Ils apprennent que l’herbe est généralement verte, que le ciel est souvent bleu et que certaines textures correspondent au grain du bois ou au tissu. C’est comparable à une supposition éclairée, mais informée par une énorme encyclopédie visuelle. L’algorithme ne ‘connaît’ pas la vraie couleur au sens humain, mais il peut faire des prédictions très probables basées sur des corrélations apprises.
Le Langage de la Couleur : CIELab et Réseaux Neuronaux
Pour aborder la colorisation de manière computationnelle, nous avons besoin d’un moyen approprié pour représenter la couleur. Bien que le RGB
(Rouge, Vert, Bleu) soit courant pour les affichages, il mélange les informations de luminance (luminosité) et de chrominance (couleur). Un système plus avantageux pour cette tâche est l’espace colorimétrique CIELab. Ce modèle sépare élégamment la couleur en trois composantes distinctes :
- L (Lightness/Luminosité) : Ce canal représente l’information en niveaux de gris, allant du noir pur au blanc pur. C’est essentiellement les données d’entrée que nous avons déjà dans une image en noir et blanc.
- a : Ce canal encode le spectre allant du vert (valeurs négatives) au rouge (valeurs positives).
- b : Ce canal encode le spectre allant du bleu (valeurs négatives) au jaune (valeurs positives).
La beauté de CIELab
réside dans cette séparation. Notre modèle de deep learning peut se concentrer sur la prédiction des deux canaux de chrominance (‘a’ et ‘b’) en se basant uniquement sur le canal de Luminosité (‘L’) d’entrée. La tâche principale devient : étant donné l’information en niveaux de gris (L), quelles sont les valeurs ‘a’ et ‘b’ correspondantes les plus probables pour chaque pixel ?
Les premières tentatives utilisaient souvent des Réseaux Neuronaux Convolutifs (CNN
) – un type d’architecture de deep learning particulièrement adapté au traitement de données en grille telles que les images. Ces réseaux étaient entraînés sur de grands ensembles de données d’images (comme ImageNet
) pour prédire directement les valeurs ‘a’ et ‘b’ pour chaque pixel, le traitant comme un problème de régression (prédire des valeurs continues). Cependant, un écueil courant est apparu : les colorisations résultantes semblaient souvent désaturées ou ternes. Pourquoi ? Considérez un objet comme une pomme. Elle pourrait plausiblement être rouge, verte ou même jaune. Si le réseau essaie de moyenner ces possibilités lors de la régression, il pourrait se contenter d’un compromis brunâtre et terne au lieu d’une couleur vibrante et spécifique. Cet effet de moyennage sur plusieurs couleurs plausibles avait tendance à délaver les résultats.
Un Changement de Paradigme : La Colorisation comme Classification
Pour surmonter le problème de la désaturation et produire des couleurs plus vibrantes et réalistes, une approche plus sophistiquée recadre le problème. Au lieu de traiter la prédiction des couleurs comme une régression, elle est considérée comme une tâche de classification.
Voici le changement conceptuel :
- Espace Colorimétrique Quantifié : Le spectre continu des valeurs ‘a’ et ‘b’ possibles est discrétisé en un ensemble prédéfini de ‘cases’ ou classes de couleurs représentatives. Pensez-y comme la réduction d’une vaste palette à un ensemble gérable, mais complet, d’options de couleurs distinctes dans le plan ‘a’-‘b’.
- Prédiction de Probabilités : Pour chaque pixel de l’image en niveaux de gris d’entrée, le
CNN
ne prédit pas une seule valeur ‘a’ et ‘b’. Au lieu de cela, il produit une distribution de probabilités sur les cases de couleurs quantifiées. Il dit essentiellement : ‘Pour ce pixel, il y a 70% de chances qu’il appartienne à la ‘case rouge vif #5’, 20% de chances qu’il soit ‘case rouge pâle #2’, 5% de chances qu’il soit ‘case brunâtre #12’’, et ainsi de suite. - Gestion de l’Ambigüité : Cette approche probabiliste gère intrinsèquement l’ambiguïté des couleurs. Si un objet peut avoir plusieurs couleurs (comme la pomme), le réseau peut attribuer des probabilités significatives à plusieurs cases de couleurs différentes, reflétant cette incertitude sans recourir à une moyenne fade.
- Décodage vers une Couleur Vibrante : L’étape finale consiste à traduire cette distribution de probabilités en une seule couleur spécifique pour chaque pixel. Une approche naïve pourrait être de simplement choisir la case de couleur avec la probabilité la plus élevée (le mode). Cependant, pour encourager la vivacité et éviter le problème de désaturation, des techniques comme le calcul de la moyenne recuite (annealed mean) de la distribution sont utilisées. Cette méthode accorde plus de poids aux prédictions moins probables mais plus colorées (saturation plus élevée), ‘tranchant’ efficacement en faveur de la vivacité tout en respectant la distribution globale prédite.
Ce cadre de classification, combiné à une conception soignée de la fonction de perte (la métrique utilisée pour évaluer les performances du modèle pendant l’entraînement) spécifiquement pour la colorisation, permet au modèle d’apprendre la relation complexe entre les caractéristiques des niveaux de gris et la distribution des couleurs probables. Le résultat est des images qui sont non seulement colorisées de manière plausible, mais qui possèdent également une richesse et un attrait visuel souvent absents dans les méthodes antérieures basées sur la régression.
Un Aperçu Sous le Capot : Un Flux de Travail Pratique en Deep Learning
Bien que l’entraînement d’un CNN
aussi sophistiqué à partir de zéro soit une tâche monumentale nécessitant d’immenses ressources de calcul et de vastes ensembles de données, l’utilisation de modèles pré-entraînés rend cette technologie accessible. Parcourons les étapes conceptuelles impliquées dans l’utilisation d’un modèle de deep learning pré-entraîné (spécifiquement un construit à l’aide du framework Caffe
, comme dans l’exemple original) pour la colorisation d’images, implémenté en utilisant Python
et des bibliothèques courantes.
1. Assembler la Boîte à Outils :
La base implique généralement Python
, un langage de programmation polyvalent populaire en science des données et en IA. Des bibliothèques clés jouent des rôles cruciaux :
NumPy
: Essentiel pour des opérations numériques efficaces, en particulier la manipulation des tableaux multidimensionnels qui représentent les images.OpenCV
(cv2
) : Une bibliothèque puissante pour les tâches de vision par ordinateur. Elle fournit des fonctions pour lire, écrire, manipuler et afficher des images, et surtout, inclut un module de Réseau Neuronal Profond (DNN
) capable de charger et d’exécuter des modèles entraînés dans divers frameworks commeCaffe
,TensorFlow
etPyTorch
.Argparse
: Une bibliothèquePython
standard pour créer des interfaces de ligne de commande conviviales, permettant aux utilisateurs de spécifier facilement les paramètres d’entrée comme le chemin du fichier image.OS
: Utilisé pour les interactions de base avec le système d’exploitation, comme la construction de chemins de fichiers de manière compatible entre différents systèmes (Windows
,macOS
,Linux
).
2. Acquérir l’Intelligence Pré-Entraînée :
Au lieu de construire le réseau neuronal brique par brique, nous utilisons des fichiers représentant un réseau déjà entraîné pour la colorisation. Ceux-ci incluent généralement :
- Fichier d’Architecture du Modèle (
.prototxt
pourCaffe
) : Ce fichier définit la structure du réseau neuronal – les couches, leurs types, connexions et paramètres. C’est le plan du modèle. - Fichier de Poids Entraînés (
.caffemodel
pourCaffe
) : Ce fichier contient les poids numériques appris par le réseau lors de son processus d’entraînement intensif. Ces poids encapsulent la ‘connaissance’ que le modèle a acquise sur la mise en correspondance des caractéristiques des niveaux de gris avec les probabilités de couleur. C’est l’intelligence distillée. - Données de Quantification des Couleurs (fichier
.npy
) : Ce fichierNumPy
stocke généralement les points centraux des cases de couleurs quantifiées utilisées dans l’approche de classification décrite précédemment. Il sert de palette de référence pour les probabilités de couleur prédites.
Ces fichiers représentent l’aboutissement de potentiellement des semaines ou des mois d’entraînement sur du matériel puissant.
3. Charger le Moteur de Colorisation :
Avec les fichiers nécessaires localisés, le module DNN
d’OpenCV
fournit le mécanisme pour charger le réseau pré-entraîné en mémoire. La fonction cv2.dnn.readNetFromCaffe
(ou des équivalents pour d’autres frameworks) prend les fichiers d’architecture et de poids en entrée et instancie le réseau, le rendant prêt pour l’inférence (le processus de faire des prédictions sur de nouvelles données). Les points de quantification des couleurs du fichier .npy
sont également chargés, généralement à l’aide de NumPy
.
4. Ajuster les Composants du Réseau (Si Nécessaire) :
Parfois, des couches spécifiques au sein du réseau pré-entraîné nécessitent des ajustements mineurs avant l’inférence. Dans le contexte du modèle de colorisation basé sur la classification discuté :
- Ajustement de la Couche de Sortie : La couche finale responsable de la sortie des prédictions des canaux ‘a’ et ‘b’ (par exemple, nommée
class8_ab
dans le modèle de référence) pourrait nécessiter d’être explicitement chargée avec les centres des cases de couleur du fichier.npy
. Cela garantit que les probabilités de sortie du réseau correspondent correctement à la palette de couleurs prédéfinie. Les points sont souvent remodelés et convertis au type de données approprié (par exemple,float32
) avant d’être assignés aux ‘blobs’ de la couche (terme deCaffe
pour les conteneurs de données). - Rééquilibrage des Couleurs : Une autre couche (par exemple,
conv8_313_rh
) pourrait être ajustée pour influencer l’équilibre entre les différentes couleurs dans la sortie, potentiellement en augmentant la saturation ou en corrigeant les biais appris pendant l’entraînement. Cela implique souvent de définir les blobs de la couche sur des valeurs spécifiques apprises (comme la valeur2.606
mentionnée dans le code original, probablement dérivée empiriquement ou pendant l’entraînement).
Ces étapes adaptent le modèle pré-entraîné générique aux nuances spécifiques de la tâche de colorisation en utilisant l’approche de classification.
5. Préparer l’Image d’Entrée :
L’image en niveaux de gris d’entrée doit subir plusieurs étapes de prétraitement avant d’être fournie au réseau neuronal :
- Chargement : L’image est lue à partir du chemin de fichier spécifié en utilisant
cv2.imread
. Même si elle est en niveaux de gris,OpenCV
peut la charger par défaut comme une imageBGR
à 3 canaux, en dupliquant la valeur de gris sur les canaux. - Normalisation : Les valeurs des pixels, allant généralement de 0 à 255, sont mises à l’échelle dans une plage plus petite, souvent de 0.0 à 1.0, en divisant par 255.0. Cette normalisation aide à stabiliser le processus d’apprentissage et d’inférence du réseau.
- Conversion de l’Espace Colorimétrique : L’image est convertie de l’espace colorimétrique
BGR
par défaut à l’espace colorimétriqueCIELab
en utilisantcv2.cvtColor
. Ceci est crucial pour isoler le canal de Luminosité (L). - Redimensionnement : La plupart des
CNN
pré-entraînés attendent des images d’entrée d’une taille fixe (par exemple, 224x224 pixels, une norme courante influencée par des ensembles de données commeImageNet
). L’imageLAB
est redimensionnée en conséquence en utilisantcv2.resize
. Cette standardisation assure la compatibilité avec l’architecture du réseau. - Isolation et Centrage du Canal L : Le canal de Luminosité (L) est extrait de l’image
LAB
redimensionnée. Souvent, ses valeurs (typiquement 0-100 enLAB
) sont ensuite centrées autour de zéro en soustrayant une valeur moyenne (par exemple, 50). Ce centrage est une autre pratique courante qui peut améliorer les performances du réseau.
Ce canal L méticuleusement prétraité est maintenant prêt à être présenté au réseau.
6. L’Étape d’Inférence : Prédire la Couleur :
C’est ici que la magie opère :
- Création du Blob : Le canal L traité (maintenant un tableau 2D) est converti en un ‘blob’, un format de tableau 4D attendu par le module
DNN
(cv2.dnn.blobFromImage
). Ce format inclut généralement des dimensions pour la taille du lot (batch size), les canaux, la hauteur et la largeur. - Passe Avant (Forward Pass) : Le blob est défini comme entrée du réseau chargé en utilisant
net.setInput
. Ensuite, la méthodenet.forward()
est appelée. Cela déclenche le calcul : les données d’entrée circulent à travers les couches du réseau, subissant des transformations dictées par les poids appris, produisant finalement la sortie prédite. Pour notre modèle de colorisation, la sortie représente les canaux ‘a’ et ‘b’ prédits (ou plutôt, les distributions de probabilités sur les cases de couleur). - Remodelage de la Sortie : La sortie brute du réseau doit être remodelée et transposée pour retrouver un format spatial 2D correspondant aux canaux ‘a’ et ‘b’.
Le réseau a maintenant généré sa meilleure estimation pour l’information de couleur basée sur l’image en niveaux de gris d’entrée.
7. Reconstruire l’Image Couleur :
L’étape finale consiste à combiner l’information de couleur prédite avec les données de l’image originale :
- Redimensionnement des Canaux Prédits : Les canaux ‘a’ et ‘b’ prédits (qui sont actuellement de taille 224x224, correspondant à l’entrée du réseau) doivent être redimensionnés aux dimensions originales de l’image d’entrée en utilisant
cv2.resize
. Cela garantit que l’information de couleur s’aligne correctement avec la structure de l’image originale. - Extraction de la Luminosité Originale : Crucialement, le canal de Luminosité (L) est extrait de l’image
LAB
originale, de taille complète (créée pendant le prétraitement avant le redimensionnement). L’utilisation du canal L original préserve les détails et la structure de luminance originaux de l’image, qui seraient dégradés si le canal L redimensionné était utilisé. - Concaténation : Le canal L original est combiné (concaténé) avec les canaux ‘a’ et ‘b’ redimensionnés et prédits le long de l’axe des canaux de couleur. Cela réassemble une image
LAB
complète, maintenant avec la couleur prédite. - Conversion vers un Format Affichable : L’image
LAB
résultante est reconvertie dans l’espace colorimétriqueBGR
en utilisantcv2.cvtColor
, car c’est le format standard attendu par la plupart des fonctions d’affichage d’images (commecv2.imshow
). - Écrêtage (Clipping) et Mise à l’Échelle : Les valeurs des pixels dans l’image
BGR
, actuellement dans la plage normalisée (probablement 0.0 à 1.0), sont écrêtées pour s’assurer qu’elles restent dans cette plage valide (les valeurs peuvent parfois dépasser légèrement les limites en raison du processus de prédiction). Ensuite, elles sont remises à l’échelle dans la plage entière standard de 0 à 255 requise pour l’affichage ou l’enregistrement en tant que fichier image standard.
8. Visualisation :
Enfin, des fonctions comme cv2.imshow
peuvent être utilisées pour afficher l’image en niveaux de gris originale à côté de son homologue nouvellement colorisée, permettant une comparaison visuelle immédiate.
Exécution du Processus :
Typiquement, un script implémentant ces étapes serait exécuté depuis la ligne de commande. En utilisant la configuration argparse
, l’utilisateur fournirait le chemin vers l’image en niveaux de gris d’entrée comme argument (par exemple, python colorize_image.py --image ma_photo.jpg
). Le script exécute ensuite les étapes de chargement, de prétraitement, d’inférence et de reconstruction, affichant ou sauvegardant finalement le résultat colorisé.
Ce flux de travail, exploitant des modèles pré-entraînés et des bibliothèques puissantes, transforme la théorie complexe de la colorisation par deep learning en un outil pratique capable d’ajouter des couleurs vibrantes et plausibles aux images monochromes, comblant ainsi efficacement le fossé entre le passé et le présent.