Bonjour,
voilà une classe qui permet de calculer la "Run Length Matrix".
Code java : Sélectionner tout - Visualiser dans une fenêtre à part
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 package rdf.textures.glrlm; import imagetiti.Image; /** * <p>Description : Cette classe calcule la "run length matrix" pour une image (vignette). Elle peut etre calculee dans plusieurs directions, mais dans ce * dernier cas, une moyenne des differentes matrices sera faite.<br> * Inspire des articles suivants :<br> * - M. M. Galloway, Texture analysis using grey level run lengths. In 1975 in Computer Graphics Image Process, volume 4, pages 1971-1975.<br> * - A. Chu and C. M. Sehgal and J. F. Greenleaf, Use of gray value distribution of run lengths for texture analysis. In 1990 in Pattern Recognition Letters, * volume 11, number 6, pages 415-420.<br> * - K. Yogesan and T. Jørgensen and F. Albregtsen and K. J. Tveter and H. E. Danielsen, Entropy based texture analysis of chromatin structure in advanced * prostate cancer. In 1996 in Cytometry, volume 24, pages 268-276.<br> * - S. A. Karkanis and George D. Magoulas and Maria Grigoriadou and Dimitris A. Karras, Neural Network based textural labeling of images in multimedia * applications. In 1999 in EUROMICRO, volume 2, pages 392-396.<br> * - D.-H. Xu and A.S. Kurani and J.D. Furst and D.S. Raicu, Run-Length Encoding For Volumetric Texture. In 2004 in International Conference on Visualization, * Imaging, and Image Processing (VIIP), pages 452-458.<br></p> * <p>Packages necessaires : imagetiti.</p> * <p>Copyright : Copyright (c) 2007.</p> * <p>Laboratoire : LSIS.</p> * <p>Equipe : Image et Modele, I&M (ex LXAO).</p> * <p>Dernieres modifications :<br> * 8 Avril 2008 => Creation.</p> * * @author Guillaume THIBAULT * @version 1.0 */ public class GreyLevelRunLengthMatrix { /** Hauteur de la run length matrix.*/ protected int nbNiveauxGris = 32 ; /** Largeur de la run length matrix.*/ protected int largeur = 0 ; /** Tableau representant la run length matrix.*/ protected double[][] matrix = null ; /** Tableau representant la run length matrix ajustee (a la taille de la chaine la plus longue).*/ protected double[][] matriceajustee = null ; // Les directions de calculs. /** La variation en X pour le calcul de la matrice.*/ protected int[] dx = new int[] {1, 1, 0,-1} ; /** La variation en Y pour le calcul de la matrice.*/ protected int[] dy = new int[] {0, 1, 1, 1} ; /** L'image (la vignette) sur laquelle on a calcule la matrice de cooccurrences.*/ protected Image image = null ; // image source /** Un constructeur vide.*/ public GreyLevelRunLengthMatrix() { } /** Un constructeur qui permet de modifier la taille de la run length matrix. * @param nbNiveauxGris Le nombre de niveaux de gris a prendre en compte, ce sera la hauteur de la matrice.*/ public GreyLevelRunLengthMatrix(int nbNiveauxGris) { if ( nbNiveauxGris < 2 || nbNiveauxGris > 256 ) throw new Error("Parametre nbNiveauxGris incorrect : " + nbNiveauxGris + ", attendu [2..256]") ; this.nbNiveauxGris = nbNiveauxGris ; while ( nbNiveauxGris > 1 ) // On vérifie que nbNiveauxGris est une puissance de deux. { if ( nbNiveauxGris % 2 != 0 ) throw new Error("Parametre nbNiveauxGris doit être une puissance de deux : " + nbNiveauxGris) ; nbNiveauxGris /= 2 ; } } /** Methode qui affecte la direction de calcul. * @param DX Deplacement en X. * @param DY Deplacement en Y.*/ public void setDirection(int DX, int DY) { int x = DX ; int y = DY ; if ( x < 0 ) x = -x ; if ( y < 0 ) y = -y ; if ( x > 1 || y > 1 ) throw new Error("Variation de direction trop importante. Attendu [-1..1].") ; if ( x + y == 0 ) throw new Error("Direction nulle : x = y = 0.") ; dx = null ; dy = null ; dx = new int[]{DX} ; dy = new int[]{DY} ; } /** Methode qui affecte le nouveau tableau de direction. Si le tableau a une taille superieure a 1, une moyenne sera faite. * @param dx Nouveau tableau de variation en X. * @param dy Nouveau tableau de variation en Y.*/ public void setDirection(int[] dx, int[] dy) { if ( dx == null || dy == null ) throw new Error("Un des tableau est null.") ; if ( dx.length != dy.length ) throw new Error("Tailles des deux tableaux différentes : " + dx.length + " & " + dy.length) ; this.dx = null ; this.dy = null ; this.dx = dx ; this.dy = dy ; } /** Methode qui lance et gere les differentes etapes de calcul.*/ public void Calculer(Image image) { if ( image == null ) throw new Error("Paramètre image == null") ; this.image = image ; int x, y, i ; int max = 0 ; if ( image.getWidth() > image.getHeight() ) largeur = image.getWidth() + 1 ; else largeur = image.getHeight() + 1 ; matrix = null ; matriceajustee = null ; matrix = new double[nbNiveauxGris][largeur] ; for (y=0 ; y < nbNiveauxGris ; y++) for (x=0 ; x < largeur ; x++) matrix[y][x] = 0.0 ; // raz matrix for (i=0 ; i < dx.length ; i++) computeMatrix(dx[i], dy[i]) ; // On trouve la largeur de la matrice. for (y=0 ; y < nbNiveauxGris ; y++) for (x=0 ; x < largeur ; x++) if ( matrix[y][x] > 0.0 && x > max ) max = x ; // Moyenne for (y=0 ; y < nbNiveauxGris ; y++) for (x=0 ; x < largeur ; x++) matrix[y][x] /= (double)dx.length ; // On trouve la largeur pour ajuster puis on moyenne largeur = max + 1 ; matriceajustee = new double[nbNiveauxGris][largeur] ; for (y=0 ; y < nbNiveauxGris ; y++) for (x=0 ; x < largeur ; x++) matriceajustee[y][x] = matrix[y][x] ; } /** Methode qui effectue le remplissage de la matrice de cooccurrence. * @param dx Variation de calcul en X. * @param dy Variation de calcul en Y.*/ protected void computeMatrix(int dx, int dy) { int x, y, x1, y1, v0, nb ; int height = image.getHeight() ; int width = image.getWidth() ; boolean Fin ; int[][] tampon = new int[nbNiveauxGris][largeur] ; for (y=0 ; y < nbNiveauxGris ; y++) // Initialisation for (x=0 ; x < largeur ; x++) tampon[y][x] = 0 ; for (y=0 ; y < height ; y++) // calculs des run length for (x=0 ; x < width ; x++) { // pour chaque pixel v0 = (int)((double)nbNiveauxGris*(double)this.image.getPix(y, x)/256.0) ; nb = 1 ; Fin = false ; x1 = x ; y1 = y ; do { x1 += dx ; if ( x1 < 0 || x1 >= width ) Fin = true ; y1 += dy ; if ( y1 < 0 || y1 >= height ) Fin = true ; if ( !Fin && (int)((double)nbNiveauxGris*(double)this.image.getPix(y1, x1)/256.0) == v0 ) nb++ ; else Fin = true ; } while ( !Fin ) ; tampon[v0][nb]++ ; // on incrémente la matrice } for (y=0 ; y < nbNiveauxGris ; y++) // On ajuste pour corriger les erreurs de comptages multiples. for (x=1 ; x < largeur ; x++) tampon[y][x-1] -= tampon[y][x] ; for (y=0 ; y < nbNiveauxGris ; y++) // On met le résultat dans la matrice. for (x=1 ; x < largeur ; x++) matrix[y][x-1] += tampon[y][x] ; // On supprime la colonne 0 qui contient que des 0 (aucune chaine de longueur 0). tampon = null ; } /* ------------------------------------------------------ Les getters ------------------------------------------------------ */ /** Methode qui retourne la run length matrix non ajustee. * @return Le tableau de double[][] contenant la run length matrix.*/ public double[][] getMatrix() { return matrix ; } /** Methode qui retourne la run length matrix ajustee. La largeur est ajustee en fonction de la plus longue chaine. * @return Le tableau de double[][] contenant la run length matrix ajustee.*/ public double[][] getMatriceAjustee() { return matriceajustee ; } /** Tableau d'int contenant les variations de directions en X. * @return Direction en X.*/ public int[] getDx() { return dx ; } /** Tableau d'int contenant les variations de directions en Y. * @return Direction en Y.*/ public int[] getDy() { return dy ; } public String toString() { StringBuffer sb = new StringBuffer() ; for (int j=0 ; j < nbNiveauxGris ; j++) { for (int i=0 ; i < largeur ; i++) sb.append(matrix[j][i] + " ") ; sb.append("\n") ; } return sb.toString() ; } }
Partager