Révision 1

bin/image2geometry/measure_sepals.py (revision 1)
1
#!/usr/bin/env python
2

  
3
# Usage:
4
# ------
5
# measure_sepals.py directory filetype
6
# filetype = '.tif' or '.inr.gz'
7

  
8
from sys import path, argv
9
import os
10
import numpy as np
11
from multiprocessing import Pool
12
nproc = 11 # number of processors
13

  
14
indir=argv[1]
15
filetype=argv[2]
16

  
17
outdir=indir+'measures'
18

  
19
os.system("mkdir "+outdir)
20

  
21
def one_simulation(param):
22
	if filetype in param:
23
		filename=param
24
		os.system("measure_sepal.py "+filename+" "+outdir)
25
	return
26

  
27
list_params=[indir+'/'+filename for filename in os.listdir(indir)]
28

  
29
pool = Pool(processes=nproc)
30
pool.map(one_simulation, list_params)
31
pool.close()
32
pool.join()
33

  
0 34

  
bin/image2geometry/orient_sepals.sh (revision 1)
1
#! /bin/bash
2

  
3
# Usage:
4
# ------
5
# ./orient_sepals.sh directory filetype
6
# filetype = '.tif' or '.inr.gz'
7

  
8

  
9
indir=$1
10
filetype=$2
11

  
12
outdir=$indir'_oriented'
13

  
14

  
15
cd $indir
16

  
17
logfile='orient_sepals-'$indir'.log'
18
date > $logfile
19
echo '--------------------------' >> $logfile
20

  
21

  
22
for file in *$filetype
23
do
24
	echo '--------------------------' >> $logfile
25
	echo $file  >> $logfile
26
	echo $file $outdir
27
	echo '--------------------------' >> $logfile
28
	orient_sepal.py $file $outdir
29
	echo '--------------------------' >> $logfile
30
done
31

  
32

  
33
oriented='oriented-sepals'
34
mkdir $oriented
35
scp */*_oriented.inr.gz $oriented
36

  
37
cd ..
0 38

  
bin/image2geometry/bib_sepals.py (revision 1)
1
import numpy as np
2
import matplotlib.pyplot as plt
3
import math
4
from scipy import optimize
5

  
6
from titk_tools.io import imread, imsave, SpatialImage
7

  
8
def center_on_point(img, cm):
9
	'''
10
	Centers the image img on the point cm
11
	'''
12
	x = np.array(np.where(img > 0) )
13
	xp=np.zeros_like(x)
14
	img1=np.zeros_like(img)
15
	s=img.shape
16
	center_img=np.array(s)/2
17
	for i in [0, 1, 2]:
18
		xp[i]=x[i]+center_img[i]-cm[i]
19
	for i in range(0, len(x[0])):
20
		if ((xp[0][i]>=0) and (xp[0][i]<s[0]) and (xp[1][i]>=0) and (xp[1][i]<s[1]) and (xp[2][i]>=0) and (xp[2][i]<s[2])):
21
			img1[xp[0][i],xp[1][i],xp[2][i]]=img[x[0][i],x[1][i],x[2][i]]
22
	img1=SpatialImage(img1)
23
	img1.resolution=img.resolution
24
	return img1
25

  
26

  
27
def center_on_cm(img):
28
	'''
29
	Centers the image img on the point cm
30
	'''
31
	s=img.shape
32
	res=img.voxelsize
33
	x = np.array(np.where(img > 0) )
34
	cm = np.array([np.mean(x[i]) for i in [0,1,2]])
35
	xp=np.zeros_like(x)
36
	img1=np.zeros_like(img)
37
	center_img=np.array(s)/2
38
	for i in [0, 1, 2]:
39
		xp[i]=x[i]+center_img[i]-cm[i]
40
	for i in range(0, len(x[0])):
41
		if ((xp[0][i]>=0) and (xp[0][i]<s[0]) and (xp[1][i]>=0) and (xp[1][i]<s[1]) and (xp[2][i]>=0) and (xp[2][i]<s[2])):
42
			img1[xp[0][i],xp[1][i],xp[2][i]]=img[x[0][i],x[1][i],x[2][i]]
43
	img1=SpatialImage(img1)
44
	img1.voxelsize=res
45
	return img1
46

  
47

  
48
def principal_directions(img, threshold=10):	
49
	'''
50
	Returns the first two principal eigen vectors of an input image
51
	Fixed threshold of 10 for a 8 bit image
52
	It suppposes an isotropic sampling of the image.
53
	'''
54
	x,y,z = np.where(img > threshold) ## appropriate thresholding 
55
	x = x - np.mean(x)
56
	y = y - np.mean(y)
57
	z = z - np.mean(z)
58
	coords = np.vstack([x,y,z])
59
	cov = np.cov(coords)
60
	evals,evecs = np.linalg.eig(cov)
61
	sort_indices = np.argsort(evals)[::-1]
62
	return list(evecs[:,sort_indices][0:2])
63

  
64
def direct_frame(pv):
65
	'''
66
	Constructs a direct frame with first two unitvectors v0 and v1
67
	'''
68
	return np.array([pv[0], pv[1], np.cross(pv[0], pv[1])])
69

  
70

  
71
def write_transformation(T, trsf_file):
72
	'''
73
	writes the affine transformation T (4x4 matrix) in
74
	a textfile read by blockmatching.
75
	'''
76
	f = open(trsf_file,'w')
77
	f.write("( "+"\n")
78
	f.write("08 "+"\n")
79
	for i in T:
80
		for j in i:
81
			f.write("  "+str(j)+" ")
82
		f.write("\n")
83
	f.write(") ")
84
	return
85

  
86

  
87

  
88
def write_rigid(trsf_file, R, a):
89
	'''
90
	write a rigid transformation with rotation matrix R and translation a
91
	'''
92
	T = np.identity(4)
93
	T[0:3,0:3] = R
94
	T = np.transpose(T)
95
	T[0:3,3] = a
96
	write_transformation(T, trsf_file)
97
	return
98

  
99

  
100

  
101
def write_superposing_transfo(pv_flo, pv_ref, img, trsf_file):
102
	'''
103
	- pv_flo and pv-ref are lists of the first two principal vectors of the floating and the reference images respectively
104
	- img is the floating image
105
	'''
106
	# compute the rotation matrix R
107
	pframe_ref = direct_frame(pv_ref)
108
	pframe_flo = direct_frame(pv_flo)
109
	F = np.transpose(pframe_ref)
110
	G = np.transpose(pframe_flo)
111
	R = np.matmul(G, np.linalg.inv(F))
112
	# blockmatching rotates arround the origin,
113
	# so a rotation arround the middle of the image contains an additional translation t
114
	s = img.shape
115
	res = img.voxelsize
116
	com = np.array(res)*np.array(s)/2
117
	i = np.identity(3)
118
	t = np.dot((i-R),np.array(com))
119
	R = np.transpose(R)
120
	write_rigid(trsf_file, R, t)
121
	return
122

  
123

  
124
def add_side_slices(Img, x0, x1, y0, y1, z0, z1):
125
	"""
126
	adds 0 value slices on different sides of the image
127
	"""
128
	s=Img.shape
129
	ss=(s[0]+x0+x1,s[1]+y0+y1,s[2]+z0+z1)
130
	Img_new = (SpatialImage(np.zeros(ss))).astype('uint8')
131
	Img_new[x0:ss[0]-x1,y0:ss[1]-y1,z0:ss[2]-z1]=Img
132
	Img_new.voxelsize = Img.voxelsize
133
	return Img_new
134

  
135

  
136
def remove_side_slices(Img, x0, x1, y0, y1, z0, z1):
137
	"""
138
	removes slices on different sides of the image
139
	"""
140
	ss=Img.shape
141
	Img_new=Img[x0:ss[0]-x1,y0:ss[1]-y1,z0:ss[2]-z1]
142
	#Img_new.resolution = Img.resolution
143
	return Img_new
144

  
145

  
146
def measure_hight(a):
147
	b= np.where(a)
148
	height = 0
149
	if b[0].shape[0]>0 :
150
		height = b[0][-1]
151
	return height
152

  
153

  
154
def measure_height(a):
155
	b= np.where(a)
156
	height = [0,0]
157
	if b[0].shape[0]>0 :
158
		height = [b[0].min(),b[0].max()]
159
	return height
160

  
161

  
162
def extract_curve(x_section):
163
	sx = x_section.shape
164
	xx = np.zeros((sx[0],2))
165
	for i in range(0,sx[0]):
166
		xx[i,0] = i
167
		xx[i,1] = measure_hight(x_section[i,:])
168
	return xx
169

  
170

  
171
def extract_curves(x_section):
172
	sx = x_section.shape
173
	xup = np.zeros((sx[0],2))
174
	xdown = np.zeros((sx[0],2))
175
	for i in range(0,sx[0]):
176
		xup[i,0] = i
177
		xdown[i,0] = i
178
		xup[i,1] = measure_height(x_section[i,:])[1]
179
		xdown[i,1] = measure_height(x_section[i,:])[0]
180
	return xup, xdown
181

  
182

  
183
def write_curve(y, pixelsize, filename) :
184
	FILE = open(filename,"w")
185
	FILE.write('# '+str(pixelsize[0])+' '+str(pixelsize[1])+'\n')
186
	s = y.shape
187
	#FILE.write('# '+str(s[0])+'\n')
188
	for i in range(0,s[0]) :
189
		FILE.write(str(y[i,0])+' '+str(y[i,1])+'\n')
190
	FILE.close()
191
	return
192

  
193

  
194
def struct_element_sphere(radius):
195
	s=int(2*radius+1)
196
	structure=np.zeros((s,s,s))
197
	center = np.array([radius, radius, radius])
198
	Nl=range(s)
199
	for i in Nl:
200
		for j in Nl:
201
			for k in Nl:
202
				p=np.array([i,j,k])
203
				d=p-center
204
				dist=np.sqrt(sum(d*d))
205
				if dist<=radius:
206
					structure[i,j,k]=1
207
	return structure
208

  
209

  
210
def create_artificial_sepal(AA, RR, resolution):
211
	# A = parameters of an ellipse, as projected on xy plane (2d array)
212
	# R = curvature radius in directions x and y (2d array)
213
	# (A and R are given in micrometers)
214
	# resolution = voxelsize of the output stack
215
	A = np.array([AA[i]/resolution[i] for i in [0,1]])
216
	R = np.array([RR[i]/resolution[i] for i in [0,1]])
217
	h = np.array([math.sqrt(R[i]**2-A[i]**2) for i in range(len(A))])
218
	zmax=np.array([R[i]-math.sqrt(R[i]**2-A[i]**2) for i in [0,1]])
219
	#zmax= int(math.sqrt(zmax[0]*zmax[1]))
220
	zmax=zmax.mean()
221
	#zmax = 5
222
	print(zmax)
223
	marge = 0.2
224
	# creating the stack and the surface
225
	s = (int(A[0]*2*(1+marge)), int(A[1]*2*(1+marge)), int(zmax*(1+2*marge)))
226
	cm = np.array(s)/2
227
	x = np.array(range(0,s[0]))
228
	y = np.array(range(0,s[1]))
229
	xx = x - cm[0]
230
	yy = y - cm[1]
231
	#xgrid, ygrid = np.meshgrid(xx, yy, sparse=True)  # make sparse output arrays
232
	#mask=(((xgrid**2)/float(A[0])**2+(ygrid**2)/float(A[1])**2)<1).astype('uint8')
233
	z = np.zeros((s[0],s[1]))
234
	stack= np.zeros(s).astype('uint8')
235
	for i in x:
236
		for j in range(0,s[1]):
237
			if xx[i]**2/float(A[0])**2+yy[j]**2/float(A[1])**2<=1 :
238
				zx = (math.sqrt(R[0]**2-xx[i]**2)-h[0])*(1-abs(yy[j])/A[1])
239
				zy = (math.sqrt(R[1]**2-yy[j]**2)-h[1])*(1-abs(xx[i])/A[0])
240
				z[i,j] = math.sqrt(zx*zy)
241
				#z[i,j] = (zx+zy)/2
242
				#z[i,j] = 5
243
				stack[i,j,int(zmax*marge+z[i,j])]=1
244
	stack = SpatialImage(stack)
245
	stack.resolution = resolution
246
	return z, stack
247

  
248

  
249

  
250
def create_artificial_sepal_ellipse(AA, H, resolution):
251
	'''
252
	# A = parameters of an ellipse, as projected on xy plane (2d array)
253
	# R = curvature radius in directions x and y (2d array)
254
	# (A and R are given in micrometers)
255
	# resolution = voxelsize of the output stack
256
	'''
257
	A = np.array([AA[i]/resolution[i] for i in [0,1]])
258
	h = H/resolution[2]
259
	zmax=h
260
	marge = 0.2
261
	# creating the stack and the surface
262
	s = (int(A[0]*2*(1+marge)), int(A[1]*2*(1+marge)), int(zmax*(1+5*marge)))
263
	cm = np.array(s)/2
264
	x = np.array(range(0,s[0]))
265
	y = np.array(range(0,s[1]))
266
	xx = x - cm[0]
267
	yy = y - cm[1]
268
	#xgrid, ygrid = np.meshgrid(xx, yy, sparse=True)  # make sparse output arrays
269
	#mask=(((xgrid**2)/float(A[0])**2+(ygrid**2)/float(A[1])**2)<1).astype('uint8')
270
	z = np.zeros((s[0],s[1]))
271
	#z = -h*((xgrid**2)/float(A[0])**2+(ygrid**2)/float(A[1])**2)
272
	stack= np.zeros(s).astype('uint8')
273
	for i in x:
274
		for j in y:
275
			if xx[i]**2/float(A[0])**2+yy[j]**2/float(A[1])**2<=1 :
276
				z[i,j] = -h*((xx[i]**2)/float(A[0])**2+(yy[j]**2)/float(A[1])**2-1)
277
				stack[i,j,int(zmax*4*marge+z[i,j])]=1
278
	stack = SpatialImage(stack)
279
	stack.voxelsize = resolution
280
	return z, stack
281

  
282
# -------------------------------------------------------------------
283

  
284
def read_curve(filename) :
285
	"""
286
	Reads the coordinates of the point-list defining a 2D curve.
287
	**Returns**
288
	y : 2-column array
289
		defines a curve as an ordered list of points, 
290
		each row of the array represents a point on the curve and contains
291
		its 2D cartesian coordinates
292
	pixelsize : tuple (res0, res1) in micrometers
293
	"""	
294
	x0 = []
295
	pixelsize = (1.0,1.0)
296
	for line in file(filename):
297
		if line[0] == "#" :
298
			line = line.lstrip('# ')
299
			line = line.rstrip('\n')
300
			line_list = [float(x) for x in line.split(' ')]
301
			pixelsize = (line_list[0], line_list[1])
302
		else :
303
			line = line.rstrip('\n')
304
			line_list = [float(x) for x in line.split(' ')]
305
			x0.append(line_list)
306
	y = np.array(x0)
307
	return y, pixelsize
308

  
309

  
310

  
311
def distance(p1, p2):
312
	return np.sqrt((p1[0]-p2[0])**2+(p1[1]-p2[1])**2)
313

  
314
def distance_to_line(p1, p2, p0):
315
	'''
316
	gives the distance of point p0 to the line defined by points p1 and p2 (in 2d)
317
	'''
318
	return abs((p2[1]-p1[1])*p0[0]-(p2[0]-p1[0])*p0[1]+p2[0]*p1[1]-p2[1]*p1[0])/distance(p1,p2)
319

  
320
def curvature(p1,p2,p3):
321
	t1 = (p3[0]**2-p2[0]**2+p3[1]**2-p2[1]**2)/(2.0*(p3[1]-p2[1]))
322
	t2 = (p2[0]**2-p1[0]**2+p2[1]**2-p1[1]**2)/(2.0*(p2[1]-p1[1]))
323
	n1 = (p3[0]-p2[0])/(p3[1]-p2[1])
324
	n2 = (p2[0]-p1[0])/(p2[1]-p1[1])
325
	pcx = (t1-t2+p3[1]-p1[1])/(n1-n2)
326
	pc = [pcx, -n1*pcx+t1/2+p3[1]/2+p1[1]/2]
327
	R = distance(p1, pc)
328
	return 1.0/R, pc
329

  
330

  
331
def curvature2(p1,p2,p3):
332
	# http://www.ambrsoft.com/TrigoCalc/Circle3D.htm
333
	A = p1[0]*(p2[1]-p3[1])-p1[1]*(p2[0]-p3[0])+p2[0]*p3[1]-p3[0]*p2[1]
334
	B = (p1[0]**2+p1[1]**2)*(p3[1]-p2[1])+(p2[0]**2+p2[1]**2)*(p1[1]-p3[1])+(p3[0]**2+p3[1]**2)*(p2[1]-p1[1])
335
	C = (p1[0]**2+p1[1]**2)*(p3[0]-p2[0])+(p2[0]**2+p2[1]**2)*(p1[0]-p3[0])+(p3[0]**2+p3[1]**2)*(p2[0]-p1[0])
336
	D = (p1[0]**2+p1[1]**2)*(p3[0]*p2[1]-p2[0]*p3[1])+(p2[0]**2+p2[1]**2)*(p1[0]*p3[1]-p3[0]*p1[1])+(p3[0]**2+p3[1]**2)*(p2[0]*p1[1]-p1[0]*p2[1])
337
	x = -B/(2*A)
338
	y = C/(2*A)
339
	pc = [x, y]
340
	R = distance(p1, pc)
341
	return 1.0/R, pc
342

  
343

  
344
def curve_perle(y, first, last, step):
345
	yy=[]
346
	for i in range(first, last, step):
347
		if y[i][1]>0:
348
			yy.append(y[i])
349
	if i<last:
350
		yy.append(y[last])
351
	return np.array(yy)
352

  
353

  
354

  
355
def compute_curvature_radius(x,y):
356
	# coordinates of the barycenter
357
	x_m = np.mean(x)
358
	y_m = np.mean(y)
359
	def calc_R(c):
360
		""" calculate the distance of each 2D points from the center c=(xc, yc) """
361
		return np.sqrt((x-c[0])**2 + (y-c[1])**2)
362
	#
363
	def calc_ecart(c):
364
		""" calculate the algebraic distance between the 2D points and the mean circle centered at c=(xc, yc) """
365
		Ri = calc_R(c)
366
		return Ri - Ri.mean()
367
	#
368
	center_estimate = x_m, y_m
369
	center_2, ier = optimize.leastsq(calc_ecart, center_estimate)
370
	#
371
	xc_2, yc_2 = center_2
372
	Ri_2       = calc_R(center_2)
373
	R_2        = Ri_2.mean()
374
	residu_2   = sum((Ri_2 - R_2)**2)
375
	pc=[xc_2, yc_2]
376
	return R_2, pc
377

  
378

  
379
def analyze_curve1(name, y, pixelsize, outfilename, graph_name='graph.png'):
380
	# isotropic pixels
381
	y[:,0] = y[:,0]*pixelsize[0]
382
	y[:,1] = y[:,1]*pixelsize[1]
383
	maxv = [y[:,i].max() for i in [0,1]]
384
	# find first and last points on the curve
385
	step = 5
386
	sep_indices = np.where(y[:,1])[0]
387
	first = sep_indices[0]#+step/2
388
	last = sep_indices[-1]#-step/2
389
	# compute flat length
390
	flatlength = distance(y[first],y[last])
391
	print("flat length =", flatlength," um")
392
	# compute curved length and height (maximal distance to the base)
393
	yy = curve_perle(y, first, last, step)
394
	length = 0
395
	height = 0
396
	height_index = 0
397
	p1 = yy[0]
398
	p2 = yy[-1]
399
	for i in range(0, len(yy)-1):
400
		length = length + distance(yy[i+1],yy[i])
401
		d = distance_to_line(p1, p2, yy[i])
402
		if d>height :
403
			height = d
404
			height_index = i
405
	print("length = ",length," um")
406
	print("height = ",height," um")
407
	middle_point = yy[int(len(yy)/2)]
408
	# compute curvature radius by fitting the sepal section to a circle
409
	yyy=y[first:last]
410
	R, pc = compute_curvature_radius(yyy[:,0],yyy[:,1])
411
	print("R=",R," um")
412
	# cutting curve in pieces in order to estimate curvature radius on portions of the curve
413
	slength=len(yyy)
414
	y21=yyy[0:int(slength/2)]
415
	y22=yyy[int(slength/2):slength]
416
	y41=yyy[0:int(slength/4)]
417
	y423=yyy[int(slength/4):3*int(slength/4)]
418
	y44=yyy[3*int(slength/4):slength]
419
	# and computing the curvature radius for each portion
420
	R21, pc = compute_curvature_radius(y21[:,0],y21[:,1])
421
	R22, pc = compute_curvature_radius(y22[:,0],y22[:,1])
422
	R41, pc = compute_curvature_radius(y41[:,0],y41[:,1])
423
	R423, pc = compute_curvature_radius(y423[:,0],y423[:,1])
424
	R44, pc = compute_curvature_radius(y44[:,0],y44[:,1])
425
	fig = plt.figure()
426
	plt.plot(yy[:,0], yy[:,1], 'bo')
427
	plt.plot(y[:,0], y[:,1], 'r')
428
	plt.plot(y[first][0], y[first][1], 'ro')
429
	plt.plot(middle_point[0], middle_point[1], 'ro')
430
	plt.plot(y[last][0], y[last][1], 'ro')
431
	plt.plot(yy[height_index][0], yy[height_index][1], 'go')
432
	plt.plot(pc[0], pc[1], 'bx')
433
	plt.gca().set_aspect('equal', adjustable='box')
434
	#plt.show()
435
	fig.savefig(graph_name)
436
	#plt.close()
437
	# write the data into a file
438
	FILE = open(outfilename,"a")
439
	FILE.write(name+';'+str(length)+';'+str(R)+';'+str(flatlength)+';'+str(height)+'\n')
440
	FILE.close()
441
	return length, flatlength, height, R, R21, R22, R41, R423, R44
442

  
443
def imsave2D(filename, matrix):
444
	fig = plt.figure()
445
	plt.gca().imshow(np.transpose(matrix), interpolation='none')
446
	fig.savefig(filename)
447
	return
bin/image2geometry/inr2tif.ijm (revision 1)
1
//////////////////////////////////////////////////////////////////////////////////
2

  
3
//The script will process all your .inr.gz files in the chosen folder.
4
//The stacks will be saved in subfolders named as the treated lif files.
5

  
6
print ("===========================");
7
print ("==== Macro inr2tif.ijm ====");
8

  
9

  
10
//Choose the directory containing your .inr.gz files//
11
dir = getDirectory("Choose a directory")
12
setBatchMode(true);
13
list = getFileList(dir);
14

  
15
print(dir);
16
ShortNameDir=substring(dir,0,lastIndexOf(dir,"/"));
17
print (ShortNameDir);
18
dirout=ShortNameDir+"-tif/";
19
print("Creating output directory ",dirout);
20
File.makeDirectory(dirout);
21

  
22
for (FileInd=0; FileInd<list.length; FileInd++){
23
	FileName = list[FileInd];
24
	if(endsWith (FileName, ".inr.gz")){
25
		print ("### Processing ",FileName," ###");
26
		path = dir+FileName;
27
		ShortName=substring(FileName,0,indexOf(FileName,".inr.gz"));
28
		run("Bio-Formats Importer", "open=["+path+"] color_mode=Default view=Hyperstack stack_order=XYCZT use_virtual_stack open_all_series ");
29
		TiffName=ShortName+".tif";
30
		saveAs("Tiff", dirout+TiffName);
31
		run("Close All");
32
		print("Done with", FileName,"!");
33
	} else {
34
	print("### ",FileName," Not an .inr.gz file ###");
35
	};
36
};	
37
print("Done with this folder!!!");
38

  
39

  
40

  
41

  
bin/image2geometry/orient_sepal.py (revision 1)
1
#!/usr/bin/env python
2

  
3
'''
4
Usage:
5
orient_object.py filename output.txt
6

  
7
- filename = path and name of the stack file containing the object (background=0)
8

  
9
Output:
10
the image with the object reoriented:
11
- CM in the middle of the image
12
- first principal axis along y
13
- second principal axis along x
14

  
15
'''
16

  
17
from sys import argv
18
import os
19
import numpy as np
20
from scipy.ndimage.morphology import binary_closing, binary_opening
21

  
22
from titk_tools.io import imread, imsave, SpatialImage
23
from titk_tools.rw.registration import isotropic_resampling_seg
24

  
25
from bib_sepals import *
26

  
27

  
28

  
29
print('============== orient_sepal.py =================')
30

  
31
filename = argv[1]
32

  
33
print(argv)
34

  
35
imname = filename.split('/')[-1]
36
imnameroot = imname.split('.')[0]
37

  
38
outputdir = imnameroot+'_oriented/'
39
os.system("mkdir -p "+outputdir)
40

  
41
isodir = imnameroot+'_iso/'
42
os.system("mkdir -p "+isodir)
43

  
44
#outname = outputfile.split('/')[-1]
45
#outroot = outname.split('.')[0]
46

  
47
inrname = outputdir+imnameroot+'.inr.gz'
48
outfilename = outputdir+imnameroot+'_oriented.inr.gz'
49
isoname = isodir+imnameroot+'_iso.inr.gz'
50
sname = isodir+imnameroot+'_iso_closed.inr.gz'
51

  
52
# resample isotropically
53
print("----------------------")
54
print("isotropic resampling of : filename=", filename)
55
print("----------------------")
56
sepale=imread(filename)
57
voxelsize = sepale.voxelsize
58
print("voxelsize=",voxelsize)
59
s = sepale.shape
60
print("shape=",s)
61

  
62
radius=int(voxelsize[2]/voxelsize[0])
63
isovs=(voxelsize[0]*voxelsize[1]*voxelsize[2])**(1.0/3)
64
#isovs=voxelsize[0]
65
print("new voxelsize=",isovs)
66

  
67
sepale=SpatialImage(sepale>0, dtype='uint8', voxelsize=voxelsize, origin=[0, 0, 0])
68
imsave(inrname, sepale)
69
isotropic_resampling_seg(inrname, isoname, isovs)
70

  
71
sepale=imread(isoname)
72
s = sepale.shape
73
voxelsize = sepale.voxelsize
74
print('new voxelsize read=', voxelsize)
75
print('new shape', s)
76

  
77
# alongate the target image so that a sepal originally along the diagonal fits into the target image
78
print("----------------------")
79
print("elongating field : filename=", filename)
80
print("----------------------")
81
s_addy=int((np.sqrt(s[0]*s[1]*2)-np.sqrt(s[0]*s[1]))/2)
82
#s_addy=int(np.sqrt(s[0]*s[1])(1.-np.sqrt(2.))/2. * 1.05)
83
s_addz=int(s[2]*0.20)
84
sepale_long=add_side_slices(sepale, 0, 0, s_addy, s_addy, s_addz, s_addz)
85
sepale=SpatialImage(sepale_long, dtype='uint8', voxelsize=voxelsize, origin=[0, 0, 0])
86
imsave(isoname, sepale)
87
print('--------------------')
88

  
89
# smooth it with opening
90
sepale=imread(isoname)
91
s = sepale.shape
92
voxelsize = sepale.voxelsize
93
struct_el=struct_element_sphere(radius)
94
sepale = binary_closing(sepale, structure=struct_el, iterations=int(radius))
95
struct_el=struct_element_sphere(radius/2)
96
sepale = binary_closing(sepale, structure=struct_el, iterations=int(radius/2))
97
sepale=SpatialImage(sepale*255, dtype='uint8', voxelsize=voxelsize, origin=[0, 0, 0])
98
imsave(sname, sepale)
99

  
100

  
101
# put the center of mass in the center of the image
102
sepale_centered=center_on_cm(sepale)
103
voxelsize = sepale_centered.resolution
104
sepale_centered_filename = outputdir+imnameroot+'_centered.inr.gz'
105
imsave(sepale_centered_filename, sepale_centered)
106

  
107

  
108
# compute principal directions
109
pv_flo=principal_directions(sepale_centered)
110
print(pv_flo)
111

  
112
# sepals originally are oriented with top in more-or less "up" direction on the images
113
# while the eigenvectors' orientation is arbitrary
114
# --> do not change the original rough orientation
115

  
116
# check logitudinal direction:
117
if pv_flo[0][1]<0 :
118
	pv_flo[0] = -pv_flo[0]
119

  
120
# check the transversal direction
121
if pv_flo[1][0]<0 :
122
	pv_flo[1] = -pv_flo[1]
123

  
124
print("New pv_flo",pv_flo)
125

  
126
'''
127
pv_ref = [np.array([0,-1,0]),
128
np.array([-1,0,0])]
129

  
130
'''
131
pv_ref = [np.array([0,1,0]),
132
np.array([1,0,0])]
133

  
134

  
135
# compute superposing transformation
136
trsf_file=outputdir+imnameroot+'_rigid.txt'
137
write_superposing_transfo(pv_flo, pv_ref, sepale_centered, trsf_file)
138

  
139
# apply transformation
140
sepale_filename = outputdir+imnameroot+'_oriented.inr.gz'
141
apply_transfo_on_seg1(trsf_file, sepale_centered_filename, sepale_filename)
142

  
143
# smooth the transformed image
144
sepale=imread(sepale_filename)
145
sepale = binary_closing(sepale, structure=struct_el, iterations=radius)
146

  
147
# and save the oriented sepal
148
sepale=SpatialImage(sepale*255, dtype='uint8', voxelsize=voxelsize, origin=[0, 0, 0])
149
imsave(sepale_filename, sepale)
150

  
0 151

  
bin/image2geometry/measure_sepal.py (revision 1)
1
#!/usr/bin/env python
2

  
3
'''
4
Usage:
5
measure_sepal.py filename output.csv
6

  
7
- filename = path and name of the stack file containing the object (background=0)
8
the object is supposed already oriented as follows:
9
- output = output directory
10
---------------------------------------------------------------------------------
11
- CM in the middle of the image
12
- first principal axis along y
13
- second principal axis along x
14

  
15
Output:
16

  
17
measured data is written into the file output.csv
18
flat projections are written in the output directory
19

  
20
'''
21

  
22
from sys import argv
23
import os
24
import numpy as np
25
from scipy.ndimage.morphology import binary_closing, binary_opening
26

  
27
from titk_tools.io import imread, imsave
28
from bib_sepals import *
29

  
30

  
31
print('============== measure_sepal.py =================')
32

  
33
filename = argv[1]
34
outdir = argv[2]
35
outputfile=outdir+"/"+outdir+".csv"
36

  
37

  
38
print(argv)
39

  
40
imname = filename.split('/')[-1]
41
imnameroot = imname.split('.')[0]
42

  
43
outputdir = imnameroot+'_sections/'
44
projected2Dimage=outdir+"/"+imnameroot+"2D.png"
45
projected2Dimage_hight=outdir+"/hight_"+imnameroot+"2D.png"
46

  
47
os.system("mkdir -p "+outputdir)
48

  
49
outname = outputfile.split('/')[-1]
50
outroot = outname.split('.')[0]
51

  
52
print("----------------------")
53
print("reading the file ", filename)
54
print("----------------------")
55
sepale=imread(filename)
56
voxelsize = sepale.voxelsize
57
print("voxelsize=",voxelsize)
58
s = sepale.shape
59
print("shape=",s)
60

  
61
print("Projecting on 2D...")
62

  
63
def project2D(im3):
64
	s2=(s[1],s[0])
65
	im2=np.zeros(s2, dtype='uint8')
66
	for i in range(s[0]):
67
		im2[:,i]=np.array([max(im3[i,j,:]) for j in range(s[1])])
68
	return im2
69

  
70
def project2D_hightmap(im3):
71
	s2=(s[1],s[0])
72
	im2=np.zeros(s2, dtype='uint8')
73
	for i in range(s[0]):
74
		im2[:,i]=np.array([list(im3[i,j,:]).index(max(im3[i,j,:])) for j in range(s[1])])
75
	return im2
76

  
77

  
78
sepale2D=project2D(sepale)
79
imsave2D(projected2Dimage, sepale2D)
80

  
81
'''
82
sepale2D=project2D_hightmap(sepale)
83
imsave2D(projected2Dimage_hight, sepale2D)
84
'''
85

  
86
print('Extracting principal section curves...')
87

  
88
# longitudinal section
89
x_section = sepale[int(s[0]/2), :, :]
90
xup_filename = outputdir+imnameroot+'_section_xup.txt'
91
xdown_filename = outputdir+imnameroot+'_section_xdown.txt'
92
x_filename = outputdir+imnameroot+'_section_x.txt'
93
x_pixelsize = (voxelsize[1],voxelsize[2])
94
xup, xdown = extract_curves(x_section)
95

  
96
write_curve(xup, x_pixelsize, xup_filename)
97

  
98

  
99
# transversal section
100
y_section = sepale[:,int(s[1]/2), :]
101
yup_filename = outputdir+imnameroot+'_section_yup.txt'
102
ydown_filename = outputdir+imnameroot+'_section_ydown.txt'
103
y_filename = outputdir+imnameroot+'_section_y.txt'
104
y_pixelsize = (voxelsize[0],voxelsize[2])
105
yup, ydown = extract_curves(y_section)
106

  
107
write_curve(yup, y_pixelsize, yup_filename)
108

  
109

  
110
# 
111
# ----------------------------------------
112
print('Analyzing principal section curves...')
113

  
114
if not(os.path.isfile(outputfile)):
115
	FILE = open(outputfile,"w")
116
	FILE.write('Sepal;CurvedLength;FlatLength;LHeight;LR;LR21;LR22;LR41;LR423;LR44;CurvedWidth;FlatWidth;THeight;TR;TR21;TR22;TR41;TR423;TR44\n')
117
	FILE.close()
118

  
119
FILE = open(outputfile,"a")
120
FILE.write(imnameroot+';')
121

  
122
outfile=outroot+'_up_longitudinal.csv'
123
graph_name= outputdir+imnameroot+'_up_longitudinal.png'
124
length_x, flatlength_x, height_x, R, R21, R22, R41, R423, R44=analyze_curve1(imnameroot, xup, x_pixelsize, outfile, graph_name)
125

  
126
FILE.write(str(length_x)+';'+str(flatlength_x)+';'+str(height_x)+';'+str(R)+';'+str(R21)+';'+str(R22)+';'+str(R41)+';'+str(R423)+';'+str(R44)+';')
127

  
128
outfile=outroot+'_up_transversal.csv'
129
graph_name= outputdir+imnameroot+'_up_transversal.png'
130
length_y, flatlength_y, height_y, R, R21, R22, R41, R423, R44=analyze_curve1(imnameroot, yup, y_pixelsize, outfile, graph_name)
131

  
132
FILE.write(str(length_y)+';'+str(flatlength_y)+';'+str(height_y)+';'+str(R)+';'+str(R21)+';'+str(R22)+';'+str(R41)+';'+str(R423)+';'+str(R44)+'\n')
133

  
0 134

  
bin/image2geometry/lif2tif.ijm (revision 1)
1
//////////////////////////////////////////////////////////////////////////////////
2

  
3
//The script will process all your .lif files in the chosen folder.
4
//The stacks will be saved in subfolders named as the treated lif files.
5

  
6
print ("====================================");
7
print ("======== Macro lif2tif.ijm =========");
8
print ("====================================");
9

  
10
//Choose the directory containing your .lif file//
11
dir = getDirectory("Choose a directory")
12
setBatchMode(true);
13
list = getFileList(dir);
14

  
15
//Find .lif experiment//
16
for (FileInd=0; FileInd<list.length; FileInd++){
17
	FileName = list[FileInd];
18
	if(endsWith (FileName, "lif")){
19
		print ("### Processing ",FileName," ###");
20
		path = dir+FileName;
21
		ShortName=substring(FileName,0,indexOf(FileName,".lif"));
22
		print("Creating output directory ",ShortName);
23
		File.makeDirectory(dir+ShortName);
24
		//Open .lif//
25
		run("Bio-Formats Importer", "open=["+path+"] color_mode=Default view=Hyperstack stack_order=XYCZT use_virtual_stack open_all_series ");
26
		//Saving as .tif the content of the .lif files, in their destination folders//
27
		list = getList("image.titles");
28
		//get the name of each image opened//  
29
		ids=newArray(nImages);
30
		for (j=0; j<list.length; j++){
31
			//print(list[j]);
32
			selectImage(j+1);
33
			ids[j]=getTitle;
34
			//Get experiment name (title of the .lif file)//
35
			experiment_name=substring(ids[j],0,indexOf(ids[j],".lif"));
36
			//Remove the name of the .lif file that is included in each image//
37
			short_name1 = substring(ids[j], indexOf(ids[j], "- "), lastIndexOf(ids[j], ""));
38
			short_name = replace(short_name1, "- ", "");
39
			//If not a stack, save directly as .tif with a short name//
40
			if (nSlices==1){				
41
				print("Not a stack");
42
				run("8-bit");
43
				saveAs("Tiff", dir+File.separator+experiment_name+File.separator+short_name);
44
				print(short_name, ">>> Image saved as .tif");			
45
			//If a stack, reverse and save as .tif with a short name//
46
			} else {
47
				run("Reverse");
48
				run("8-bit");
49
				saveAs("Tiff", dir+File.separator+experiment_name+File.separator+short_name);
50
				print("----- ",short_name, " >>> Reversed and saved as .tif");
51
				};
52
			getPixelSize(unit, pw, ph, pd);
53
			print("Voxelsize="+pw+"x"+ph+"x"+pd+" "+unit+"^3");
54
			print("nSlices="+nSlices);
55
			};
56
		run("Close All");
57
		print("Done with", FileName,"!");
58
	} else {
59
	print("### ",FileName," Not a .lif file###");
60
	};
61
};	
62
print("Done with this folder!!!");
63

  
64

  
65

  
66

  
readme.txt (revision 1)
1
---------------------------------------------------------------------------
2
# "FLORIVAR" project
3
(project ID : "florivar")
4
---------------------------------------------------------------------------
5
Biophysics Team - RDP ENS Lyon
6

  
7
Developers :
8
--------------
9
Annamaria KISS, Corentin MOLLIER, Frenk Diego HARTASANCHEZ
10

  
11
Download the repository / Rapatrier le dépot
12
--------------------------------------------
13
cd "directory that will contain the project's directory"
14
svn --username $USER checkout http://forge.cbp.ens-lyon.fr/svn/florivar
15

  
16
Update (download changes from the repository)
17
--------------------------------------------
18
cd florivar
19
svn up
20

  
21
Commit (upload your changes into the repository)
22
-----------------------------------------------
23
cd florivar
24
svn commit
25

  
26
Changing the file tree
27
----------------------
28
if you want to add, delete or move individual files in the file-tree of the repository, you have to do that by svn
29
... cd in the right subdirectory
30
svn add toto
31
svn mv toto titi
32
svn rm titi
33
... and then make a commit (!)
34

  
35
Useful links
36
-------------
37
svn useful commands : http://wiki.greenstone.org/wiki/index.php/Useful_SVN_Commands
38
formats in a wiki : https://forge.cbp.ens-lyon.fr/redmine/help/wiki_syntax.html
39

  

Formats disponibles : Unified diff