Hackathon II - Annotation et la segmentation sémantique d'image
Bas-relief annoté, Kaṇagaṇahaḷḷi, Inde, Ier - IIIe siècles (© Léa Maronet)
Introduction
⭐︎ Contexte
L’annotation est une étape cruciale dans l’entraînement des modèles de vision par ordinateur (et elle est particulièrement critique pour les corpus que les modèles ne sont pas habitués à traiter, à l’instar des corpus patrimoniaux) mais elle est une étape laborieuse et fastidieuse.
“Annotation is a well-defined problem. It addresses a key need in supervised machine learning; and it is so onerous that no engineer or scientist wants to do it themselves.” (Corso 2024)
De plus, dans le domaine de l’histoire de l’art numérique, l’annotation est, malgré une illusion qui subsiste en sciences humaines et sociales, loin d’être toujours juste et exhaustive (Morlock et Stutzmann 2024). Elle doit en effet répondre à une problématique propre aux corpus patrimoniaux dont la considération ne peut se restreindre à une simple conception positiviste des objets : il existe une multiplicité d’interprétations possibles pour une même image, un même objet (Arnold et Tilton 2019). Elle constitue par conséquent une étape cruciale dans tout projet de recherche, où l’annotation du corpus doit être adaptée aux spécificités des problématiques de recherche propres à chaque étude.
Actuellement, les workflows en histoire de l’art numérique suivent un schéma classique : les chercheurs annotent manuellement les images, puis utilisent ces annotations pour entraîner des modèles. Pourquoi ne pas inverser cette logique en adoptant un modèle de segmentation ou de détection d’objets dès le départ, afin de rendre le processus d’annotation plus rapide, précis et corrigible ?
Deux avancées majeures dans le domaine de la vision par ordinateur permettent d’aller dans ce sens : la capacité du modèle Segment Anything (SAM) de Meta à segmenter une zone d’intérêt dans une image avec un minimum d’informations (un ou deux points, une boîte) et la capacité des modèles de type Vision Transformer (dont SAM fait partie) à évaluer la similarité entre deux images.
⭐︎ Objectifs
⇒ Annotation d’images RAPIDE ET PRECISE dans un notebook Jupyter.
Avec une correction par l’utilisateur au fur et à mesure, pour minimiser au maximum les inconsistances et les erreurs. Donc l’idée est d’allier un modèle de segmentation et de clustering pour sa rapidité et le traitement en lots avec la correction par l’utilisateur pour limiter les erreurs.
Le cas d’usage est d’identifier rapidement, sur des images, certains motifs iconographiques et de créer des masques et des étiquettes associés à ceux-ci, afin de produire un jeu de vérités de terrain pour entraîner un modèle :
- Utiliser SegmentAnything pour produire des masques à partir d’un seul point (ou d’un nombre très réduit, maximum 3/4 par motif) ;
- Ajouter des étiquettes aux masques produits ;
- Enregistrer les objets identifiés.
D’autres étapes du workflow d’annotation classique sont également automatisables et sont soit testées, soit formalisées ici. Notamment :
- Produire automatiquement des masques sur des images non-traitées par recherche de similarité avec les objets identifiés préalablement ;
- Associer des objets identifiés à des objets non-identifiés afin d’étiqueter ces derniers ;
- Présenter à l’utilisateur les cas limites d’objets non-identifiés similaires à plusieurs objets qui le sont ;
- Repérer des formes caractéristiques d’objets identifiés sous forme de sous-masques spécifiques à leur catégorie.
Processus
Plusieurs processus ont été envisagés en s’interrogeant sur quelles étapes doivent être réalisées par l’utilisateur et lesquelles le doivent être automatiquement.
⭐︎ Cas 1 : Vérification a priori
- Cliquer sur le(s) motif(s) dans les images ;
- Corriger les masques dans chaque image avec d’autres clics (+/-) si nécessaire ;
- Extraire les masques produits ;
- Comparer les masques avec un calcul de distance et les regrouper en fonction de leur proximité ;
- Étiqueter les motifs selon les groupes formés.
⭐︎ Cas 2 : Vérification a posteriori
- Cliquer sur le(s) motif(s) dans les images ;
- Extraire les masques produits ;
- Comparer les masques avec un calcul de distance et les regrouper en fonction de leur proximité ;
- Étiqueter les motifs selon les groupes formés ;
- Correction des masques qui ne sont pas attribués aux bons groupes.
⭐︎ Cas 3 : Étiquetage au fur et à mesure
- Cliquer sur le(s) motif(s) dans quelques images ;
- Extraire les masques produits et leur attribuer une étiquette ;
- Pour les images suivantes, recherche automatique des masques similaires à partir de celles déjà annotées en fonction de leur proximité, avec un étiquetage automatique ;
- Validation manuelle des propositions ;
- (Recherche supplémentaire si nécessaire sur les images avec différents paramètres, notamment avec une contrainte de distance plus “lâche”).
De nombreux flux de travail peuvent être envisagés. Nous avons fait le choix du cas 1 qui permet une production de masques propres dès le débat. Le cas 2 est certainement moins chronophage pour l’utilisateur et plus efficace mais il est plus lourd en code et en calcul. La qualité des masques produits dans le cas 3 peut grandement varier en fonction des données et des paramètres des algorithmes.
Étapes du hackathon et expérimentations
⭐︎ Étapes réalisées
- Adapter le code de SegmentAnything à nos données ;
- Rendre l’image interactive pour pouvoir enregistrer les coordonnées des points ;
- Extraire les masques des images et les enregistrer dans des arrays ;
- Transformer les arrays pour :
- Supprimer la partie de l’image où il n’y a pas de masque ;
- Avoir le même nombre de points dans chaque masque ;
- Ne conserver que les points qui forment le contour de l’objet ;
- Normaliser les masques pour qu’ils soient sur le même plan, qu’ils aient le même ordre de grandeur, et à peu près la même orientation (analyse procrustéenne) et supprimer les masques intérieurs dans le cas de masques superposés ;
- Comparer plusieurs calculs de distance:
- Algorithmes de comparaison de courbes ;
- Algorithmes de comparaison de caractéristiques d’images (type SURF/SIFT) ;
- Similarité cosinus entre deux vecteurs (embeddings) obtenus par un ViT (Vision Transformers) ;
- Produire un graphe pour afficher les différents objets et comparer leurs distances ;
- Réassigner les masques à la photographie d’origine ;-Enregistrer les masques associés au nom de l’image, avec les coordonnées des points et leur étiquette dans un fichier .json (basé sur le format de sérialisation des fichiers VGG).
⭐︎ Expérimentations infructueuses sur les calculs de distance
Deux manières de calculer la proximité des masques ont été testées :
- À partir des coordonnées des points formant les masques ;
- En comparant directement les images des motifs en ne conservant que la partie de l’image d’origine située dans le masque.
‣ Calculs à partir des coordonnées des masques
- Avantages : elle mesure la similarité entre deux courbes en tenant compte de l’ordre des points sur les courbes ; elle est moins sensible aux petites perturbations ou irrégularités tant que celles-ci ne modifient pas l’ordre des points de manière significative ;
- Exigences : elle nécessite, donc, de conserver l’ordre des points des masques (c’est possible si l’on ne créé pas nouveau masque dans la variable
contours
dedraw.Countours
) mais du coup, quand le motif est séparé en plusieurs pièces, elles sont considérées comme des objets différents (il faut donc conserver uniquement le masque dont le tracé est le plus grand) ; - Résultats : ne trouve qu’une proximité très réduite entre les motifs de la même classe.
- Avantages : elle est plus simple à calculer car elle réalise la moyenne de la distance des x et des y ; l’ordre des points des contours n’a, par conséquent, pas besoin d’être conservé ;
- Résultats : les motifs de la même classe ne sont pas plus proches que les motifs appartenant à des classes différentes.
Autre tentative :
- Comparer les coordonnées de tous les points du masque, pas uniquement ceux à formant le contour du masque. Les résultats sont tout aussi peu satisfaisants.
⇒ Malgré que ces distances soient employées dans la littérature scientifique pour comparer des formes, les résultats obtenus sur nos jeux de données sont peu satisfaisants. Cela peut être dû au fait que les motifs analysés possèdent des contours irréguliers ou des détails fins qui peuvent ne pas être bien captés par ces métriques.
‣ Calculs par comparaison des images
- Avantages : ces méthodes extraient des caractéristiques saillantes des images, telles que les contours, les coins ou les points clés qui sont ensuite comparés entre les images ;
- Résultats : les caractéristiques saillantes (qui sont pourtant relativement similaires sur les deux motifs d’éléphant ci-dessous) ne sont pas mis en perspectives.
⇒ Ces résultats indiquent que les motifs artistiques étudiées ont des caractéristiques visuelles difficiles à capturer par de telles méthodes de détection de points clés.
⭐︎ Problèmes identifiés et résolutions
Problème d’interactivité du notebook :
- Selon l’environnement dans lequel le notebook est lancé, l’interactivité (le fait de cliquer directement sur l’image pour sélectionner les points du masque à créer) ne fonctionne pas de la même façon ;
- Le code a dû être adapté selon que le notebook soit lancé dans un environnement conda (en local ou sur un des serveurs du CC), ou dans Google Colab (sur le serveur du CC, l’interactivité n’est pas (encore) fonctionnelle).
Problème du poids des masques produits par SegmentAnything :
- Les masques produits possèdent un très grand nombre de points, sur toute la surface du masque, alors que pour notre cas, et pour les algorithmes de comparaison de courbe, nous avons seulement besoin du contour du masque.
- Même en ne conservant que le contour, un grand nombre de points persiste. La réduction du nombre de points doit être cohérente (en conservant ceux à x distance du précédent par exemple) afin de ne pas perdre les petites variations dans la forme du masque.
Problème de normalisation :
- Les images et donc les masques ne sont pas de la même taille, ne sont pas sur le même plan et les images ne sont pas orientées de la même façon, ce qui entraîne des difficultés pour la comparaison des masques ;
- D’autres problèmes de normalisation sont également à noter :
- éclairage et couleur des des images (certaines sont en couleurs et d’autres en noir et blanc) ;
- érosion et état de conservation variable des sculptures ;
- orientation de la prise de vue ;
- …
- La normalisation a pu être effectuée grâce à l’analyse procrustéenne, via son implémentation dans la librairie Scipy.
Problèmes dans les calculs de distance :
- Aucune des distances quand appliquée à la comparaison des points des masques n’offre de résultat très satisfaisant (peu importe quelle manière de calculer la distance a été choisie) ;
- La solution trouvée a été de réaliser le clustering à l’aide d’un modèle de deep learning (le choix a été porté sur le modèle
'ViT-H-14-378-quickgelu'
, et son pré-entrainement'dfn5b'
qui est le plus performant de la librairie OpenClip) qui fonctionne très bien sur les images de test (de plus amples vérifications seront nécessaires). Des modèles plus récents, évolutions de modèles types ViT ou autres, seraient peut être plus performants. Cependant, pour notre cas, les résultats étaient suffisamment précis: les éléphants et les lotus ont bien été correctement groupés.
⭐︎ Sorties du notebook
Visualisations :
- Un graphe pour afficher les distances entre les masques
- Un affichage tabulaire des masques et leur étiquette
Fichiers :
- Un .json avec le nom de l’image, les coordonnées des points des masques, les étiquettes ;
- Un .csv avec les distances entre les masques.
Ce qu’il reste à faire
⭐︎ Améliorations et ajouts envisagés
- Tester le code sur un plus grand nombre d’images, avec des motifs plus variés et différents ;
- Produire un graphe/arbre de possibilités pour avoir une vision plus claire des cas d’usage et du parcours utilisateur ;
- Comparer d’autres calculs de distance ;
- Produire un notebook propre pour démonstration avec une documentation claire ;
- Identifier les contours intérieurs des motifs pour mettre au point une classification hiérarchique avec une visualisation ;
- Ajouter quelques fonctions pour réaliser du pré-traitement des images et pouvoir les recadrer/nettoyer, etc.
- Traiter les images en lots ;
- Assigner des étiquettes aux masques proches à la suite du clustering.
⭐︎ Perspectives de recherche
- Avoir plusieurs cas d’usages et plusieurs parcours utilisateurs ;
- Mettre au point une classification hiérarchique des motifs et des éléments qui les composent ;
- Remplacer la récupération des contours externes par celle des contours internes et avoir des masques plus précis par motif pour pouvoir faire des comparaisons plus fine que la forme globale.
Références
- Arnold, Taylor, et Lauren Tilton. « Distant viewing: analyzing large visual corpora ». Digital Scholarship in the Humanities 34, nᵒ 1 (2019): i3‑16.
- Corso, Jason. « Annotation is dead ». Medium, 2024. https://medium.com/@jasoncorso/annotation-is-dead-1e37259f1714.
- Maiseli, Baraka Jacob. « Hausdorff Distance with Outliers and Noise Resilience Capabilities ». SN Computer Science 2 (2021): 358:1-14. https://link.springer.com/article/10.1007/s42979-021-00737-y.
- Morlock, Emmanuelle, et Dominique Stutzmann. « Quelles démarches “Low Tech” pour l’innovation numérique dans le domaine des cultures écrites anciennes ». Présenté à Séminaire commun Huma-Num - MSH Mondes, Nanterre, 2024.
- Ravi, Nikhila, et al. « SAM 2: Segment Anything in Images and Videos ». GitHub, 2024. https://github.com/facebookresearch/sam2.
- Reddy, Vasista. « Exploring Image Similarity Approaches in Python ». Medium, 2023. https://medium.com/scrapehero/exploring-image-similarity-approaches-in-python-b8ca0a3ed5a3.
- Roman. « Image Similarity Comparison using VGG16 Deep Learning Model ». Medium, 2023. https://medium.com/@developerRegmi/image-similarity-comparison-using-vgg16-deep-learning-model-a663a411cd24.
- Wenner, Nelson. « Shape Similarity ». GitHub, 2024. https://github.com/nelsonwenner/shape-similarity.
Playlist
- Glass Beams
- Sunday Morning - The Velvet Underground
- Mr. Morale & The big steppers - Kendrick Lamar
- 50 ways to leave your lover - Paul Simon
- Prelude to ecstasy - The last dinner party