TP - Introduction à ImageJ - dept

Transcription

TP - Introduction à ImageJ - dept
TP
1
TP - Introduction à ImageJ
Nicholas Journet / Anne Vialard - Traitement d’images - LPRO - 2016/2017 1
Supports : http://dept-info.labri.fr/∼vialard/Traitement/
1.1
Prise en main de ImageJ
ImageJ est un logiciel libre de traitement et d’analyse d’images, inspiré du logiciel NIH Image, développé par le NIH et
implémenté par la communauté des scientifiques. Il fonctionne sous de multiples plates-formes (Windows, Mac, Linux,
Unix,...). Il est disponible ainsi que toute la documentation associée à l’adresse suivante :http://rsbweb.nih.gov/ij/.
ImageJ possède de nombreuses fonctions, entre autres :
ä
ä
ä
ä
ä
ä
ä
ä
ä
affichage, édition, analyse, et traitement d’images 8, 16 ou 32 bits
ouverture d’images multiformats : TIFF, GIF, JPEG, BMP, PGM ...
ouverture de piles d’images, série d’images affichées dans une même fenêtre.
calculs d’aires et valeurs de pixels de régions définies par l’utilisateur
mesures de distances, mesures d’angles
histogrammes, profils d’intensité le long d’une ligne
modification de contraste, sharpening, smoothing, détection de bords, filtre médian...
transformations géométriques : rotation, flip...
automatisation des tâches par création de macros et de plugins.
Question 1
ä Lancez ImageJ (l’exécutable run fait partie des fichiers fournis).
ä Explorez les menus et testez les différentes fonctionnalités des menus Image et Process. Un choix
d’images est disponible via le menu File/Open Samples.
1.2
Programmation de plugins
ImageJ est un logiciel dont les fonctions peuvent être étendues par le biais de plugins. Les plugins sont des classes
Java.Nous allons créer un premier plugin afin d’en étudier la structure.
1. Support inspiré du tutoriel ImageJ de l’IJM
1
Question 2
Avec votre éditeur préféré créez le fichier Mon_Script.java. Ce fichier contiendra le code suivant :
1
2
3
import ij .*;
import ij . process .*;
import ij . plugin . filter .*;
4
5
6
7
8
public class Mon_Script implements PlugInFilter {
public void run ( ImageProcessor ip ) {
ip . invert () ;
}
9
public int setup ( String arg , ImagePlus imp ) {
if ( arg . equals ( " about " ) ) {
IJ . showMessage ( " Inversion video " ) ;
return DONE ;
}
return DOES_8G ;
}
10
11
12
13
14
15
16
17
}
Question 3
Exécutez ce code (Menu Plugins/Compile and Run de ImageJ, le plugin doit se trouver dans le même répertoire que le fichier run).
Sur quel type d’images fonctionne-t-il ? Que fait-il ? Expliquez les lignes de code 1,7,8 et 9. Quel est le rôle des
lignes 13 à 15 ? Peut-on les supprimer ?
Remarque : si vous relancez ImageJ, le nouveau plugin apparaitra dans le menu Plugins.
Vous pouvez également travailler avec l’environnement de développement Eclipse en suivant les étapes suivantes :
ä Configurer Eclipse pour Java
ä Créer un projet correspondant à l’ensemble des travaux pratiques de traitement d’image. L’assistant permet de
séparer les sources (.java) des fichiers compilés (.class). Vous choisirez plugins au lieu de bin comme valeur
de default output folder.
ä Ajouter l’archive ImageJ. Après un clic droit sur le nom du projet, suivre les menus Build Path puis Add
external archives et donner le chemin de l’archive java ImageJ/ij.jar.
La classe ImageProcessor possède les méthodes suivantes :
ä
ä
ä
ä
ä
getWidth() qui retourne la largeur de l’image ( x ∈ [0, getW idth()[ ).
getHeight() qui retourne la hauteur de l’image ( y ∈ [0, getHeight()[ ).
getPixel(x, y) qui retourne un entier correspondant à la valeur du pixel de coordonnées (x, y).
putPixel(x, y, val qui permet de donner une nouvelle valeur au pixel (x, y).
getPixels qui permet de récupérer toutes les valeurs de l’image dans un tableau mono-dimensionnel (tableau
de byte pour une image en niveaux de gris, tableau d’int pour une image couleur). En modifiant les valeurs
de ce tableau, on modifie directement l’image.
2/5
Question 4
Complétez le code ci-dessous pour colorier en blanc une ligne sur deux de l’image traitée. Testez.
1
2
3
import ij .*;
import ij . process .*;
import ij . plugin . filter .*;
4
5
public class Rayures_ implements PlugInFilter {
6
public void run ( ImageProcessor ip ) {
int w =
;
int h =
;
7
8
9
10
for ( int y
for ( int x
;
}
11
12
13
14
){
)
}
15
16
public int setup ( String arg , ImagePlus imp ) {
if ( arg . equals ( " about " ) ) {
IJ . showMessage ( " Rayures blanches " ) ;
return DONE ;
}
return DOES_8G ;
}
17
18
19
20
21
22
23
24
}
Question 5
Réécrivez le code de la classe Rayures_ en utilisant uniquement getPixels pour accéder aux valeurs de
l’image. Pourquoi peut-il être préférable de parcourir une image dans un tableau à une dimension plutôt qu’à
deux dimensions ?
Question 6
Ecrire un plugin permettant de binariser une image : l’intensité d’un pixel est mise à 0 si le niveau de gris de ce
pixel est inférieur à un seuil, à 255 sinon.
1.3
Travail sur les images couleur
Pour les images couleurs, les 3 composantes sont empaquetées dans le même entier.
1
2
3
4
5
int red = ( pixels [ i ] & 0 xff0000 ) > >16;
int green = ( pixels [ i ] & 0 x00ff00 ) > >8;
int blue = ( pixels [ i ] & 0 x0000ff ) ;
...
pixels [ i ] = ( red < <16) +( green < <8) + blue ;
Le code ci-dessous permet de créer une nouvelle image couleur de largeur w et de hauteur h.
1
2
ImagePlus new = NewImage . createRGBImage ( " nouvelle image " , w , h , 1 ,
NewImage . FILL_BLACK ) ;
ImageProcessor ipNew = copy . getProcessor () ;
Question 7
Complétez/Modifiez le code java suivant afin de mettre à 0 l’une des trois composantes (R G ou B)
3/5
public class S uppressi on_Rouge implements PlugInFilter {
1
2
public int setup ( String arg , ImagePlus imp ) {
if ( arg . equals ( " about " ) ) {
IJ . showMessage ( " Suppression du canal rouge " ) ;
return DONE ;
}
return DOES_RGB ;
}
3
4
5
6
7
8
9
10
public void run ( ImageProcessor ip ) {
int w = ip . getWidth () ;
int h = ip . getHeight () ;
ImagePlus res = NewImage . createRGBImage ( " Sans rouge " , w , h , 1 ,
NewImage . FILL_BLACK ) ;
ImageProcessor ipRes = res . getProcessor () ;
int [] pixels = ( int []) ip . getPixels () ;
int [] pixelsRes = ( int []) ipRes . getPixels () ;
for ( int i =0; i < w * h ; i ++) {
int r =
;
int g =
;
int b =
;
;
pixelsRes [ i ] =
;
}
res . show () ;
res . updateAndDraw () ;
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
}
28
29
}
Vous pouvez préférer accéder aux valeurs RGB d’un pixel par la méthode
int[] getPixel(int x, int y, int[] iArray)
qui remplit et retourne un tableau de 3 entiers avec les valeurs R, G et B du pixel de coordonnées (x, y).
1
2
int [] c = new int [3];
c = ip . getPixel (x , y , c ) ;
Réécrire le plugin précédent en utilisant cette méthode. Dans cette nouvelle version, c’est l’image ouverte qui sera
modifiée (pas de création d’une nouvelle image).
Question 8
On veut obtenir une version grisée d’une image couleur. Ecrire un plugin imageJ qui crée une image 8 bits en
niveaux de gris à partir de l’image couleur RGB ouverte par l’utilisateur. Le niveau de gris correspondant au pixel
(r, g, b) est 0.3r + 0.59g + 0.11b.
4/5
Question 9
On veut obtenir une version colorisée d’une image en niveaux de gris 8 bits. Pour choisir une couleur, on peut
utiliser la classe ColorChooser de la façon suivante :
1
2
3
4
5
6
ColorChooser cc = new ColorChooser ( ‘ ‘ couleur ’ ’ , Color . yellow , true ) ;
Color cRef = cc . getColor () ;
if ( cRef == null ) {
IJ . error ( ‘‘ PlugIn cancelled ’ ’ ) ;
return ;
}
Trouvez une solution pour garder la teinte de la couleur sélectionnée et la luminosité des niveaux de gris de
l’image initiale.
1.4
Calcul du PSNR
Question 10
Complétez le code suivant pour calculer le PSNR de deux images de même taille. Prenez comme image de
référence paysage.jpg et calculez le PSNR de cette image compressée à des taux différents. Concluez sur les
valeurs obtenues.
1
2
3
4
5
6
7
8
9
10
11
public void run ( ImageProcessor ip ) {
ImagePlus imgRef = new ImagePlus ( " chemin de l ’ image de reference " ) ;
ImageProcessor ipRef = imgRef . getProcessor () ;
double psnr = computePSNR ( ip , ipRef ) ;
}
double computePSNR ( ImageProcessor ip , ImageProcessor ipRef ) {
...
double psnr =...;
IJ . showMessage ( " PSNR = " + psnr ) ;
return psnr ;
}
Ce document est publié sous Licence Creative Commons « ByNonCommercial-ShareAlike ». Cette licence vous autorise une utilisation
libre de ce document pour un usage non commercial et à condition d’en
conserver la paternité. Toute version modifiée de ce document doit être placée sous la même licence pour pouvoir être diffusée.
http://creativecommons.org/licenses/by-nc-sa/2.0/fr/
5/5