Révision 18

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

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

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

  
27

  
28
def center_on_cm(img, volumic=True):
29
	'''
30
	Centers the image img on the point cm
31
	'''
32
	s=img.shape
33
	res=img.voxelsize
34
	if volumic:
35
		obj=img
36
	else :
37
		obj=binary_dilation(img)-img
38
	x = np.array(np.where(obj > 0) )
39
	cm = np.array([np.mean(x[i]) for i in [0,1,2]])
40
	x = np.array(np.where(img > 0) )
41
	xp=np.zeros_like(x)
42
	img1=np.zeros_like(img)
43
	center_img=np.array(s)/2
44
	for i in [0, 1, 2]:
45
		xp[i]=x[i]+center_img[i]-cm[i]
46
	for i in range(0, len(x[0])):
47
		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])):
48
			img1[xp[0][i],xp[1][i],xp[2][i]]=img[x[0][i],x[1][i],x[2][i]]
49
	img1=SpatialImage(img1)
50
	img1.voxelsize=res
51
	return img1
52

  
53

  
54
def principal_directions(img, threshold=10, volumic=True):	
55
	'''
56
	Returns the first two principal eigen vectors of an input image
57
	Fixed threshold of 10 for a 8 bit image
58
	It suppposes an isotropic sampling of the image.
59
	'''
60
	if volumic:
61
		obj=img
62
	else :
63
		obj=binary_dilation(img)-img
64
	x,y,z = np.where(obj*255 > threshold) ## appropriate thresholding 
65
	x = x - np.mean(x)
66
	y = y - np.mean(y)
67
	z = z - np.mean(z)
68
	coords = np.vstack([x,y,z])
69
	cov = np.cov(coords)
70
	evals,evecs = np.linalg.eig(cov)
71
	sort_indices = np.argsort(evals)[::-1]
72
	return list(evecs[:,sort_indices][0:2])
73

  
74
def direct_frame(pv):
75
	'''
76
	Constructs a direct frame with first two unitvectors v0 and v1
77
	'''
78
	return np.array([pv[0], pv[1], np.cross(pv[0], pv[1])])
79

  
80

  
81
def write_transformation(T, trsf_file):
82
	'''
83
	writes the affine transformation T (4x4 matrix) in
84
	a textfile read by blockmatching.
85
	'''
86
	f = open(trsf_file,'w')
87
	f.write("( "+"\n")
88
	f.write("08 "+"\n")
89
	for i in T:
90
		for j in i:
91
			f.write("  "+str(j)+" ")
92
		f.write("\n")
93
	f.write(") ")
94
	return
95

  
96

  
97

  
98
def write_rigid(trsf_file, R, a):
99
	'''
100
	write a rigid transformation with rotation matrix R and translation a
101
	'''
102
	T = np.identity(4)
103
	T[0:3,0:3] = R
104
	T = np.transpose(T)
105
	T[0:3,3] = a
106
	#write_transformation(T, trsf_file)
107
	np.savetxt(trsf_file, T, delimiter=";")
108
	return
109

  
110

  
111

  
112
def write_superposing_transfo(pv_flo, pv_ref, img, trsf_file):
113
	'''
114
	- pv_flo and pv-ref are lists of the first two principal vectors of the floating and the reference images respectively
115
	- img is the floating image
116
	'''
117
	# compute the rotation matrix R
118
	pframe_ref = direct_frame(pv_ref)
119
	pframe_flo = direct_frame(pv_flo)
120
	F = np.transpose(pframe_ref)
121
	G = np.transpose(pframe_flo)
122
	R = np.matmul(G, np.linalg.inv(F))
123
	# blockmatching rotates arround the origin,
124
	# so a rotation arround the middle of the image contains an additional translation t
125
	s = img.shape
126
	res = img.voxelsize
127
	com = np.array(res)*np.array(s)/2
128
	i = np.identity(3)
129
	t = np.dot((i-R),np.array(com))
130
	R = np.transpose(R)
131
	write_rigid(trsf_file, R, t)
132
	return
133

  
134

  
135
def add_side_slices(Img, x0, x1, y0, y1, z0, z1):
136
	"""
137
	adds 0 value slices on different sides of the image
138
	"""
139
	s=Img.shape
140
	ss=(s[0]+x0+x1,s[1]+y0+y1,s[2]+z0+z1)
141
	Img_new = (SpatialImage(np.zeros(ss))).astype('uint8')
142
	Img_new[x0:ss[0]-x1,y0:ss[1]-y1,z0:ss[2]-z1]=Img
143
	Img_new.voxelsize = Img.voxelsize
144
	return Img_new
145

  
146

  
147
def remove_side_slices(Img, x0, x1, y0, y1, z0, z1):
148
	"""
149
	removes slices on different sides of the image
150
	"""
151
	ss=Img.shape
152
	Img_new=Img[x0:ss[0]-x1,y0:ss[1]-y1,z0:ss[2]-z1]
153
	#Img_new.resolution = Img.resolution
154
	return Img_new
155

  
156

  
157
def measure_hight(a):
158
	b= np.where(a)
159
	height = 0
160
	if b[0].shape[0]>0 :
161
		height = b[0][-1]
162
	return height
163

  
164

  
165
def measure_height(a):
166
	b= np.where(a)
167
	height = [0,0]
168
	if b[0].shape[0]>0 :
169
		height = [b[0].min(),b[0].max()]
170
	return height
171

  
172

  
173
def extract_curve(x_section):
174
	sx = x_section.shape
175
	xx = np.zeros((sx[0],2))
176
	for i in range(0,sx[0]):
177
		xx[i,0] = i
178
		xx[i,1] = measure_hight(x_section[i,:])
179
	return xx
180

  
181

  
182
def extract_curves(x_section):
183
	sx = x_section.shape
184
	xup = np.zeros((sx[0],2))
185
	xdown = np.zeros((sx[0],2))
186
	for i in range(0,sx[0]):
187
		xup[i,0] = i
188
		xdown[i,0] = i
189
		xup[i,1] = measure_height(x_section[i,:])[1]
190
		xdown[i,1] = measure_height(x_section[i,:])[0]
191
	return xup, xdown
192

  
193

  
194
def write_curve(y, pixelsize, filename) :
195
	FILE = open(filename,"w")
196
	FILE.write('# '+str(pixelsize[0])+' '+str(pixelsize[1])+'\n')
197
	s = y.shape
198
	#FILE.write('# '+str(s[0])+'\n')
199
	for i in range(0,s[0]) :
200
		FILE.write(str(y[i,0])+' '+str(y[i,1])+'\n')
201
	FILE.close()
202
	return
203

  
204

  
205
def struct_element_sphere(radius):
206
	s=int(2*radius+1)
207
	structure=np.zeros((s,s,s))
208
	center = np.array([radius, radius, radius])
209
	Nl=range(s)
210
	for i in Nl:
211
		for j in Nl:
212
			for k in Nl:
213
				p=np.array([i,j,k])
214
				d=p-center
215
				dist=np.sqrt(sum(d*d))
216
				if dist<=radius:
217
					structure[i,j,k]=1
218
	return structure
219

  
220

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

  
259

  
260

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

  
293
# -------------------------------------------------------------------
294

  
295
def read_curve(filename) :
296
	"""
297
	Reads the coordinates of the point-list defining a 2D curve.
298
	**Returns**
299
	y : 2-column array
300
		defines a curve as an ordered list of points, 
301
		each row of the array represents a point on the curve and contains
302
		its 2D cartesian coordinates
303
	pixelsize : tuple (res0, res1) in micrometers
304
	"""	
305
	x0 = []
306
	pixelsize = (1.0,1.0)
307
	for line in file(filename):
308
		if line[0] == "#" :
309
			line = line.lstrip('# ')
310
			line = line.rstrip('\n')
311
			line_list = [float(x) for x in line.split(' ')]
312
			pixelsize = (line_list[0], line_list[1])
313
		else :
314
			line = line.rstrip('\n')
315
			line_list = [float(x) for x in line.split(' ')]
316
			x0.append(line_list)
317
	y = np.array(x0)
318
	return y, pixelsize
319

  
320

  
321

  
322
def distance(p1, p2):
323
	return np.sqrt((p1[0]-p2[0])**2+(p1[1]-p2[1])**2)
324

  
325
def distance_to_line(p1, p2, p0):
326
	'''
327
	gives the distance of point p0 to the line defined by points p1 and p2 (in 2d)
328
	'''
329
	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)
330

  
331
def curvature(p1,p2,p3):
332
	t1 = (p3[0]**2-p2[0]**2+p3[1]**2-p2[1]**2)/(2.0*(p3[1]-p2[1]))
333
	t2 = (p2[0]**2-p1[0]**2+p2[1]**2-p1[1]**2)/(2.0*(p2[1]-p1[1]))
334
	n1 = (p3[0]-p2[0])/(p3[1]-p2[1])
335
	n2 = (p2[0]-p1[0])/(p2[1]-p1[1])
336
	pcx = (t1-t2+p3[1]-p1[1])/(n1-n2)
337
	pc = [pcx, -n1*pcx+t1/2+p3[1]/2+p1[1]/2]
338
	R = distance(p1, pc)
339
	return 1.0/R, pc
340

  
341

  
342
def curvature2(p1,p2,p3):
343
	# http://www.ambrsoft.com/TrigoCalc/Circle3D.htm
344
	A = p1[0]*(p2[1]-p3[1])-p1[1]*(p2[0]-p3[0])+p2[0]*p3[1]-p3[0]*p2[1]
345
	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])
346
	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])
347
	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])
348
	x = -B/(2*A)
349
	y = C/(2*A)
350
	pc = [x, y]
351
	R = distance(p1, pc)
352
	return 1.0/R, pc
353

  
354

  
355
def curve_perle(y, first, last, step):
356
	yy=[]
357
	for i in range(first, last, step):
358
		if y[i][1]>0:
359
			yy.append(y[i])
360
	if i<last:
361
		yy.append(y[last])
362
	return np.array(yy)
363

  
364

  
365

  
366
def compute_curvature_radius(x,y):
367
	# coordinates of the barycenter
368
	x_m = np.mean(x)
369
	y_m = np.mean(y)
370
	def calc_R(c):
371
		""" calculate the distance of each 2D points from the center c=(xc, yc) """
372
		return np.sqrt((x-c[0])**2 + (y-c[1])**2)
373
	#
374
	def calc_ecart(c):
375
		""" calculate the algebraic distance between the 2D points and the mean circle centered at c=(xc, yc) """
376
		Ri = calc_R(c)
377
		return Ri - Ri.mean()
378
	#
379
	center_estimate = x_m, y_m
380
	center_2, ier = optimize.leastsq(calc_ecart, center_estimate)
381
	#
382
	xc_2, yc_2 = center_2
383
	Ri_2       = calc_R(center_2)
384
	R_2        = Ri_2.mean()
385
	residu_2   = sum((Ri_2 - R_2)**2)
386
	pc=[xc_2, yc_2]
387
	return R_2, pc
388

  
389

  
390
def circle(R, c):
391
	phi=np.linspace(np.pi/6., 5*np.pi/6., 51)
392
	x=c[0]+R*np.cos(phi)
393
	y=c[1]+R*np.sin(phi)
394
	return x,y
395

  
396

  
397

  
398
def analyze_curve1(name, y, pixelsize, outfilename,  title, graph_name='graph.png'):
399
	# isotropic pixels
400
	y[:,0] = y[:,0]*pixelsize[0]
401
	y[:,1] = y[:,1]*pixelsize[1]
402
	maxv = [y[:,i].max() for i in [0,1]]
403
	# find first and last points on the curve
404
	step = 5
405
	sep_indices = np.where(y[:,1])[0]
406
	first = sep_indices[0]#+step/2
407
	last = sep_indices[-1]#-step/2
408
	# compute flat length
409
	flatlength = distance(y[first],y[last])
410
	print("flat length =", flatlength," um")
411
	# compute curved length and height (maximal distance to the base)
412
	yy = curve_perle(y, first, last, step)
413
	length = 0
414
	height = 0
415
	height_index = 0
416
	p1 = yy[0]
417
	p2 = yy[-1]
418
	for i in range(0, len(yy)-1):
419
		length = length + distance(yy[i+1],yy[i])
420
		d = distance_to_line(p1, p2, yy[i])
421
		if d>height :
422
			height = d
423
			height_index = i
424
	print("length = ",length," um")
425
	print("height = ",height," um")
426
	middle_point = yy[int(len(yy)/2)]
427
	# compute curvature radius by fitting the sepal section to a circle
428
	yyy=y[first:last]
429
	R, pcR = compute_curvature_radius(yyy[:,0],yyy[:,1])
430
	print("R=",R," um")
431
	# cutting curve in pieces in order to estimate curvature radius on portions of the curve
432
	slength=len(yyy)
433
	y21=yyy[0:int(slength/2)]
434
	y22=yyy[int(slength/2):slength]
435
	y41=yyy[0:int(slength/4)]
436
	y423=yyy[int(slength/4):3*int(slength/4)]
437
	y44=yyy[3*int(slength/4):slength]
438
	# and computing the curvature radius for each portion
439
	R21, pc21 = compute_curvature_radius(y21[:,0],y21[:,1])
440
	R22, pc22 = compute_curvature_radius(y22[:,0],y22[:,1])
441
	R41, pc41 = compute_curvature_radius(y41[:,0],y41[:,1])
442
	R423, pc423 = compute_curvature_radius(y423[:,0],y423[:,1])
443
	R44, pc44 = compute_curvature_radius(y44[:,0],y44[:,1])
444
	fig = plt.figure(figsize=(12, 5))
445
	plt.plot(yy[:,0], yy[:,1], color='lightgreen', linewidth=10, label='length='+"{:.0f}".format(length)+" um")
446
	#plt.plot(y[:,0], y[:,1], '--')
447
	#plt.plot(y[first][0], y[first][1], 'ro')
448
	#plt.plot(middle_point[0], middle_point[1], 'ro')
449
	#plt.plot(y[last][0], y[last][1], 'ro')
450
	#plt.plot(yy[height_index][0], yy[height_index][1], 'go')
451
	plt.plot(pcR[0], pcR[1], 'ro', color='royalblue')
452
	plt.plot(pc423[0], pc423[1], 'ro', color='tomato')
453
	xR,yR = circle(R, pcR)
454
	plt.plot(xR, yR, "--",color='royalblue', linewidth=3, label='R='+"{:.0f}".format(R)+" um")
455
	xR,yR = circle(R423, pc423)
456
	plt.plot(xR, yR, "--", color='tomato', linewidth=3, label='R423='+"{:.0f}".format(R423)+" um")
457
	plt.gca().set_aspect('equal', adjustable='box')
458
	plt.xlabel('x (um)')
459
	plt.ylabel('z (um)')
460
	plt.ylim([0,1000])
461
	plt.xlim([0,3000])
462
	plt.legend()
463
	plt.grid(True)
464
	plt.title(title)
465
	#plt.show()
466
	fig.savefig(graph_name)
467
	#plt.close()
468
	# write the data into a file
469
	FILE = open(outfilename,"a")
470
	FILE.write(name+';'+str(length)+';'+str(R)+';'+str(flatlength)+';'+str(height)+'\n')
471
	FILE.close()
472
	return length, flatlength, height, R, R21, R22, R41, R423, R44
473

  
474
def imsave2D(filename, matrix):
475
	fig = plt.figure()
476
	plt.gca().imshow(np.transpose(matrix), interpolation='none')
477
	fig.savefig(filename)
478
	return
479

  
480

  
481

  
482
def register_objects(img_flo, img_ref, preregisterd=True, ph=6, pl=2, es=5, fs=3, save_files=True, iterations=2):
483
	# -- "Specify paths to image files" --
484
	# ------------------------------------------------
485
	sequence_name = "register_"
486
	file_times = [1, 2]
487
	filenames = [sequence_name + str(t).zfill(2)  for t in file_times]
488
	list_images = [img_flo, img_ref]
489

  
490
	images = {}
491
	for i in [0,1]:
492
		images[filenames[i]] = list_images[i]
493

  
494
	rigid_images = {}
495
	rigid_transformations = {}
496
	affine_images = {}
497
	affine_transformations = {}
498
	registered_images = {}
499
	non_linear_transformations = {}
500
	[reference_filename, floating_filename, reference_time, floating_time] = [ filenames[0], filenames[1], file_times[0], file_times[1]]
501
	#for reference_filename, floating_filename, reference_time, floating_time, in zip(filenames[1:],filenames[:-1],file_times[1:],file_times[:-1]):
502
	print("================================")
503
	print("Registering ", floating_time, " on ", reference_time)
504
	print("================================")
505

  
506
	###################################################
507
	# Output structure
508
	###################################################
509

  
510
	namestring = "_ph"+str(ph)+"_pl"+str(pl)+"_es"+str(es)+"_fs"+str(fs)
511

  
512
	output_dirname = dirname + '/' + sequence_name + "_" + str(floating_time).zfill(2) + "_on_" + str(reference_time).zfill(2) + "" + namestring
513
	if not os.path.exists(output_dirname):
514
		os.makedirs(output_dirname)
515

  
516
	reference_img = images[reference_filename]
517
	floating_img = images[floating_filename]
518

  
519
	####################################################################
520

  
521
	# Registration of the floating images on ref
522
	# -----------------------------------------------------
523
	
524
	if (not preregistered) :
525
		# A. Find optimised rigid transformations
526
		rigid_img, rigid_trsf = find_rigid_transfo2(reference_img, floating_img)
527
		rigid_images[floating_filename] = rigid_img
528
		rigid_transformations[floating_filename] = rigid_trsf
529
		
530
		if save_files:
531
			# rigid-registered images
532
			rigid_filename = output_dirname + '/' + floating_filename + "_rigid_on_" + str(reference_time).zfill(2) + ".inr.gz"
533
			imsave(rigid_filename, rigid_img)
534

  
535
			# optimised (with block-matching) rigid transformations
536
			rigid_trsf_filename = output_dirname + '/tr_' + floating_filename + '_rigid.txt'
537
			tfsave(rigid_trsf_filename, rigid_trsf)
538

  
539
		# B. Find optimised affine transformations (initialised by the rigid tfs computed above)
540
		affine_img, affine_trsf = find_affine_transfo(reference_img, floating_img, init_trsf=rigid_trsf)
541
		affine_images[floating_filename] = affine_img
542
		affine_transformations[floating_filename] = affine_trsf
543

  
544
		if save_files:
545
			# affine-registered images
546
			affine_filename = output_dirname + '/' + floating_filename + "_affine_on_" + str(reference_time).zfill(2) + ".inr.gz"
547
			imsave(affine_filename, affine_img)
548

  
549
			# optimised (with block-matching) affine transformations
550
			affine_trsf_filename = output_dirname + '/tr_' + floating_filename + '_affine.txt'
551
			tfsave(affine_filename, affine_trsf)
552
		floating_img0=affine_img
553
	else :
554
		floating_img0=floating_img
555
	# C. Find nonlinear transformations which register the affine-transformed images
556
	#registered_img, nl_trsf = find_nl_transfo(reference_img, affine_img, ph=ph, pl=pl, es=es, fs=fs)
557
	for it in range(iterations):
558
		registered_img, nl_trsf = find_nl_transfo(reference_img, floating_img0, ph=ph, pl=pl, es=es, fs=fs)
559
		registered_images[floating_filename] = registered_img
560
		non_linear_transformations[floating_filename] = nl_trsf
561

  
562
		# paths to nonlinearly registered images
563
		registered_filename = output_dirname + '/' + floating_filename + "_registered_on_" + str(reference_time).zfill(2) + "_it"+str(it)+".inr.gz"
564
		imsave(registered_filename, registered_img)
565
		floating_img0=registered_img
566

  
567
		if save_files:
568
			# non-linear transformations
569
			nl_trsf_filename = output_dirname + '/' + floating_filename + "_it"+str(it)+"_vectorfield.inr.gz"
570
			save_trsf(nl_trsf, nl_trsf_filename, compress=True)
571
	return registered_img
572

  
bin/gather_data.py (revision 18)
1
#!/usr/bin/env python
2

  
3
# before lounching the executable activate the timagetk conda environement
4
# conda activate florivar
5

  
6
# general imports :
7
from sys import argv
8
import pandas as pd
9
import os
10

  
11

  
12
def read_areas(dirname):
13
    listfiles=os.listdir(dirname)
14
    listfiles=[i for i in listfiles if '-area.csv' in i]
15
    sepalname=[]
16
    area=[]
17
    for i in listfiles:
18
        name=i.split('-area.csv')[0]
19
        sepalname.append(name)
20
        df=pd.read_csv(dirname+i, delimiter=',')[:-2]
21
        A=sum(df['Value'])/2.
22
        area.append(A)
23
    data = {'Sepal': sepalname, 'Area': area}
24
    newdf=pd.DataFrame.from_dict(data)    
25
    newdf=newdf.sort_values("Sepal", ascending=True, inplace=False)
26
    return newdf
27

  
28
def read_measurements(fname):
29
    df=pd.read_csv(fname, delimiter=';')
30
    print("Reading file : ",fname)
31
    print("Number of entries at reading: ",df.shape)
32
    df['Sepal']=[name.split('_oriented')[0] for name in df['Sepal']]
33
    df=df.sort_values("Sepal", ascending=True, inplace=False)
34
    return df
35

  
36

  
37
measures_filename = argv[1]
38
areadir = argv[2]+'/'
39

  
40
root=measures_filename.split('.csv')[0]
41
outputfile=root+"_full.csv"
42

  
43

  
44
df=read_measurements(measures_filename)
45
newdf=read_areas(areadir)
46
#
47
df = pd.merge(df, newdf, left_on="Sepal", right_on="Sepal")
48
#
49
df['CurvedSF']=df['CurvedWidth']/df['CurvedLength']
50
df['FlatSF']=df['FlatWidth']/df['FlatLength']
51
#
52
df['Thickness']=df['volume']/df['Area']
53
#
54
df['GaussK']=1./df['LR']/df['TR']
55
df['CentralGaussK']=1./df['LR423']/df['TR423']
56
df.to_csv(outputfile, index=False, sep=";")
57
print("Number of entries : ",df.shape)
58
labels=list(df.columns[1:])
59
print('Columns written:',list(df.columns))
60
print('Sepals:',list(df['Sepal']))
61
print('Measurements written in file:',outputfile)
62

  
63

  
bin/orient_sepal.py (revision 18)
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, tfread, SpatialImage
23
from titk_tools.registration import isotropic_resampling_seg, isotropic_resampling
24
from titk_tools.registration import apply_transfo_on_seg1, apply_transfo_on_image
25

  
26
from bib_sepals import *
27

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

  
30
filename = argv[1]
31
outputdir=argv[2]+'/'
32

  
33
segmented=True
34

  
35
if len(argv)>3:
36
	imagetype=argv[3]
37
	if imagetype=='grey':
38
		segmented=False
39

  
40
print(argv)
41
print('segmented=',segmented)
42

  
43
imname = filename.split('/')[-1]
44
imnameroot = imname.split('.')[0]
45

  
46
outfilename = outputdir+imnameroot+'_oriented.inr.gz'
47

  
48
# read the image
49
img=imread(filename)
50
# resample isotropically
51
print("----------------------")
52
print("isotropic resampling of : filename=", filename)
53
print("----------------------")
54
voxelsize = img.voxelsize
55
print("voxelsize=",voxelsize)
56
s = img.shape
57
imgtype=img.dtype
58
print("shape=",s)
59

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

  
65
sepale=SpatialImage(img>0, dtype='uint8', voxelsize=voxelsize, origin=[0, 0, 0])
66
if segmented:
67
	sepale=isotropic_resampling_seg(sepale,isovs)
68
else:
69
	img=isotropic_resampling(img,isovs)
70
	sepale=isotropic_resampling_seg(sepale,isovs)
71

  
72
s = sepale.shape
73
voxelsize = sepale.voxelsize
74
print('new shape', s)
75

  
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_addz=int(s[2]*0.20)
83
sepale=add_side_slices(sepale, 0, 0, s_addy, s_addy, s_addz, s_addz)
84
if not segmented :
85
	img=add_side_slices(img, 0, 0, s_addy, s_addy, s_addz, s_addz)
86

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

  
100
# put the center of mass in the center of the image
101
sepale_centered=center_on_cm(sepale, volumic=True)
102
if not segmented:
103
	img=center_on_cm(img, volumic=True)
104

  
105
# compute principal directions
106
pv_flo=principal_directions(sepale_centered, volumic=True)
107
print(pv_flo)
108

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

  
113
# check logitudinal direction:
114
if pv_flo[0][1]<0 :
115
	pv_flo[0] = -pv_flo[0]
116

  
117
# check the transversal direction
118
if pv_flo[1][0]<0 :
119
	pv_flo[1] = -pv_flo[1]
120

  
121
print("New pv_flo",pv_flo)
122

  
123
'''
124
pv_ref = [np.array([0,-1,0]),
125
np.array([-1,0,0])]
126

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

  
131

  
132
# compute superposing transformation
133
trsf_file=outputdir+imnameroot+'_rigid.txt'
134
write_superposing_transfo(pv_flo, pv_ref, sepale_centered, trsf_file)
135

  
136
trsf=tfread(trsf_file)
137
os.system("rm "+trsf_file)
138

  
139
# apply transformation
140
if segmented :
141
	oriented=apply_transfo_on_seg1(trsf, sepale_centered)
142
else :
143
	oriented=apply_transfo_on_image(trsf, img)
144

  
145
# smooth the transformed image
146
#sepale = binary_closing(oriented, structure=struct_el, iterations=radius)
147

  
148
# and save the oriented sepal
149
sepale_filename = outputdir+imnameroot+'_oriented.inr.gz'
150
if segmented :
151
	sepale=SpatialImage(oriented*255, dtype='uint8', voxelsize=voxelsize, origin=[0, 0, 0])
152
else:
153
	sepale=SpatialImage(oriented, dtype=imgtype, voxelsize=voxelsize, origin=[0, 0, 0])
154

  
155
imsave(sepale_filename, sepale)
156

  
0 157

  
bin/ImageJ/tif2tif.ijm (revision 18)
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+"-newtif/";
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, ".tif")){
25
		print ("### Processing ",FileName," ###");
26
		path = dir+FileName;
27
		ShortName=substring(FileName,0,indexOf(FileName,".tif"));
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
		open(path);
31
		saveAs("Tiff", dirout+TiffName);
32
		run("Close All");
33
		print("Done with", FileName,"!");
34
	} else {
35
	print("### ",FileName," Not a .tif file ###");
36
	};
37
};	
38
print("Done with this folder!!!");
39

  
40

  
41

  
42

  
bin/ImageJ/inr2tif.ijm (revision 18)
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/ImageJ/flip-vertically-mgx.ijm (revision 18)
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 flip-vertically-mgx.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+"-flipped/";
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, ".tif")){
25
		print ("### Processing ",FileName," ###");
26
		path = dir+FileName;
27
		pathout = dirout+FileName;
28
		print("avant open", FileName,"!");
29
		//run("Bio-Formats Importer", "open=["+path+"] color_mode=Default view=Hyperstack stack_order=XYCZT use_virtual_stack open_all_series ");
30
		open(path);
31
		print("apres open", FileName,"!");
32
		run("Flip Vertically", "stack");
33
		saveAs("Tiff", pathout);
34
		print("avant close", FileName,"!");
35
		run("Close All");
36
		print("Done with", FileName,"!");
37
	} else {
38
	print("### ",FileName," Not a .tif file ###");
39
	};
40
};	
41
print("Done with this folder!!!");
42

  
43

  
44

  
45

  
bin/ImageJ/lif2tif.ijm (revision 18)
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

  
bin/ImageJ/lsm2tif.ijm (revision 18)
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, ".lsm")){
25
		print ("### Processing ",FileName," ###");
26
		path = dir+FileName;
27
		ShortName=substring(FileName,0,indexOf(FileName,".lsm"));
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
		open(path);
31
		saveAs("Tiff", dirout+TiffName);
32
		run("Close All");
33
		print("Done with", FileName,"!");
34
	} else {
35
	print("### ",FileName," Not an .lsm file ###");
36
	};
37
};	
38
print("Done with this folder!!!");
39

  
40

  
41

  
42

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

  
3
'''
4
Usage:
5
measure_sepal.py filename outputdir
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

  
36
outputfile=outdir+"/"+outdir+".csv"
37

  
38
outputdir=outdir+"/sections/"
39
projectiondir=outdir+"/projections"
40

  
41

  
42
print(argv)
43

  
44
imname = filename.split('/')[-1]
45
imnameroot = imname.split('.')[0]
46

  
47
projected2Dimage=projectiondir+"/"+imnameroot+"2D.png"
48
#projected2Dimage_hight=outdir+"/hight_"+imnameroot+"2D.png"
49

  
50
os.system("mkdir -p "+outputdir)
51

  
52

  
53

  
54
outname = outputfile.split('/')[-1]
55
outroot = outname.split('.')[0]
56

  
57
print("----------------------")
58
print("reading the file ", filename)
59
print("----------------------")
60
sepale=imread(filename)
61
voxelsize = sepale.voxelsize
62
print("voxelsize=",voxelsize)
63
s = sepale.shape
64
imtype=sepale.dtype
65
print("shape=",s)
66

  
67
print("Computing the volume and volumic asymmetry...")
68
vol=len(np.where(sepale)[0])
69

  
70
# left-right symmetry
71
sep_left=sepale[:int(s[0]/2), :, :]
72
sep_right=sepale[int(s[0]/2):, :, :]
73
vol_left=len(np.where(sep_left)[0])
74
vol_right=len(np.where(sep_right)[0])
75
Avolx=(vol_left-vol_right+0.0)/(vol+0.0)
76

  
77
# top-base symmetry
78
sep_left=sepale[:, :int(s[1]/2), :]
79
sep_right=sepale[:, int(s[1]/2):, :]
80
vol_left=len(np.where(sep_left)[0])
81
vol_right=len(np.where(sep_right)[0])
82
Avoly=(vol_left-vol_right+0.0)/(vol+0.0)
83

  
84
vol=vol*voxelsize[0]*voxelsize[1]*voxelsize[2]
85

  
86

  
87

  
88
print("Projecting on 2D...")
89

  
90
def project2D(im3):
91
	s2=(s[1],s[0])
92
	im2=np.zeros(s2, dtype='uint8')
93
	for i in range(s[0]):
94
		im2[:,i]=np.array([max(im3[i,j,:]) for j in range(s[1])])
95
	return im2
96

  
97
def project2D_hightmap(im3):
98
	s2=(s[1],s[0])
99
	im2=np.zeros(s2, dtype='uint8')
100
	for i in range(s[0]):
101
		im2[:,i]=np.array([list(im3[i,j,:]).index(max(im3[i,j,:])) for j in range(s[1])])
102
	return im2
103

  
104

  
105
sepale2D=project2D(sepale)
106
imsave2D(projected2Dimage, sepale2D)
107

  
108
'''
109
sepale2D=project2D_hightmap(sepale)
110
imsave2D(projected2Dimage_hight, sepale2D)
111
'''
112

  
113

  
114
print('Extracting principal section curves...')
115

  
116
# longitudinal section
117
x_section = sepale[int(s[0]/2), :, :]
118
xup_filename = outputdir+imnameroot+'_section_xup.txt'
119
xdown_filename = outputdir+imnameroot+'_section_xdown.txt'
120
x_filename = outputdir+imnameroot+'_section_x.txt'
121
x_pixelsize = (voxelsize[1],voxelsize[2])
122
xup, xdown = extract_curves(x_section)
123

  
124
write_curve(xup, x_pixelsize, xup_filename)
125

  
126

  
127
# transversal section
128
y_section = sepale[:,int(s[1]/2), :]
129
yup_filename = outputdir+imnameroot+'_section_yup.txt'
130
ydown_filename = outputdir+imnameroot+'_section_ydown.txt'
131
y_filename = outputdir+imnameroot+'_section_y.txt'
132
y_pixelsize = (voxelsize[0],voxelsize[2])
133
yup, ydown = extract_curves(y_section)
134

  
135
write_curve(yup, y_pixelsize, yup_filename)
136

  
137

  
138
# 
139
# ----------------------------------------
140
print('Analyzing principal section curves...')
141

  
142
if not(os.path.isfile(outputfile)):
143
	FILE = open(outputfile,"w")
144
	FILE.write('Sepal;CurvedLength;FlatLength;LHeight;LR;LR21;LR22;LR41;LR423;LR44;CurvedWidth;FlatWidth;THeight;TR;TR21;TR22;TR41;TR423;TR44;volume;AsymL;AsymT\n')
145
	FILE.close()
146

  
147
FILE = open(outputfile,"a")
148
FILE.write(imnameroot+';')
149

  
150
print("Longitudinal section:")
151
outfile=outroot+'_up_longitudinal.csv'
152
graph_name= outputdir+imnameroot+'_up_longitudinal.png'
153

  
154
length_x, flatlength_x, height_x, R, R21, R22, R41, R423, R44=analyze_curve1(imnameroot, xup, x_pixelsize, outfile, "Longitudinal", graph_name)
155
os.system("rm "+outfile)
156

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

  
159
print("Transversal section:")
160
outfile=outroot+'_up_transversal.csv'
161
graph_name= outputdir+imnameroot+'_up_transversal.png'
162
length_y, flatlength_y, height_y, R, R21, R22, R41, R423, R44=analyze_curve1(imnameroot, yup, y_pixelsize, outfile, "Transversal", graph_name)
163
os.system("rm "+outfile)
164

  
165
FILE.write(str(length_y)+';'+str(flatlength_y)+';'+str(height_y)+';'+str(R)+';'+str(R21)+';'+str(R22)+';'+str(R41)+';'+str(R423)+';'+str(R44)+';')
166

  
167
FILE.write(str(vol)+';'+str(Avoly)+';'+str(Avolx)+'\n')
0 168

  
bin/MGX_CurvatureMapSegmentation.py (revision 18)
1
import os
2

  
3
'''
4
Input:
5
 - directory with detected sepal contour stacks .tif
6
 
7
Output:
8
 - segmented meshes (up and down surfaces treated as cells)
9
 - csv file / sepale containing : up and down surface areas
10

  
11
'''
12

  
13
# directory with detected sepal contours
14
filedata1="/home/akiss/RDP/Projects/Sepals/RNA-Seq_Final/06.ContourDetection/JL_22C/mgx-contours"
15

  
16

  
17
################### Parameters ###########
18

  
19
# cubesize for mesh creation
20
cubesize=str(15)
21

  
22
# size of neighbourhood for the segmented curvature map
23
curv_neighb=str(100)
24

  
25
# segmentation
26
signal_ratio=str(3) # minimal border / cell signal ratio (if less, cells are fused)
27
# - cell
28
cell_blur_radius=str(100)
29
seed_radius=str(150)
30
# - border
31
border_distance=str(100)
32
border_blur_radius=str(100)
33

  
34
#########################################
35

  
36
filedata=filedata1+'/'
37
meshresult=filedata1+'-MGX-mesh'+cubesize+'/'
38
curvaturecsvresult=filedata1+'-MGX-curvature-csv/'
39
arearesult=filedata1+'-MGX-area/'
40
segresult=filedata1+'-MGX-seg/'
41

  
42

  
43
os.system("mkdir "+meshresult)
44
os.system("mkdir "+curvaturecsvresult)
45
os.system("mkdir "+arearesult)
46
os.system("mkdir "+segresult)
47

  
48

  
49
listfiles=os.listdir(filedata)
50
listfiles=[ i for i in listfiles if '.tif' in i]
51

  
52

  
53
Process.Stack__System__Clear_Work_Stack('0')
54
Process.Stack__System__Clear_Main_Stack('0')
55
Process.Stack__System__Clear_Main_Stack('1')
56
Process.Stack__System__Clear_Work_Stack('1')
57
for i in listfiles:	
58
	Process.Stack__System__Set_Current_Stack('Main', '0')
59
	Process.Stack__System__Open(filedata+i, 'Main', '0')
60
	# --- creating surface mesh
61
	Process.Mesh__Creation__Marching_Cubes_Surface(cubesize, '5000')
62
	Process.Mesh__Structure__Smooth_Mesh('1', 'No')
63
	Process.Mesh__Structure__Smooth_Mesh('1', 'No')
64
	Process.Mesh__Structure__Smooth_Mesh('1', 'No')
65
	Process.Mesh__Structure__Smooth_Mesh('1', 'No')
66
	# --- computing maximal curvature
67
	csvname=i[:-4]+'-carte-courbure-Maximal'+curv_neighb+'.csv'
68
	Process.Mesh__Signal__Project_Mesh_Curvature(curvaturecsvresult+csvname, 'Maximal', curv_neighb, 'Yes', '-50.0', '50.0', '85')
69
	meshname=i[:-4]+'-mesh.mgxm'
70
	Process.Mesh__System__Save(meshresult+meshname, 'no', '0')
71
	Process.Stack__System__Clear_Work_Stack('0')
72
	Process.Stack__System__Clear_Main_Stack('0')
73
	Process.Stack__System__Clear_Main_Stack('1')
74
	Process.Stack__System__Clear_Work_Stack('1')
75
	# --- watershed segmentation of the maximal curvature map
76
	Process.Mesh__Segmentation__Auto_Segmentation('Yes', 'No', cell_blur_radius, seed_radius, border_blur_radius, '100.0', border_distance, signal_ratio)
77
	segname=i[:-4]+'-seg.mgxm'
78
	Process.Mesh__System__Save(segresult+segname, 'no', '0')
79
	# --- computing the area of the faces
80
	csvname=i[:-4]+'-area.csv'
81
	Process.Mesh__Heat_Map__Heat_Map_Classic('Area', 'Geometry', arearesult+csvname, 'Geometry', 'No', '0', '65535', 'Yes', 'No', 'None', 'No', 'Decreasing', 'Ratio', '0.001', '1')
82
	# --- computing teh perimeter
83
	#csvname=i[:-4]+'-perimeter.csv'
84
	#Process.Mesh__Heat_Map__Heat_Map('/Geometry/Perimeter', 'No', 'No', '', 'No', '', '', 'Yes', 'Yes')
85
	# --- computing gaussian curvature
86
	#Process.Mesh__Signal__Project_Mesh_Curvature('', 'Gaussian', '100', 'Yes', '-50.0', '50.0', '85')
87
	"""print("Please put two seeds on the two sides of the sepal :-) ... ")
88
	a=input("")
89
	Process.Mesh__Segmentation__Watershed_Segmentation('50000')
90
	csvname=i[:-4]+'-area.csv'
91
	Process.Mesh__Heat_Map__Heat_Map_Classic('Area', 'Geometry', csvresult+csvname, 'Geometry', 'No', '0', '65535', 'Yes', 'No', 'None', 'No', 'Decreasing', 'Ratio', '0.001', '1')
92
	"""
bin/MGX_EdgeDetect.py (revision 18)
1
import os
2

  
3
'''
4
Input:
5
 - directory with grey images of sepals
6
 
7
Output:
8
 - detected sepal contour stacks
9

  
10
'''
11

  
12
# directory of grey images
13
filedata="/home/biophysics/Desktop/Fanfan/Col-0_A-tif"
14

  
15

  
16
################### Parameters ###########
17

  
18
# smoothing
19
gaussianblurvalue=str(1)
20

  
21
# threshold value for the Edgedetect procedure 
22
edgedetectvalue=str(8000)
23

  
24
# xy dilation value
25
dilatevalue=str(0)
26

  
27
#########################################
28

  
29
path=filedata+'/'
30
outputdir=filedata+'-MGX-EdgeDetect_Blur'+gaussianblurvalue+'_ED'+edgedetectvalue+'_d'+dilatevalue+'/'
31
os.system("mkdir "+outputdir)
32

  
33
listfiles=os.listdir(path)
34
listfiles=[ i for i in listfiles if '.tif' in i]
35

  
36
Process.Stack__System__Clear_Work_Stack('0')
37
Process.Stack__System__Clear_Main_Stack('0')
38
Process.Stack__System__Clear_Main_Stack('1')
39
Process.Stack__System__Clear_Work_Stack('1')
40
for i in listfiles:	
41
	Process.Stack__System__Set_Current_Stack('Main', '0')
42
	Process.Stack__System__Open(path+i, 'Main', '0')
43
	Process.Stack__System__Open(path+i, 'Main', '1')
44
	Process.Stack__Filters__Gaussian_Blur_Stack(gaussianblurvalue, gaussianblurvalue, gaussianblurvalue)
45
	Process.Stack__MultiStack__Copy_Work_to_Main_Stack()
46
	Process.Stack__MultiStack__Swap_or_Copy_Stack_1_and_2('Main', '1 -> 2')
47
	Process.Stack__Morphology__Edge_Detect(edgedetectvalue, '2.0', '0.3', '30000')
48
	Process.Stack__MultiStack__Copy_Work_to_Main_Stack()
49
	Process.Stack__MultiStack__Swap_or_Copy_Stack_1_and_2('Main', '1 <-> 2')
50
	Process.Stack__System__Set_Current_Stack('Main', '0')
51
	Process.Stack__Canvas__Reverse_Axes('No', 'No', 'Yes')
52
	Process.Stack__Morphology__Edge_Detect(edgedetectvalue, '2.0', '0.3', '30000')
53
	Process.Stack__Canvas__Reverse_Axes('No', 'No', 'Yes')
54
	Process.Stack__MultiStack__Swap_or_Copy_Stack_1_and_2('Main', '1 <- 2')
55
	Process.Stack__System__Set_Current_Stack('Both', '0')
56
	Process.Stack__MultiStack__Combine_Stacks('Product')
57
	Process.Stack__System__Set_Current_Stack('Work', '0')
58
	Process.Stack__Morphology__Dilate(dilatevalue, dilatevalue, "0", 'No', 'No')
59
	Process.Stack__System__Save(outputdir+"MGX_"+i[:-4]+'_e'+edgedetectvalue+'_d'+dilatevalue+'.tif', 'Work', '0', '0')
60
	Process.Stack__System__Clear_Work_Stack('0')
61
	Process.Stack__System__Clear_Main_Stack('0')
62
	Process.Stack__System__Clear_Main_Stack('1')
63
	Process.Stack__System__Clear_Work_Stack('1')
64
	Process.Stack__System__Clear_Main_Stack('2')
65
	Process.Stack__System__Clear_Work_Stack('2')
bin/measure_sepals.py (revision 18)
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 -p "+outdir)
20
os.system("mkdir -p "+outdir+"/sections")
21
os.system("mkdir -p "+outdir+"/projections")
22

  
23

  
24
def one_simulation(param):
25
	if filetype in param:
26
		filename=param
27
		os.system("measure_sepal.py "+filename+" "+outdir)
28
	return
29

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

  
32
pool = Pool(processes=nproc)
33
pool.map(one_simulation, list_params)
34
pool.close()
35
pool.join()
36

  
0 37

  
bin/orient_sepals.sh (revision 18)
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
imagetype=$3
12

  
13
outdir=$indir'_oriented-sepals'
14

  
15
mkdir $indir'/'$outdir
16

  
17
cd $indir
18

  
19
logfile='orient_sepals-'$indir'.log'
20
date > $logfile
21
echo '--------------------------' >> $logfile
22

  
23

  
24
for file in *$filetype
25
do
26
	echo '--------------------------' >> $logfile
27
	echo $file  >> $logfile
28
	echo $file $outdir
29
	echo '--------------------------' >> $logfile
30
	if test $imagetype=="grey"
31
	then
... Ce différentiel a été tronqué car il excède la taille maximale pouvant être affichée.

Formats disponibles : Unified diff