Précédent   Forum du club des développeurs et IT Pro > Autres langages > Algorithmes > Contribuez
Contribuez Proposez vos articles, cours, tutoriels, FAQ, sources, etc.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 16/12/2009, 11h25   #1
ToTo13
Modérateur
 
Avatar de ToTo13
 
Homme Guillaume
Ingénieur de Recherche
Inscription : janvier 2006
Messages : 4 784
Détails du profil
Informations personnelles :
Nom : Homme Guillaume
Âge : 34
Localisation : Etats-Unis

Informations professionnelles :
Activité : Ingénieur de Recherche
Secteur : Santé

Informations forums :
Inscription : janvier 2006
Messages : 4 784
Points : 7 016
Points : 7 016
Par défaut [Image/Java] Gray Level Size Zone Matrix

Bonjour,

voilà deux classes qui permettent de calculer les Gray Level Size Zone Matrix (GLSZM) ainsi que les indices associés.
C'est une méthode statistique de description de la texture (au même titre que les Glcm et Glrlm), mais cette fois-ci basée sur la taille des zones.
Elle a été présentée pour la première fois dans :
Citation:
@conference{Thibault09,
Address = {Minsk, Belarus},
Author = {Guillaume Thibault and Bernard Fertil and Claire Navarro and Sandrine Pereira and Pierre Cau and Nicolas Levy and Jean Sequeira and Jean-Luc Mari},
Booktitle = {Pattern Recognition and Information Processing (PRIP)},
Keywords = {Texture features, Texture indexes, Classification, Cell Nuclei, Run length matrix (GLRLM), Size Zone Matrix (GLSZM), WND-CHARM, Homogeneous Texture},
Month = {May},
Pages = {140-145},
Title = {Texture Indexes and Gray Level Size Zone Matrix Application to Cell Nuclei Classification},
Year = {2009}}


Pour ceux qui souhaiteraient utiliser ce morceaux de code, je conseille :
- d'effacer le paramètre Leveling. C'est des méthodes de nivellement basées sur des algorithmes de morphologie mathématique. Donc effacer aussi l'appel de la class Gaussian qui effectue un filtre Gaussien.
- pour les classes de réduction des niveaux de gris, voir ici.
- de regarder cette contribution car elle décrit l'étiquetage des composantes connexes.


Code java :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
 
package rdf.textures.glzm.glszm;
 
import java.util.Iterator;
import java.util.List;
 
import imageTiTi.Image;
import imageTiTi.reducer.ColorReducer;
 
import mathematics.Maths;
import measures.cclh.ConnectedComponentLabeling;
import measures.cclh.FifoCcl;
import morphee.Levelings.Leveling;
 
import processing.filters.Gaussian;
 
import utils.arrays.ArraysOperations;
 
/**
 * <p>Description : Cette classe calcule la "Size Zone Matrix" pour une image (vignette).
 *  Il s'agit d'une creation de ma part.</p>
 * <p>Packages necessaires : dv, imageTiTi, mathematics, measures, morphee, processing, utils.</p>
 * <p>Copyright : Copyright (c) 2007.</p>
 * <p>Laboratoires/Equipes : CMM (Mines-ParisTech), I&M (ex LXAO) LSIS.</p>
 * <p>Dernieres modifications :<br>
 * 11 Avril 2010, 1.3 => Gestion de la reduction des tailles pour le stockage dans la matrice.<br>
 * <dd> => Possibilite de fixer la taille de la matrice ou de la laisser variable avec un pas.</dd><br>
 * <dd> => Simplification par l'utilisation de l'interface ColorReducer.</dd><br>
 * 26 Janvier 2010 => Modifications des methodes FindValues qui s'effectuent desormais en un seul passage.<br> 
 * 19 Janvier 2010 => Ajout de la methode "FillMatrix(DV, int, boolean)", pour le projet Loreal.<br>
 * 29 Decembre 2009, 1.2 => Correction d'un bug pour la gestion de la valeur interdite :
 *  ccl.Label("this."image, 0, EightConnex, null).<br>
 * <dd> => Ajout de la methode FillMatrix(Image, int, int) pour une generalisation dans GLZM.</dd><br>
 * <dd> => Ajout de la methode FillMatrix(List) pour une generalisation dans GLZM.</dd><br>
 * 27 Novembre 2009 => Correction d'un bug du a la gestion de la valeur interdite :
 *  Correspondances[i] = TrouverValeur(Carte, i)"-1" ;<br>
 * 18 Avril 2008, 1.1 => Ajout de l'affinage des niveaux de gris par KMeans.<br>
 * 10 Avril 2008 => Creation.</p>
 * 
 * @author Guillaume THIBAULT
 * @version 1.3
 * <p>
 * <!-- technical-bibtex-start -->
 * BibTeX:
 * <pre>
 * @conference{Galloway75,
 * 		address = {Minsk, Belarus},
 *		author = {Guillaume Thibault and Bernard Fertil and Claire Navarro and Sandrine Pereira and Pierre Cau
 *					and Nicolas Levy and Jean Sequeira and Jean-Luc Mari},
 *		booktitle = {Pattern Recognition and Information Processing (PRIP)},
 *		pages = {140--145},
 *		title = {{Texture Indexes and Gray Level Size Zone Matrix. Application to Cell Nuclei Classification},
 *		year = {2009}
 *		}
 * </pre>
 * <!-- technical-bibtex-end -->
 </p>
 */
 
public class GrayLevelSizeZoneMatrix
{
 
/** Hauteur de la size zone matrix <=> Le nombre de niveaux de gris.*/
protected int nbGrayLevel = -1 ;
/** Nombre de tailles de zones a prendre en compte. Si FixedSize=true ce sera la largeur de la matrice, sinon c'est le pas.*/
protected int nbSizes = -1 ;
/** Largeur de la matrice. Si FixedSize Alors Width=nbSizes, Sinon Width=TailleZoneMax/nbSizes+1.*/
protected int Width = -1 ;
/** La largeur doit elle etre fixe ? */
protected boolean FixedSize = false ;
/** Tableau representant la size zone matrix.*/
protected double[][] matrix = null ;
 
/** L'image sur laquelle on a calcule la matrice de taille de zones, donc apres reduction du nombre de niveaux de gris.*/
protected Image Reduced = null ;
 
/** Volume sur lequel on a calcule la matrice de taille de zones, donc apres reduction du nombre de niveaux de gris.*/
protected DV Reduced3D = null ;
 
/** Classe qui va permettre le calcul/etiquettage des composantes connexes.*/
private ConnectedComponentLabeling ccl = new FifoCcl() ;
/** Un filtre gaussien, utile pour construire le marqueur du leveling.*/
private Gaussian gauss = new Gaussian(1, 1) ;
 
 
 
 
/** Un constructeur qui permet de modifier la taille de la Size Zone Matrix.
 * @param nbGrayLevel Le nombre de niveaux de gris a prendre en compte, ce sera la hauteur de la matrice.
 * @param nbSizes Nombre de tailles de zones a prendre en compte.
 *  Si FixedSize=true ce sera la largeur de la matrice, sinon c'est le pas.
 * @param FixedSize La largeur doit elle etre fixe ? */
public GrayLevelSizeZoneMatrix(int nbGrayLevel, int nbSizes, boolean FixedSize)
	{
	if ( nbGrayLevel < 2 )
		throw new IllegalArgumentException("Number of gray level incorrect: " + nbGrayLevel + ", wish [2...2^N[") ;
 
	this.nbGrayLevel = nbGrayLevel ;
	this.nbSizes = nbSizes ;
	this.FixedSize = FixedSize ;
 
	if ( !Maths.isPowerOf(nbGrayLevel, 2)  )
		throw new IllegalArgumentException("Number of gray level must be a power of 2: " + nbGrayLevel) ;
 
	if ( FixedSize )
		{
		Width = nbSizes ;
		matrix = new double[nbGrayLevel][Width] ;
		}
	}
 
 
 
/** Methode qui lance et gere les differentes etapes de calcul.
 * @param image La vignette contenant la texture.
 * @param reducer Classe qui permet de reduire le nombre de couleurs.
 * @param leveling Methode de nivellement a utiliser avant la reduction des couleurs avec un filtre gaussien comme marqueur.
 *  Si ce parametre est null, alors rien n'est realise.
 * @param ForbidenValue Valeur interdite (du fond) =>
 *  Valeur a ne pas prendre en compte pour les calculs. Si strictement negative, on prend toutes les valeurs en consideration.
 * @param EightConnex Doit on travailler en huit connexite ?
 * @param nbCPU Nombre de CPU autorises dans cette classes => Nombre de threads autorises.*/
public void FillMatrix(Image image, ColorReducer reducer, Leveling leveling, int ForbidenValue, boolean EightConnex, int nbCPU)
	{
	if ( !image.isGrayLevel() ) throw new IllegalArgumentException("Only gray level images supported.") ;
	int i, width ;
	Reduced = null ;
 
	if ( leveling == null ) Reduced = reducer.Reduce(image, nbGrayLevel, ForbidenValue) ;
	else Reduced = reducer.Reduce(leveling.Filter(image, nbCPU, gauss.Filter(image, nbCPU)), nbGrayLevel, ForbidenValue) ;
 
	ccl.Label(Reduced, 0, EightConnex, null) ; // On calcule (étiquette) les composantes connexes.
	int[][] Labels = ccl.Labels() ;
	int[] Sizes = ccl.Sizes() ; // On récupère la dimension de chaque composante.
	int[] Correspondances = new int[Sizes.length] ;	
 
	FindValues(Labels, Correspondances) ; // Correspondance composante/niveau de gris. La case 0 = ForbidenValue
 
	width = 0 ;
	for (i=1 ; i < Sizes.length ; i++) // On trouve la taille de la plus grande zone.
		if ( Correspondances[i] >= 0 && width < Sizes[i] )
			width = Sizes[i] ;	
 
	if ( FixedSize )
		{
		ArraysOperations.SetConstant(matrix, 0.0) ; // Matrice déjà allouée, donc il suffit de la re-initialiser.
		for (i=1 ; i < Correspondances.length ; i++) // On remplit la matrice
			if ( Correspondances[i] >= 0 )
				matrix[Correspondances[i]][(int)((double)(Sizes[i]-1)/(double)width*(double)nbSizes)]++ ;
		}
	else
		{
		Width = width/nbSizes+1 ;
		matrix = null ;
		matrix = new double[nbGrayLevel][Width] ;
		for (i=1 ; i < Correspondances.length ; i++) // On remplit la matrice
			if ( Correspondances[i] >= 0 )
				matrix[Correspondances[i]][Sizes[i]/nbSizes]++ ;
		}
	}
 
 
 
/** Methode qui lance et gere les differentes etapes de calcul.
 * @param ImageReduced La vignette contenant la texture, dont les niveaux de gris ont prealablement ete reduit.
 * @param Ccl La classe permettant de realiser l'etiquettage des composantes connexes,
 *  mais sur laquelle les calculs ont DEJA ete realises.*/
public void FillMatrix(Image ImageReduced, ConnectedComponentLabeling Ccl)
	{
	if ( !ImageReduced.isGrayLevel() ) throw new IllegalArgumentException("Only gray level images supported.") ;
	int i, width ;
	int[][] Labels = Ccl.Labels() ;
	int[] Sizes = Ccl.Sizes() ;
	int[] Correspondances = new int[Sizes.length] ;
 
	FindValues(Labels, Correspondances) ; // Correspondance composante/niveau de gris. La case 0 = ForbidenValue
 
	width = 0 ;
	for (i=1 ; i < Sizes.length ; i++) // On trouve la taille max des composantes qui sera la largeur de la matrice.
		if ( Correspondances[i] >= 0 && width < Sizes[i] )
			width = Sizes[i] ;
 
	if ( FixedSize )
		{
		ArraysOperations.SetConstant(matrix, 0.0) ; // Matrice déjà allouée, donc il suffit de la re-initialiser.
		for (i=1 ; i < Correspondances.length ; i++) // On remplit la matrice
			if ( Correspondances[i] >= 0 )
				matrix[Correspondances[i]][(int)((double)(Sizes[i]-1)/(double)width*(double)nbSizes)]++ ;
		}
	else
		{
		Width = width/nbSizes+1 ;
		matrix = null ;
		matrix = new double[nbGrayLevel][Width] ;
		for (i=1 ; i < Correspondances.length ; i++) // On remplit la matrice
			if ( Correspondances[i] >= 0 )
				matrix[Correspondances[i]][Sizes[i]/nbSizes]++ ;
		}
	}
 
 
 
/** Methode qui realise les calculs.
 * @param list La liste contenant les images reduites.*/
public void FillMatrix(List<Image> list)
	{
	int i, x, y, Largeur, width, height, nb = 0 ;
	Image shape = null ;
	int[] Sizes = new int[list.size()] ;
	Iterator<Image> iter = list.iterator() ;
 
	Largeur = 0 ;
	while ( iter.hasNext() )
		{
		shape = iter.next() ;
		if ( !shape.isGrayLevel() ) throw new IllegalArgumentException("Only gray level image required.") ;
 
		width = shape.Width() ;
		height = shape.Height() ;
 
		Sizes[nb] = 0 ; // Initialisation de la taille.
		for (y=0 ; y < height ; y++)
			for (x=0 ; x < width ; x++)
				if ( shape.Pixel(y, x) > 0 ) Sizes[nb]++ ; // On compte les pixels de la zone.
 
		if ( Largeur < Sizes[nb] ) Largeur = Sizes[nb] ;
		shape = null ;
		nb++ ;
		}
 
	if ( FixedSize )
		{
		ArraysOperations.SetConstant(matrix, 0.0) ; // Matrice déjà allouée, donc il suffit de la re-initialiser.
		for (i=1 ; i < nb ; i++) // On remplit la matrice
			matrix[FindColor(list.get(i))-1][(int)((double)(Sizes[i]-1)/(double)Largeur*(double)nbSizes)]++ ;
		}
	else
		{
		Width = Largeur/nbSizes + 1 ;
		matrix = null ;
		matrix = new double[nbGrayLevel][Width] ;
		for (i=0 ; i < nb ; i++) // On remplit la matrice
			matrix[FindColor(list.get(i))-1][Sizes[i]/nbSizes]++ ;
		}
	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/** Methode qui permet de trouver la couleur de la vignette, car elle est codee avec des 0 et une autre couleur.
 * @param image L'image dont on souhaite trouver la couleur.
 * @return La valeur de la couleur trouvee.*/
private int FindColor(Image image)
	{
	for (int y=0 ; y < image.Height() ; y++)
		for (int x=0 ; x < image.Width() ; x++)
			if ( image.Pixel(y, x) > 0 )
				return image.Pixel(y, x) ;
	throw new Error("Color not found. This error must not occured.") ;
	}
 
 
 
 
/** Une methode qui trouve la correspondance entre les composantes connexes et les niveaux de gris
 *  => Affecte la couleur reduite a chaque composante.
 * @param Labels La carte des composantes.
 * @param Correspondances Le tableau des correspondances, celui que l'on doit remplir.*/
private void FindValues(int[][] Labels, int[] Correspondances)
	{
	int hauteur = Labels.length ;
	int largeur = Labels[0].length ;
	for (int y=0 ; y < hauteur ; y++)
		for (int x=0 ; x < largeur ; x++)
			if ( Labels[y][x] > 0 )
				Correspondances[Labels[y][x]] = Reduced.Pixel(y, x) - 1 ;
	}
 
 
/** Une methode qui trouve la correspondance entre les composantes connexes et les niveaux de gris
 *  => Affecte la couleur reduite a chaque composante.
 * @param Labels La carte des composantes.
 * @param Correspondances Le tableau des correspondances, celui que l'on doit remplir.*/
private void FindValues(int[][][] Labels, int[] Correspondances)
	{
	int depth = Labels.length ;
	int height = Labels[0].length ;
	int width = Labels[0][0].length ;
	for (int z=0 ; z < depth ; z++)
		for (int y=0 ; y < height ; y++)
			for (int x=0 ; x < width ; x++)
				if ( Labels[z][y][x] > 0 )
					Correspondances[Labels[z][y][x]] = Reduced3D.Voxel(z, y, x) - 1 ;
	}
 
 
 
 
 
 
 
 
 
 
 
 
 
/* ----------------------------------------------------- Les getters ----------------------------------------------------- */
/** Methode qui retourne la matrice de taille de zone.
 * @return La 'Size Zone Matrix'.*/
public double[][] getMatrix()
	{
	return matrix ;
	}
 
 
public String toString()
	{
	StringBuffer sb = new StringBuffer() ;
	for (int j=0 ; j < nbGrayLevel ; j++)
		{
		for (int i=0 ; i < nbSizes ; i++) sb.append(matrix[j][i] + " ") ;
		sb.append("\n") ;
		}
	return sb.toString() ;
	}
 
}
__________________
Consignes aux jeunes padawans : une image vaut 1000 mots !
- Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe correcteur orthographique pour FiReFox), mettre les ACCENTS et les BALISES => ECRIRE clairement et en Français tu DOIS.
- Le coté obscur je sens dans le MP => Tous tes MP je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
- ton poste tu dois marquer quand la bonne réponse tu as obtenu.
ToTo13 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/12/2009, 11h27   #2
ToTo13
Modérateur
 
Avatar de ToTo13
 
Homme Guillaume
Ingénieur de Recherche
Inscription : janvier 2006
Messages : 4 784
Détails du profil
Informations personnelles :
Nom : Homme Guillaume
Âge : 34
Localisation : Etats-Unis

Informations professionnelles :
Activité : Ingénieur de Recherche
Secteur : Santé

Informations forums :
Inscription : janvier 2006
Messages : 4 784
Points : 7 016
Points : 7 016
Et la classe calculant les indices : ce sont principalement des moments d'ordre -2 à 2 et des variances.

Code java :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
 
package rdf.textures.glzm.glszm;
 
import rdf.Features;
 
import imageTiTi.Image;
import imageTiTi.reducer.ColorReducer;
 
import measures.cclh.ConnectedComponentLabeling;
import morphee.Levelings.Leveling;
 
/**
 * <p>Description : Cette classe calcule les caracteristiques de la "Size Zone Matrix"
 *  (une petite creation de ma part) pour une image (vignette).<br>
 * Liste des caracteristiques calculees (ce sont celles de la Run Length Matrix).
 *  Ce sont principalement des moments (ordres -2 a 2) et des variances.<br>
 *  - F0 => Small Zone Emphasis, SZE.<br>
 *  - F1 => Large Zone Emphasis, LZE.<br>
 *  - F2 => Low Gray level Zone Emphasis, LGZE.<br>
 *  - F3 => High Gray level Zone Emphasis, HGZE.<br>
 *  - F4 => Small Zone Low Gray level Emphasis, SZLGE.<br>
 *  - F5 => Small Zone High Gray level Emphasis, SZHGE.<br>
 *  - F6 => Large Zone Low Gray level Emphasis, LZLGE.<br>
 *  - F7 => Large Zone High Gray Level Emphasis, LZHGE.<br>
 *  - F8 => Gray Level Non Uniformity, GLNU.<br>
 *  - F9 => Size Zone Non Uniformity, SZNU.<br>
 *  - F10 => Zone Percentage, ZPC.<br>
 *  - F11 => Barycentre sur les niveaux de gris.<br>
 *  - F12 => Barycentre sur les tailles de zones.<br>
 *  - F13 => Variance ponderee sur les niveaux de gris.<br>
 *  - F14 => Variance ponderee sur tailles des zones.<br>
 *  - F15 => Orientation.<br>
 * </p>
 * <p>Packages necessaires : imageTiTi.</p>
 * <p>Copyright : Copyright (c) 2007.</p>
 * <p>Laboratoires/Equipes : CMM (Mines-ParisTech / ENSMP), I&M (ex LXAO) LSIS.</p>
 * <p>Dernieres modifications :<br>
 * 20 Avril 2010 => Ajout des indices F13 a F15 et correction/traduction des noms.<br>
 * 07 Fevrier 2010 => Suppression des caracteristiques Haralick.<br>
 * 21 Janvier 2010 => Ajout de la methode "Compute(DV, int, boolean) pour effectuer le calcul sur des volumes.<br>
 * 19 Novembre 2009 => Ajout de la methode ComputeFromStack qui permet de faire les calculs sur une pile d'images
 *  (projet Loreal, CMM/ENSMP).<br>
 * 10 Avril 2008 => Creation.</p>
 * 
 * @author Guillaume THIBAULT
 * @version 1.0
 */
 
public class GlszmFeatures extends GrayLevelSizeZoneMatrix implements Features
{
 
/** Tableau qui contient toutes les caracteristiques.*/
private double[] Features = new double[16] ;
/** Variable egale a la somme de tous les elements de la matrice.*/
private double Sum = 0.0 ;
 
/** Tableau contenant les noms des caracteristiques qui sont calculees.*/
private String[] FeaturesNames = new String[]{"SZE", "LZE", "LGZE", "HGZE", "SZLGE", "SZHGE", "LZLGE", "LZHGE",
											"GLNU", "SZNU", "ZPC", "BARYGL", "BARYS", "VARGL", "VARS", "ORIE"} ;
 
 
 
 
 
/** Un constructeur qui permet de modifier la taille de la size zone matrix.
 * @param nbGrayLevel Le nombre de niveaux de gris a prendre en compte, ce sera la hauteur de la matrice.
 * @param nbSizes Nombre de tailles de zones a prendre en compte.
 *  Si FixedSize=true ce sera la largeur de la matrice, sinon c'est le pas.
 * @param FixedSize La largeur doit elle etre fixe ? */
public GlszmFeatures(int nbGrayLevel, int nbSizes, boolean FixedSize)
	{
	super(nbGrayLevel, nbSizes, FixedSize) ;
	}
 
 
 
 
 
/** Methode qui lance et gere les differentes etapes de calcul. Inutile d'appeler la methode "FillMatrix".
 * @param image L'image a caracteriser
 * @param reducer Classe qui permet de reduire le nombre de couleurs.
 * @param leveling Methode de nivellement a utiliser avant la reduction des couleurs avec un filtre gaussien comme marqueur.
 *  Si ce parametre est null, alors rien n'est realise.
 * @param ForbidenValue La valeur a exclure lors de calculs. Mettre -1 si toute la texture est a caracteriser.
 * @param EightConnex Travaille t-on en 8-connexite ?
 * @param nbCPU Nombre de CPU autorises dans cette classes => Nombre de threads autorises.*/
public void Compute(Image image, ColorReducer reducer, Leveling leveling, int ForbidenValue, boolean EightConnex, int nbCPU)
	{
	if ( !image.isGrayLevel() ) throw new IllegalArgumentException("Only gray level images supported.") ;
 
	FillMatrix(image, reducer, leveling, ForbidenValue, EightConnex, nbCPU) ; // On remplit la matrice :)
 
	ComputeFeatures() ;
	}
 
 
 
/** Methode qui lance et gere les differentes etapes de calcul.
 * @param ImageReduced La vignette contenant la texture, dont les niveaux de gris ont prealablement ete reduit.
 * @param Ccl La classe permettant de realiser l'etiquettage des composantes connexes,
 *  mais sur laquelle les calculs ont DEJA ete realises.*/
public void Compute(Image ImageReduced, ConnectedComponentLabeling Ccl)
	{
	if ( !ImageReduced.isGrayLevel() ) throw new IllegalArgumentException("Only gray level images supported.") ;
 
	FillMatrix(ImageReduced, Ccl) ; // On remplit la matrice :)
 
	ComputeFeatures() ;
	}
 
 
 
/** Methode qui gere le calcul des indices de texture.*/
private void ComputeFeatures()
	{
	Sum = 0.0 ;
	for (int y=0 ; y < nbGrayLevel ; y++)
		for (int x=0 ; x < Width ; x++)
			Sum += matrix[y][x] ;
 
	Features[0] = SZE() ;
	Features[1] = LZE() ;
	Features[2] = LGZE() ;
	Features[3] = HGZE() ;
	Features[4] = SZLGE() ;
	Features[5] = SZHGE() ;
	Features[6] = LZLGE() ;
	Features[7] = LZHGE() ;
	Features[8] = GLNU() ;
	Features[9] = SZNU() ;
	Features[10] = ZPC() ;
	Features[11] = BARYGL() ;
	Features[12] = BARYS() ;
	Features[13] = VARGL(Features[11]) ;
	Features[14] = VARS(Features[12]) ;
	Features[15] = ORIE(Features[11], Features[12]) ;
	}
 
 
 
 
 
/** Methode qui lance et gere les differentes etapes de calcul pour un tas (pile) d'images.
 * @param images Les vignettes (images) contenant les texture a caracteriser.
 * @param reducer Classe qui permet de reduire le nombre de couleurs.
 * @param leveling Methode de nivellement a utiliser avant la reduction des couleurs avec un filtre gaussien comme marqueur.
 *  Si ce parametre est null, alors rien n'est realise.
 * @param ForbidenValue La valeur a exclure lors de calculs. Mettre -1 si toute la texture est a caracteriser.
 * @param EightConnex Est ce que l'on doit realiser l'etiquettage en 8-connexite ?
 * @param nbCPU Nombre de CPU autorises dans cette classes => Nombre de threads autorises.*/
public void ComputeFromStack(Image[] images, ColorReducer reducer, Leveling leveling, int ForbidenValue,
											boolean EightConnex, int nbCPU)
	{
	int i, j ;
	int[] nbNanF1 = new int[Features.length] ;
	double[] F1 = new double[Features.length] ; // Tableaux temporaires contenant la somme des caractéristiques.
 
	for (i=0 ; i < images.length ; i++)
		{
		Compute(images[i], reducer, leveling, ForbidenValue, EightConnex, nbCPU) ; // On calcule les caractéristiques .
 
		for (j=0 ; j < F1.length ; j++)
			if ( Double.isNaN(Features[j])) nbNanF1[j]++ ; // On compte le nombre de Nan pour ajuster les calculs.
			else F1[j] += Features[j] ; // On sauvegarde les résultats.
		}
 
	for (j=0 ; j < F1.length ; j++) Features[j] = F1[j] / (double)(images.length-nbNanF1[j]) ;
	F1 = null ;
	nbNanF1 = null ;
	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/* -------------------------------------------- Calcul des caractéristiques -------------------------------------------- */
/** F0 - Small Zone Emphasis, SZE. Petites zones.
 * @return SZE.*/
private double SZE()
	{
	double val = 0.0 ;
	for (int n=0 ; n < nbGrayLevel ; n++)
		for (int s=0 ; s < Width ; s++)
			val += matrix[n][s] / Math.pow(s+1, 2.0) ;
	return val / Sum ;
	}
 
/** F1 - Large Zone Emphasis, LZE. Grande zone.
 * @return LZE.*/
private double LZE()
	{
	double val = 0.0 ;
	for (int n=0 ; n < nbGrayLevel ; n++)
		for (int s=0 ; s < Width ; s++)
			val += matrix[n][s] * Math.pow(s+1, 2.0) ;
	return val / Sum ;
	}
 
/** F2 - Low Gray level Zone Emphasis, LGZE.
 * @return LGZE.*/
private double LGZE()
	{
	double val = 0.0 ;
	for (int n=0 ; n < nbGrayLevel ; n++)
		for (int s=0 ; s < Width ; s++)
			val += matrix[n][s] / Math.pow(n+1, 2.0) ;
	return val / Sum ;
	}
 
/** F3 - High Gray level Zone Emphasis, HGZE.
 * @return HGZE.*/
private double HGZE()
	{
	double val = 0.0 ;
	for (int n=0 ; n < nbGrayLevel ; n++)
		for (int s=0 ; s < Width ; s++)
			val += matrix[n][s] * Math.pow(n+1, 2.0) ;
	return val / Sum ;
	}
 
/** F4 - Small Zone Low Gray level Emphasis, SZLGE.
 * @return SZLGE.*/
private double SZLGE()
	{
	double val = 0.0 ;
	for (int n=0 ; n < nbGrayLevel ; n++)
		for (int s=0 ; s < Width ; s++)
			val += matrix[n][s] / (Math.pow(n+1, 2.0) * Math.pow(s+1, 2.0)) ;
	return val / Sum ;
	}
 
/** F5 - Small Zone High Gray level Emphasis, SZHGE.
 * @return SZHGE.*/
private double SZHGE()
	{
	double val = 0.0 ;
	for (int n=0 ; n < nbGrayLevel ; n++)
		for (int s=0 ; s < Width ; s++)
			val += matrix[n][s] * Math.pow((double)(n+1)/(double)(s+1), 2.0) ;
	return val / Sum ;
	}
 
/** F6 - Large Zone Low Gray level Emphasis, LZLGE.
 * @return LSLGLE.*/
private double LZLGE()
	{
	double val = 0.0 ;
	for (int n=0 ; n < nbGrayLevel ; n++)
		for (int s=0 ; s < Width ; s++)
			val += matrix[n][s] * Math.pow((double)(s+1)/(double)(n+1), 2.0) ;
	return val / Sum ;
	}
 
/** F7 - Large Zone High Gray level Emphasis, LZHGE.
 * @return LZHGE.*/
private double LZHGE()
	{
	double val = 0.0 ;
	for (int n=0 ; n < nbGrayLevel ; n++)
		for (int s=0 ; s < Width ; s++)
			val += matrix[n][s] * Math.pow(n+1, 2.0) * Math.pow(s+1, 2.0) ;
	return val / Sum ;
	}
 
/** F8 - Gray Level Non Uniform, GLNU. Homogeneite spectrale.
 * @return GLNU.*/
private double GLNU()
	{
	double v, val = 0.0 ;
	for (int n=0 ; n < nbGrayLevel ; n++)
		{
		v = 0.0 ;
		for (int s=0 ; s < Width ; s++)
			v += matrix[n][s] ;
		val += v*v ;
		}
	return val / Sum ;
	}
 
/** F9 - Size Zone Non Uniform, SZNU. Uniformite.
 * @return SZNU.*/
private double SZNU()
	{
	double v, val = 0.0 ;
	for (int s=0 ; s < Width ; s++)
		{
		v = 0.0 ;
		for (int n=0 ; n < nbGrayLevel ; n++)
			v += matrix[n][s] ;
		val += v*v ;
		}
	return val / Sum ;
	}
 
/** F10 - Zone Percentage, ZPC. Egalite des isotailles (pourcentage primitives).
 * @return ZPC.*/
private double ZPC()
	{
	double val = 0.0 ;
	for (int n=0 ; n < nbGrayLevel ; n++)
		for (int s=0 ; s < Width ; s++)
			val += (double)(s+1) * matrix[n][s] ;
	return Sum / val ;
	}
 
/** F11 - Methode qui calcule le barycentre sur les niveaux de gris.
 * @return Le barycentre sur les niveaux de gris.*/
private double BARYGL()
	{
	double mean = 0.0 ;
	for (int n=0 ; n < nbGrayLevel ; n++)
		for (int s=0 ; s < Width ; s++)
			mean += (double)(n+1) * matrix[n][s] ;
	return mean / Sum ;
	}
 
/** F12 - Methode qui calcule le barycentre sur les tailles.
 * @return Le barycentre sur les tailles.*/
private double BARYS()
	{
	double mean = 0.0 ;
	for (int n=0 ; n < nbGrayLevel ; n++)
		for (int s=0 ; s < Width ; s++)
			mean += (double)(s+1) * matrix[n][s] ;
	return mean / Sum ; 
	}
 
/** F13 - Methode qui calcule la variance sur les niveaux de gris.
 * @param mean Moyenne sur les niveaux de gris.
 * @return La variance sur les niveaux de gris.*/
private double VARGL(double mean)
	{
	double val = 0.0 ;
	for (int n=0 ; n < nbGrayLevel ; n++)
		for (int s=0 ; s < Width ; s++)
			val += Math.pow((double)(n+1) * matrix[n][s] - mean, 2.0) ;
	return Math.sqrt(val / Sum) ;
	}
 
/** F14 - FMethode qui calcule la variance sur les tailles.
 * @param mean Moyenne sur les tailles des zones.
 * @return La variance sur les tailles.*/
private double VARS(double mean)
	{
	double val = 0.0 ;
	for (int n=0 ; n < nbGrayLevel ; n++)
		for (int s=0 ; s < Width ; s++)
			val += Math.pow((double)(s+1) * matrix[n][s] - mean, 2.0) ;
	return Math.sqrt(val / Sum) ;
	}
 
/** F15 - Methode qui calcule l'orientation des valeurs non nulles de la matrice.
 * @param bgl Barycentre sur les niveaux de gris.
 * @param bs Barycentre sur les tailles.
 * @return L'orientation comprise sur [-Pi/2, Pi/2].*/
private double ORIE(double bgl, double bs)
	{
	double a, b, c, m ;
	double m11 = 0.0, m02 = 0.0, m20 = 0.0 ;
 
	for (int n=0 ; n < nbGrayLevel ; n++)
		for (int s=0 ; s < Width ; s++)
			{
			m = matrix[n][s] ;
			m11 += (double)(n+1) * (double)(s+1) * m ;
			m02 = Math.pow(n+1, 2.0) * m ;
			m20 = Math.pow(s+1, 2.0) * m ;
			}
 
	a = m20/Sum - bs*bs ;
	b = 2.0 * (m11/Sum - bgl*bs) ;
	c = m02/Sum - bgl*bgl ;
	return Math.atan(b/(a-c))/2.0 ;
	}
 
 
 
 
 
 
 
 
 
 
 
 
/* ---------------------------------------------------- Les getters ---------------------------------------------------- */
/** Methode qui retourne la liste des caracteristiques.
 * @return Le tableau de double contenant les caracteristiques.*/
public double[] Feature()
	{
	return Features ;
	}
 
/** Methode qui retourne une des caracteristiques.
 * @return La valeur de type double de la caracteristiques.*/
public double Feature(int i)
	{
	return Features[i] ;
	}
 
/** Methode qui renvoit un tableau contenant les noms des caracteristiques.
 * @return Le tableau de string contenant les noms.*/
public String[] FeaturesNames()
	{
	return FeaturesNames ;
	}
 
}



Voici maintenant un petit exemple d'utilisation :
Code java :
1
2
3
4
 
GlszmFeatures glszm = new GlszmFeatures(32, 5, false) ; // On spécifie le nombre de niveaux de gris a utiliser lors de l'instanciation, le pas de discrétisation des tailles et si la matrice doit avoir une taille fixe.
glszm.Compute(image, new GrayLevelReducer(), null, 0, true, nbCPU) ;
double[] results = glszm.getFeatures() ;
__________________
Consignes aux jeunes padawans : une image vaut 1000 mots !
- Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe correcteur orthographique pour FiReFox), mettre les ACCENTS et les BALISES => ECRIRE clairement et en Français tu DOIS.
- Le coté obscur je sens dans le MP => Tous tes MP je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
- ton poste tu dois marquer quand la bonne réponse tu as obtenu.
ToTo13 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/04/2010, 16h42   #3
Fiorenzo
Invité régulier
 
Inscription : mai 2008
Messages : 18
Détails du profil
Informations forums :
Inscription : mai 2008
Messages : 18
Points : 8
Points : 8
Bonjour,

merci d'avoir présenté les Gray Level Size Zone Matrix qui m'ont données de très bon résultats. Jusque là je n'avais pas regardé ton code puisque je travaille sur des images 3D et en langage C mais aujourd'hui je regardé ça d'un peu plus près et du coup j'ai une question (sans doute très bête). Pourquoi les Haralick's features sont intégrés dans ce code? Tu les calcules à partir des GLSZM?
Fiorenzo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/04/2010, 14h20   #4
ToTo13
Modérateur
 
Avatar de ToTo13
 
Homme Guillaume
Ingénieur de Recherche
Inscription : janvier 2006
Messages : 4 784
Détails du profil
Informations personnelles :
Nom : Homme Guillaume
Âge : 34
Localisation : Etats-Unis

Informations professionnelles :
Activité : Ingénieur de Recherche
Secteur : Santé

Informations forums :
Inscription : janvier 2006
Messages : 4 784
Points : 7 016
Points : 7 016
Bonjour,

oui, j'ai essayé de les calculer dessus, mais les résultats ont toujours été décevant.
Je travaille actuellement sur une nouvelle version des GLSZM et je la posterai sans doute bientôt.

Par curiosité, sur quelles images appliques tu cette méthode et que souhaites tu caractériser ?
__________________
Consignes aux jeunes padawans : une image vaut 1000 mots !
- Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe correcteur orthographique pour FiReFox), mettre les ACCENTS et les BALISES => ECRIRE clairement et en Français tu DOIS.
- Le coté obscur je sens dans le MP => Tous tes MP je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
- ton poste tu dois marquer quand la bonne réponse tu as obtenu.
ToTo13 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/04/2010, 17h20   #5
Fiorenzo
Invité régulier
 
Inscription : mai 2008
Messages : 18
Détails du profil
Informations forums :
Inscription : mai 2008
Messages : 18
Points : 8
Points : 8
Merci pour ta réponse. J'avais donc bien compris ton code.

Pour ma part, je travaille sur des images PET (positron emission tomography) et (sans rentrer dans les détails sur le forum) j'utilise les textures pour caractériser des tumeurs.

Quand tu dis une nouvelle version des GLSZM tu sous-entends une nouvelle implémentation, de nouvelles features extraites de ces matrices ou une nouvelle manière de définir les zones?
Fiorenzo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/04/2010, 00h42   #6
ToTo13
Modérateur
 
Avatar de ToTo13
 
Homme Guillaume
Ingénieur de Recherche
Inscription : janvier 2006
Messages : 4 784
Détails du profil
Informations personnelles :
Nom : Homme Guillaume
Âge : 34
Localisation : Etats-Unis

Informations professionnelles :
Activité : Ingénieur de Recherche
Secteur : Santé

Informations forums :
Inscription : janvier 2006
Messages : 4 784
Points : 7 016
Points : 7 016
Citation:
Envoyé par Fiorenzo Voir le message
Pour ma part, je travaille sur des images PET (positron emission tomography) et (sans rentrer dans les détails sur le forum) j'utilise les textures pour caractériser des tumeurs.
Mmm... ça m'intéresse. Est ce que tu as des liens sur ton travail ?
Je suis très friand de tout ce qui est caractérisation et/ou classement sur des images médicales.
Surtout par l'utilisation des matrices statistiques et encore d'avantage si c'est moi qui les ait créées ;-)
Il est d'ailleurs question d'utiliser ces matrices (Glszm) pour des mélanomes, donc tumeurs de la peau. Elles sont particulièrement efficaces pour tout ce qui est homogénéité/hétérogénéité.


Citation:
Envoyé par Fiorenzo Voir le message
Quand tu dis une nouvelle version des GLSZM tu sous-entends une nouvelle implémentation, de nouvelles features extraites de ces matrices ou une nouvelle manière de définir les zones?
Ben... un peu tout ça
Je travaille dessus avec mon directeur actuel et je suis en train de finir l'implémentation.
Je fais une mise à jour au maximum en milieu de semaine prochaine... mais si je suis en retard, n'hésite pas à me rappeler à l'ordre.
__________________
Consignes aux jeunes padawans : une image vaut 1000 mots !
- Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe correcteur orthographique pour FiReFox), mettre les ACCENTS et les BALISES => ECRIRE clairement et en Français tu DOIS.
- Le coté obscur je sens dans le MP => Tous tes MP je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
- ton poste tu dois marquer quand la bonne réponse tu as obtenu.
ToTo13 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/04/2010, 16h49   #7
Fiorenzo
Invité régulier
 
Inscription : mai 2008
Messages : 18
Détails du profil
Informations forums :
Inscription : mai 2008
Messages : 18
Points : 8
Points : 8
Je ne vais pas pouvoir te donner beaucoup de liens sur mon travail vu que l'approche est relativement nouvelle mais voila quand même la référence d'un article sur une étude assez similaire à la notre:
Citation:
I. El Naqa, P. Grigsby, A. Apte, E. Kidd, E. Donnelly, D. Khullar, S. Chaudhari, D. Yang, M. Schmitt, R. Laforest, W. Thorstad, et J. Deasy, “Exploring feature-based approaches in PET images for predicting cancer treatment outcomes,” Pattern Recognition, vol. 42, Juin. 2009, p. 1162-1171.
Ça devrait déjà te donner une idée.

J'ai hâte de voir ta nouvelle version des GLSZM
Fiorenzo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/04/2010, 10h38   #8
ToTo13
Modérateur
 
Avatar de ToTo13
 
Homme Guillaume
Ingénieur de Recherche
Inscription : janvier 2006
Messages : 4 784
Détails du profil
Informations personnelles :
Nom : Homme Guillaume
Âge : 34
Localisation : Etats-Unis

Informations professionnelles :
Activité : Ingénieur de Recherche
Secteur : Santé

Informations forums :
Inscription : janvier 2006
Messages : 4 784
Points : 7 016
Points : 7 016
Par défaut Nouvelle version 1.3

Voilà, la nouvelle version est en ligne.
Alors pour les changements, c'est marqué dans les commentaires en début de classe, mais voici un petite résumé :
- possibilité de discrétiser aussi les tailles des zones. Avant on travailler directement sur les tailles, donc les variations entre matrices étaient énormes.
- possibilité d'avoir une matrice de largeur variable ou non. Je pense que fixer la taille n'apporte pas d'avantage dans la majorité des cas. Nous sommes en train de faire des tests et je donnerai les résultats dès que je les ai.
- utilisation de l'interface ColorReducer, cela permet de s'abstraire un peu.
- utilisation de l'interface Leveling pour réduire un peu le bruit avant utilisation. Tests en cours pour modéliser l'apport de cette méthode.
- optimisation du code et suppression de quelques bug mineurs.
- ajout de trois nouveaux indices.
- suppression des indices utilisaient sur les matrices de cooccurrences, car les résultats ont toujours étaient décevants.
__________________
Consignes aux jeunes padawans : une image vaut 1000 mots !
- Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe correcteur orthographique pour FiReFox), mettre les ACCENTS et les BALISES => ECRIRE clairement et en Français tu DOIS.
- Le coté obscur je sens dans le MP => Tous tes MP je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
- ton poste tu dois marquer quand la bonne réponse tu as obtenu.
ToTo13 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/05/2012, 01h42   #9
ToTo13
Modérateur
 
Avatar de ToTo13
 
Homme Guillaume
Ingénieur de Recherche
Inscription : janvier 2006
Messages : 4 784
Détails du profil
Informations personnelles :
Nom : Homme Guillaume
Âge : 34
Localisation : Etats-Unis

Informations professionnelles :
Activité : Ingénieur de Recherche
Secteur : Santé

Informations forums :
Inscription : janvier 2006
Messages : 4 784
Points : 7 016
Points : 7 016
Bonjour,

voici deux liens vers quelques explications, améliorations, des codes sources en java et autres exemples :
- Gray Level Size Zone Matrix.
- Multiple Gray Level Size Zone Matrix.
__________________
Consignes aux jeunes padawans : une image vaut 1000 mots !
- Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe correcteur orthographique pour FiReFox), mettre les ACCENTS et les BALISES => ECRIRE clairement et en Français tu DOIS.
- Le coté obscur je sens dans le MP => Tous tes MP je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
- ton poste tu dois marquer quand la bonne réponse tu as obtenu.
ToTo13 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 13h25.


 
 
 
 
Partenaires

Hébergement Web