Révision 2

FibrilTool2.ijm (revision 2)
1
// FibrilTool by Arezki Boudaoud et al. Nature Protocols
2
//
3
// double click on the Fibril Tool to select the color channels
4
// select the region of interest using the polygon tool 
5
// then click on the image using the Tool
6

  
7
// the log output gives the average properties of the region
8
// 0) 	image title
9
//		cell number
10
// 1) 	x-coordinate of region centroid (scaled)
11
// 		y-coordinate of region centroid (scaled)
12
// 	 	area (scaled)
13
// 2)  nematic tensor
14
//		average orientation (angle in -90:90 in degrees)
15
// 		quality of the orientation (score between 0 and 1)
16
// The results are drawn on an overlay
17
// 3)  coordinates of polygon vertices for record
18

  
19

  
20
// scaling factor for drawing of segments
21
var norm_constant;
22

  
23
//threshold for flat regions
24
var thresh = 2;
25

  
26
//default for font size
27
var fsize = 15;
28

  
29
// number for cells
30
var num;
31

  
32
// default for numbering of cells
33
var numbering="yes";
34

  
35

  
36
//defaults for drawing
37
var fib="No";
38
var drw="No";
39

  
40

  
41
//default for width of lines
42
var lwidth = 2;
43

  
44
var pi = 3.14159265;
45

  
46

  
47
macro "Fibril Tool - C059L11eeL14beL41ebL178eL71e8L1a5eLa1e5" {
48

  
49
if ( (fib != "R") && (fib != "G") && (fib !="B") ) 
50
	exit("Select channel for fibrils \nPlease double-click on the tool");
51

  
52
if (selectionType()==-1) 
53
	exit("Selection required !"); 
54
id = getImageID(); 
55
title = getTitle();
56

  
57
getPixelSize(unit,pixelWidth,pixelHeight);
58
if (pixelWidth != pixelHeight) exit("Rectangular pixels!");
59
scale = pixelWidth;
60

  
61
setBatchMode(true);
62

  
63
//properties of selection
64
num++ ;
65
selectImage(id);
66
getSelectionCoordinates(vertx, verty);
67
c = polygonCentre(vertx,verty);
68
c0s = c[0]*scale ;
69
c1s = c[1]*scale ;
70
getRawStatistics(area);
71
areas = area*scale*scale;
72
pr = 2;
73
sortie = title+"\t"+num;
74
sortie = sortie+"\t"+d2s(c0s,pr)+"\t"+d2s(c1s,pr)+"\t"+d2s(areas,pr);
75

  
76
//extract fibril signal
77
selectImage(id);
78
run("Duplicate...", "title=Temp");
79
run("Crop"); 
80
getSelectionCoordinates(vertxloc, vertyloc);
81
if (fib == "R") setRGBWeights(1,0,0);
82
	else if (fib == "G") setRGBWeights(0,1,0); 
83
	else if (fib =="B") setRGBWeights(0,0,1);
84
	else exit("Fibril color undefined");
85
run("8-bit");
86

  
87

  
88
//compute x-gradient in "x"
89
selectWindow("Temp");
90
run("Duplicate...","title=x");
91
run("32-bit");
92
run("Translate...", "x=-0.5 y=0 interpolation=Bicubic");
93
run ("Duplicate...","title=x1");
94
run("Translate...", "x=1 y=0 interpolation=None");
95
imageCalculator("substract","x","x1");
96
selectWindow("x1");
97
close();
98

  
99
//compute y-gradient in "y"
100
selectWindow("Temp");
101
run ("Duplicate...","title=y");
102
run("32-bit");
103
run("Translate...", "x=0 y=-0.5 interpolation=Bicubic");
104
run ("Duplicate...","title=y1");
105
run("Translate...", "x=0 y=1 interpolation=None");
106
imageCalculator("substract","y","y1");
107
selectWindow("y1");
108
close();
109

  
110

  
111
//compute norm of gradient in "g"
112
selectWindow("x");
113
run("Duplicate...","title=g");
114
imageCalculator("multiply","g","x");
115
selectWindow("y");
116
run("Duplicate...","title=gp");
117
imageCalculator("multiply","gp","y");
118
imageCalculator("add","g","gp");
119
selectWindow("gp");
120
close();
121
selectWindow("g");
122
w = getWidth(); h = getHeight();
123
for (y=0; y<h; y++) {
124
	for (x=0; x<w; x++){
125
		setPixel(x, y, sqrt( getPixel(x, y)));
126
	}
127
}
128
//set the effect of the gradient to 1/255 when too low ; threshold = thresh
129
selectWindow("g");
130
for (y=0; y<h; y++) {
131
	for (x=0; x<w; x++){
132
		if (getPixel(x,y) < thresh) 
133
			setPixel(x, y, 255);
134
	}
135
}
136

  
137
//normalize "x" and "y" to components of normal
138
imageCalculator("divide","x","g");
139
imageCalculator("divide","y","g");
140

  
141

  
142
//compute nxx
143
selectWindow("x");
144
run("Duplicate...","title=nxx");
145
imageCalculator("multiply","nxx","x");
146
//compute nxy
147
selectWindow("x");
148
run("Duplicate...","title=nxy");
149
imageCalculator("multiply","nxy","y");
150
//compute nyy
151
selectWindow("y");
152
run("Duplicate...","title=nyy");
153
imageCalculator("multiply","nyy","y");
154

  
155
//closing
156
selectWindow("Temp");
157
close();
158
selectWindow("x");
159
close();
160
selectWindow("y");
161
close();
162
selectWindow("g");
163
close();
164

  
165
//averaging nematic tensor
166
selectWindow("nxx");
167
makeSelection("polygon",vertxloc,vertyloc);
168
getRawStatistics(area,xx);
169
close();
170
selectWindow("nxy");
171
makeSelection("polygon",vertxloc,vertyloc);
172
getRawStatistics(area,xy);
173
close();
174
selectWindow("nyy");
175
makeSelection("polygon",vertxloc,vertyloc);
176
getRawStatistics(area,yy);
177
close();
178

  
179
//eigenvalues and eigenvector of texture tensor
180
m = (xx + yy) / 2;
181
d = (xx - yy) / 2;
182
v1 = m + sqrt(xy*xy + d*d);
183
v2 = m - sqrt(xy*xy + d*d);
184
//direction
185
tn = - atan((v2 - xx) / xy);
186
//score
187
scoren = abs((v1-v2) / 2 / m);
188

  
189
//output
190
tsn=tn*180/pi;
191
// nematic tensor tensor
192
sortie = sortie+"\t"+d2s(tsn,pr)+"\t"+d2s(scoren,2*pr);
193

  
194
//polygon coordinates
195
np = vertx.length;
196
for (i=0; i<np; i++){
197
xp = vertx[i]; yp = verty[i];
198
sortie = sortie+"\t"+d2s(xp,pr)+"\t"+d2s(yp,pr);
199
}
200

  
201

  
202

  
203
//
204
//print output
205
print(sortie);
206
+setResult("Label", num-1, title);
207
setResult("x-coordinate(scaled)", num-1, d2s(c0s,pr));
208
setResult("y-coordinate(scaled)", num-1, d2s(c1s,pr));
209
setResult("Area", num-1, d2s(areas,pr));
210
setResult("nematic tensor average orientation", num-1, d2s(tsn,pr));
211
setResult("nematic tensor quality", num-1, d2s(scoren,2*pr));
212
setResult("polygon coordinates X", num-1, d2s(xp,pr));
213
setResult("polygon coordinates Y", num-1, d2s(yp,pr));
214
updateResults();
215

  
216
//
217
//drawing of directions and cell contour
218
setBatchMode(false);
219
selectImage(id);
220
run("Add Selection...", "stroke=yellow width="+lwidth);
221

  
222

  
223
// drawing nematic tensor
224
if ( drw != "No" ) {
225
u1 = norm_constant*sqrt(area)*cos(tn)*scoren + c[0];
226
v1 = - norm_constant*sqrt(area)*sin(tn)*scoren + c[1];
227
u2 = - norm_constant*sqrt(area)*cos(tn)*scoren + c[0];
228
v2 =  norm_constant*sqrt(area)*sin(tn)*scoren + c[1];
229
if (drw == "R") stroke = "red";
230
	else if (drw == "G") stroke = "green"; 
231
	else if (drw =="B") stroke = "blue";
232
	else exit("Drawing color undefined");
233
makeLine(u1,v1,u2,v2);
234
run("Add Selection...", "stroke="+stroke+" width"+lwidth);
235
}
236

  
237

  
238
//print number at center
239
selectImage(id);
240
if (numbering == "yes") { makeText(num,c[0],c[1]);
241
run("Add Selection...", "stroke="+stroke+" font="+fsize+" fill=none");
242
}
243

  
244
//restore original selection
245
makeSelection("polygon",vertx,verty);
246

  
247

  
248
setTool("polygon");
249
//end macro
250
}
251

  
252

  
253
// centroid of a polygon
254
function polygonCentre(x,y){
255
     n =x.length;
256
     area1 = 0;
257
     xc = 0; yc = 0;
258
     for (i=1; i<n; i++){
259
		  inc = x[i-1]*y[i] - x[i]*y[i-1];
260
         area1 += inc;
261
		  xc += (x[i-1]+x[i])*inc; 
262
		  yc += (y[i-1]+y[i])*inc;
263
     }
264
     inc = x[n-1]*y[0] - x[0]*y[n-1];
265
     area1 += inc;
266
     xc += (x[n-1]+x[0])*inc; 
267
     yc += (y[n-1]+y[0])*inc;    
268
     area1 *= 3;
269
     xc /= area1;
270
     yc /= area1;
271
     return newArray(xc,yc);
272
}
273

  
274

  
275

  
276
//distance between two points (x1,y1) et (x2,y2)
277
function distance(x1,y1,x2,y2) {
278
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
279
   }
280

  
281

  
282

  
283
// ImageJ runs this macro when user double-clicks on the Fibril tool icon
284
macro 'Fibril Tool Options' {
285
  Dialog.create("Fibril Tool");
286
  Dialog.addMessage("Choose the channel\n(Red/Green/Blue)");
287
  Dialog.addChoice("Channel for fibrils?\t", newArray("G", "R", "B"));
288
  Dialog.addChoice("Channel for drawing\t", newArray("B","No", "G", "R"));
289
  Dialog.addNumber("Multiply linelength by\t", 1);
290
  Dialog.addChoice("Nubmering ROIs?\t", newArray("yes","no"));
291
  Dialog.show();
292
  fib = Dialog.getChoice();
293
  drw = Dialog.getChoice();
294
  norm_constant = Dialog.getNumber();
295
  numbering = Dialog.getChoice();
296
  if ( drw == "No" ) waitForUser("Note that the results will not be drawn\nDouble-click on tool to set drawing on");
297
}
298

  

Formats disponibles : Unified diff