ImageJ : le traitement d’image… pour les scientifiques
Pour mon stage de M2R que j’effectue actuellement, je dois traiter des images issues de caméras rapide, linéaire ou classique. Je regarde des gouttes qui descendent le long d’une fibre verticale ; c’est magnifique, c’est de la physique !
J’avais déjà entendu des louanges à propos de ce logiciel que l’on m’a conseillé d’utiliser : ImageJ. ImageJ est codé en Java, est multiplateforme, et appartient au domaine public. Dans la deuxième page de la documentation, les auteurs font même référence à la culture du logiciel libre en reprenant les quatre libertés de R.M.S. c’est suffisamment touchant pour que ce soir remarqué. ImageJ était développé initialement pour les gens travaillant dans le biomédical, mais son succès l’a propulsé dans d’autres sphères scientifiques comme la physique ou l’astronomie.
D’un point de vue fonctionnalités, ce logiciel permet de traiter plusieurs formats : TIFF, PNG, GIF, JPEG, BMP… et comporte de nombreuses fonctionnalités nativement (Opérations mathématiques de base, lissage, FFT, détection de contours…) Si on souhaite pousser le logiciel dans ses retranchements, on peut toujours utiliser des greffons disponibles par dizaines et écrire de petites macros afin d’automatiser des traitements récurrents. C’est ce dernier point que je vais illustrer dans cet article. Je ne vais pas vous expliquer en détail les lignes de code, mais je veux simplement vous montrer la puissance et la simplicité d’utilisation.
Profil d’une goutte (exemple simple)
Je commence par le profil d’une goutte, une macro très simple, de quelques lignes, qui va vous montrer à quel point c’est facile. Avant toute chose, je vous conseille de vous procurer ce PDF de 20 pages vous donnant toutes les clefs du langage (très simple, trivial même pour les codeurs C, C++, Java…).
Comme l’indique la figure ci-dessous, à gauche, on a l’image initiale prise à l’aide d’une caméra couleur. De gauche à droite, les étapes du traitement pour obtenir le profil des gouttes sur la fibre.
L’image est d’abord convertie en 8-bits [image 2] puis on améliore le contraste (environ 1% de pixels saturées) et on supprime le fond (du moins on l’atténue) [image 3]. On ajuste (automatiquement) le seuil [image 4] ce qui nous donne une image bicolore qui peut subir une détection des frontières [image 5]. On squeletise pour ne garder que des lignes d’un pixel de largeur. La tour est joué ! Il ne reste plus qu’à mettre cela dans un script pour faciliter le traitement de masse.
Diagramme spatio-temporel (plus poussé)
Sans entrer dans les détails encore une fois, la caméra linéaire me fournit un diagramme spatio-temporel que voici :
L’objectif est de détecter la distance entre deux lignes du diagramme (distance entre deux gouttes) ainsi que de mesurer la pente de ces lignes (vitesse des gouttes). En outre, je vais ajouter la possibilité de prendre un “blanc” afin que le traitement soit meilleur (même si cela ne s’est pas avéré nécessaire dans mes tests préliminaires, ça peut se révéler utile). Ce blanc sera soustrait à l’image initiale après avoir demandé à l’utilisateur s’il possède ce blanc. Celui utilisé pour ces tests n’ayant pas été pris dans les meilleures conditions, je n’ai pas réussit à soustraire toute la partie gauche qui correspond au dispositif d’injection du liquide. Par contre, la ligne verticale du bas (récipient) a bien été supprimée comme on va le voir sur le résultat final.
On effectue quelques traitements “classiques” comme le renforcement du contraste (la nombre de pixel saturé est ici corrélé aux nombres de lignes que l’on veut distinguer…), le seuillage, la détection de contours et la squelettisation afin d’obtenir à nouveau des lignes de pixels. (La ligne verticale à droite est bien absente)
En bouclant sur une ligne horizontale, j’obtiens alors la position de ces lignes et donc la distance entre mes gouttes. La pente demande un peu plus de ruse. Il existe un outil de type “baguette magique” qui va permettre de sélectionner une ligne. Par encadrement d’un rectangle, je récupère la hauteur et la largeur de celui-ci pour en extraire la pente de la diagonale qu’est ma droite. J’effectue alors quelques manipulations d’IO (input/output : entrée/sortie) pour ranger toutes les informations dans un fichier. Le travail est fini ! A nouveau, le script est disponible ici. Des choses sont inutiles dedans, mais je les laisse à caractère informatif. Typiquement, le fichier de résultat est de la forme :
#7/1/2010-14:52
#title=00000537.bmp
#width=2000
#height=2000
#HorPosition // slopex // slopey // slope
67 14 1982 141.5714
[...]
1581 134 1639 12.2313
1970 96 1237 12.8854
Conclusion
Par ces deux exemples, j’espère avoir montré en quoi ImageJ permet de traiter facilement vos images pour en extraire des informations, que ce traitement est facile et automatisable sans peine. En quelques coups de clavier, je suis désormais capable de traiter rapidement un grand nombre d’images.
J’ai obtenu ces résultats après une dizaine d’heures d’utilisation, ce n’est sans doute pas parfait ni idéal, mais les résultats sont tout à fait satisfaisant avec un processus de traitement efficace et sans y passer des heures en amont. Ce logiciel libre rempli tous les critères que je pouvais me donner.