root / bin / image2geometry / bib_sepals.py @ 1
Historique | Voir | Annoter | Télécharger (12,62 ko)
1 | 1 | akiss | import numpy as np |
---|---|---|---|
2 | 1 | akiss | import matplotlib.pyplot as plt |
3 | 1 | akiss | import math |
4 | 1 | akiss | from scipy import optimize |
5 | 1 | akiss | |
6 | 1 | akiss | from titk_tools.io import imread, imsave, SpatialImage |
7 | 1 | akiss | |
8 | 1 | akiss | def center_on_point(img, cm): |
9 | 1 | akiss | '''
|
10 | 1 | akiss | Centers the image img on the point cm
|
11 | 1 | akiss | '''
|
12 | 1 | akiss | x = np.array(np.where(img > 0) )
|
13 | 1 | akiss | xp=np.zeros_like(x) |
14 | 1 | akiss | img1=np.zeros_like(img) |
15 | 1 | akiss | s=img.shape |
16 | 1 | akiss | center_img=np.array(s)/2
|
17 | 1 | akiss | for i in [0, 1, 2]: |
18 | 1 | akiss | xp[i]=x[i]+center_img[i]-cm[i] |
19 | 1 | akiss | for i in range(0, len(x[0])): |
20 | 1 | akiss | 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 | 1 | akiss | img1[xp[0][i],xp[1][i],xp[2][i]]=img[x[0][i],x[1][i],x[2][i]] |
22 | 1 | akiss | img1=SpatialImage(img1) |
23 | 1 | akiss | img1.resolution=img.resolution |
24 | 1 | akiss | return img1
|
25 | 1 | akiss | |
26 | 1 | akiss | |
27 | 1 | akiss | def center_on_cm(img): |
28 | 1 | akiss | '''
|
29 | 1 | akiss | Centers the image img on the point cm
|
30 | 1 | akiss | '''
|
31 | 1 | akiss | s=img.shape |
32 | 1 | akiss | res=img.voxelsize |
33 | 1 | akiss | x = np.array(np.where(img > 0) )
|
34 | 1 | akiss | cm = np.array([np.mean(x[i]) for i in [0,1,2]]) |
35 | 1 | akiss | xp=np.zeros_like(x) |
36 | 1 | akiss | img1=np.zeros_like(img) |
37 | 1 | akiss | center_img=np.array(s)/2
|
38 | 1 | akiss | for i in [0, 1, 2]: |
39 | 1 | akiss | xp[i]=x[i]+center_img[i]-cm[i] |
40 | 1 | akiss | for i in range(0, len(x[0])): |
41 | 1 | akiss | 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 | 1 | akiss | img1[xp[0][i],xp[1][i],xp[2][i]]=img[x[0][i],x[1][i],x[2][i]] |
43 | 1 | akiss | img1=SpatialImage(img1) |
44 | 1 | akiss | img1.voxelsize=res |
45 | 1 | akiss | return img1
|
46 | 1 | akiss | |
47 | 1 | akiss | |
48 | 1 | akiss | def principal_directions(img, threshold=10): |
49 | 1 | akiss | '''
|
50 | 1 | akiss | Returns the first two principal eigen vectors of an input image
|
51 | 1 | akiss | Fixed threshold of 10 for a 8 bit image
|
52 | 1 | akiss | It suppposes an isotropic sampling of the image.
|
53 | 1 | akiss | '''
|
54 | 1 | akiss | x,y,z = np.where(img > threshold) ## appropriate thresholding
|
55 | 1 | akiss | x = x - np.mean(x) |
56 | 1 | akiss | y = y - np.mean(y) |
57 | 1 | akiss | z = z - np.mean(z) |
58 | 1 | akiss | coords = np.vstack([x,y,z]) |
59 | 1 | akiss | cov = np.cov(coords) |
60 | 1 | akiss | evals,evecs = np.linalg.eig(cov) |
61 | 1 | akiss | sort_indices = np.argsort(evals)[::-1]
|
62 | 1 | akiss | return list(evecs[:,sort_indices][0:2]) |
63 | 1 | akiss | |
64 | 1 | akiss | def direct_frame(pv): |
65 | 1 | akiss | '''
|
66 | 1 | akiss | Constructs a direct frame with first two unitvectors v0 and v1
|
67 | 1 | akiss | '''
|
68 | 1 | akiss | return np.array([pv[0], pv[1], np.cross(pv[0], pv[1])]) |
69 | 1 | akiss | |
70 | 1 | akiss | |
71 | 1 | akiss | def write_transformation(T, trsf_file): |
72 | 1 | akiss | '''
|
73 | 1 | akiss | writes the affine transformation T (4x4 matrix) in
|
74 | 1 | akiss | a textfile read by blockmatching.
|
75 | 1 | akiss | '''
|
76 | 1 | akiss | f = open(trsf_file,'w') |
77 | 1 | akiss | f.write("( "+"\n") |
78 | 1 | akiss | f.write("08 "+"\n") |
79 | 1 | akiss | for i in T: |
80 | 1 | akiss | for j in i: |
81 | 1 | akiss | f.write(" "+str(j)+" ") |
82 | 1 | akiss | f.write("\n")
|
83 | 1 | akiss | f.write(") ")
|
84 | 1 | akiss | return
|
85 | 1 | akiss | |
86 | 1 | akiss | |
87 | 1 | akiss | |
88 | 1 | akiss | def write_rigid(trsf_file, R, a): |
89 | 1 | akiss | '''
|
90 | 1 | akiss | write a rigid transformation with rotation matrix R and translation a
|
91 | 1 | akiss | '''
|
92 | 1 | akiss | T = np.identity(4)
|
93 | 1 | akiss | T[0:3,0:3] = R |
94 | 1 | akiss | T = np.transpose(T) |
95 | 1 | akiss | T[0:3,3] = a |
96 | 1 | akiss | write_transformation(T, trsf_file) |
97 | 1 | akiss | return
|
98 | 1 | akiss | |
99 | 1 | akiss | |
100 | 1 | akiss | |
101 | 1 | akiss | def write_superposing_transfo(pv_flo, pv_ref, img, trsf_file): |
102 | 1 | akiss | '''
|
103 | 1 | akiss | - pv_flo and pv-ref are lists of the first two principal vectors of the floating and the reference images respectively
|
104 | 1 | akiss | - img is the floating image
|
105 | 1 | akiss | '''
|
106 | 1 | akiss | # compute the rotation matrix R
|
107 | 1 | akiss | pframe_ref = direct_frame(pv_ref) |
108 | 1 | akiss | pframe_flo = direct_frame(pv_flo) |
109 | 1 | akiss | F = np.transpose(pframe_ref) |
110 | 1 | akiss | G = np.transpose(pframe_flo) |
111 | 1 | akiss | R = np.matmul(G, np.linalg.inv(F)) |
112 | 1 | akiss | # blockmatching rotates arround the origin,
|
113 | 1 | akiss | # so a rotation arround the middle of the image contains an additional translation t
|
114 | 1 | akiss | s = img.shape |
115 | 1 | akiss | res = img.voxelsize |
116 | 1 | akiss | com = np.array(res)*np.array(s)/2
|
117 | 1 | akiss | i = np.identity(3)
|
118 | 1 | akiss | t = np.dot((i-R),np.array(com)) |
119 | 1 | akiss | R = np.transpose(R) |
120 | 1 | akiss | write_rigid(trsf_file, R, t) |
121 | 1 | akiss | return
|
122 | 1 | akiss | |
123 | 1 | akiss | |
124 | 1 | akiss | def add_side_slices(Img, x0, x1, y0, y1, z0, z1): |
125 | 1 | akiss | """
|
126 | 1 | akiss | adds 0 value slices on different sides of the image
|
127 | 1 | akiss | """
|
128 | 1 | akiss | s=Img.shape |
129 | 1 | akiss | ss=(s[0]+x0+x1,s[1]+y0+y1,s[2]+z0+z1) |
130 | 1 | akiss | Img_new = (SpatialImage(np.zeros(ss))).astype('uint8')
|
131 | 1 | akiss | Img_new[x0:ss[0]-x1,y0:ss[1]-y1,z0:ss[2]-z1]=Img |
132 | 1 | akiss | Img_new.voxelsize = Img.voxelsize |
133 | 1 | akiss | return Img_new
|
134 | 1 | akiss | |
135 | 1 | akiss | |
136 | 1 | akiss | def remove_side_slices(Img, x0, x1, y0, y1, z0, z1): |
137 | 1 | akiss | """
|
138 | 1 | akiss | removes slices on different sides of the image
|
139 | 1 | akiss | """
|
140 | 1 | akiss | ss=Img.shape |
141 | 1 | akiss | Img_new=Img[x0:ss[0]-x1,y0:ss[1]-y1,z0:ss[2]-z1] |
142 | 1 | akiss | #Img_new.resolution = Img.resolution
|
143 | 1 | akiss | return Img_new
|
144 | 1 | akiss | |
145 | 1 | akiss | |
146 | 1 | akiss | def measure_hight(a): |
147 | 1 | akiss | b= np.where(a) |
148 | 1 | akiss | height = 0
|
149 | 1 | akiss | if b[0].shape[0]>0 : |
150 | 1 | akiss | height = b[0][-1] |
151 | 1 | akiss | return height
|
152 | 1 | akiss | |
153 | 1 | akiss | |
154 | 1 | akiss | def measure_height(a): |
155 | 1 | akiss | b= np.where(a) |
156 | 1 | akiss | height = [0,0] |
157 | 1 | akiss | if b[0].shape[0]>0 : |
158 | 1 | akiss | height = [b[0].min(),b[0].max()] |
159 | 1 | akiss | return height
|
160 | 1 | akiss | |
161 | 1 | akiss | |
162 | 1 | akiss | def extract_curve(x_section): |
163 | 1 | akiss | sx = x_section.shape |
164 | 1 | akiss | xx = np.zeros((sx[0],2)) |
165 | 1 | akiss | for i in range(0,sx[0]): |
166 | 1 | akiss | xx[i,0] = i
|
167 | 1 | akiss | xx[i,1] = measure_hight(x_section[i,:])
|
168 | 1 | akiss | return xx
|
169 | 1 | akiss | |
170 | 1 | akiss | |
171 | 1 | akiss | def extract_curves(x_section): |
172 | 1 | akiss | sx = x_section.shape |
173 | 1 | akiss | xup = np.zeros((sx[0],2)) |
174 | 1 | akiss | xdown = np.zeros((sx[0],2)) |
175 | 1 | akiss | for i in range(0,sx[0]): |
176 | 1 | akiss | xup[i,0] = i
|
177 | 1 | akiss | xdown[i,0] = i
|
178 | 1 | akiss | xup[i,1] = measure_height(x_section[i,:])[1] |
179 | 1 | akiss | xdown[i,1] = measure_height(x_section[i,:])[0] |
180 | 1 | akiss | return xup, xdown
|
181 | 1 | akiss | |
182 | 1 | akiss | |
183 | 1 | akiss | def write_curve(y, pixelsize, filename) : |
184 | 1 | akiss | FILE = open(filename,"w") |
185 | 1 | akiss | FILE.write('# '+str(pixelsize[0])+' '+str(pixelsize[1])+'\n') |
186 | 1 | akiss | s = y.shape |
187 | 1 | akiss | #FILE.write('# '+str(s[0])+'\n')
|
188 | 1 | akiss | for i in range(0,s[0]) : |
189 | 1 | akiss | FILE.write(str(y[i,0])+' '+str(y[i,1])+'\n') |
190 | 1 | akiss | FILE.close() |
191 | 1 | akiss | return
|
192 | 1 | akiss | |
193 | 1 | akiss | |
194 | 1 | akiss | def struct_element_sphere(radius): |
195 | 1 | akiss | s=int(2*radius+1) |
196 | 1 | akiss | structure=np.zeros((s,s,s)) |
197 | 1 | akiss | center = np.array([radius, radius, radius]) |
198 | 1 | akiss | Nl=range(s)
|
199 | 1 | akiss | for i in Nl: |
200 | 1 | akiss | for j in Nl: |
201 | 1 | akiss | for k in Nl: |
202 | 1 | akiss | p=np.array([i,j,k]) |
203 | 1 | akiss | d=p-center |
204 | 1 | akiss | dist=np.sqrt(sum(d*d))
|
205 | 1 | akiss | if dist<=radius:
|
206 | 1 | akiss | structure[i,j,k]=1
|
207 | 1 | akiss | return structure
|
208 | 1 | akiss | |
209 | 1 | akiss | |
210 | 1 | akiss | def create_artificial_sepal(AA, RR, resolution): |
211 | 1 | akiss | # A = parameters of an ellipse, as projected on xy plane (2d array)
|
212 | 1 | akiss | # R = curvature radius in directions x and y (2d array)
|
213 | 1 | akiss | # (A and R are given in micrometers)
|
214 | 1 | akiss | # resolution = voxelsize of the output stack
|
215 | 1 | akiss | A = np.array([AA[i]/resolution[i] for i in [0,1]]) |
216 | 1 | akiss | R = np.array([RR[i]/resolution[i] for i in [0,1]]) |
217 | 1 | akiss | h = np.array([math.sqrt(R[i]**2-A[i]**2) for i in range(len(A))]) |
218 | 1 | akiss | zmax=np.array([R[i]-math.sqrt(R[i]**2-A[i]**2) for i in [0,1]]) |
219 | 1 | akiss | #zmax= int(math.sqrt(zmax[0]*zmax[1]))
|
220 | 1 | akiss | zmax=zmax.mean() |
221 | 1 | akiss | #zmax = 5
|
222 | 1 | akiss | print(zmax) |
223 | 1 | akiss | marge = 0.2
|
224 | 1 | akiss | # creating the stack and the surface
|
225 | 1 | akiss | s = (int(A[0]*2*(1+marge)), int(A[1]*2*(1+marge)), int(zmax*(1+2*marge))) |
226 | 1 | akiss | cm = np.array(s)/2
|
227 | 1 | akiss | x = np.array(range(0,s[0])) |
228 | 1 | akiss | y = np.array(range(0,s[1])) |
229 | 1 | akiss | xx = x - cm[0]
|
230 | 1 | akiss | yy = y - cm[1]
|
231 | 1 | akiss | #xgrid, ygrid = np.meshgrid(xx, yy, sparse=True) # make sparse output arrays
|
232 | 1 | akiss | #mask=(((xgrid**2)/float(A[0])**2+(ygrid**2)/float(A[1])**2)<1).astype('uint8')
|
233 | 1 | akiss | z = np.zeros((s[0],s[1])) |
234 | 1 | akiss | stack= np.zeros(s).astype('uint8')
|
235 | 1 | akiss | for i in x: |
236 | 1 | akiss | for j in range(0,s[1]): |
237 | 1 | akiss | if xx[i]**2/float(A[0])**2+yy[j]**2/float(A[1])**2<=1 : |
238 | 1 | akiss | zx = (math.sqrt(R[0]**2-xx[i]**2)-h[0])*(1-abs(yy[j])/A[1]) |
239 | 1 | akiss | zy = (math.sqrt(R[1]**2-yy[j]**2)-h[1])*(1-abs(xx[i])/A[0]) |
240 | 1 | akiss | z[i,j] = math.sqrt(zx*zy) |
241 | 1 | akiss | #z[i,j] = (zx+zy)/2
|
242 | 1 | akiss | #z[i,j] = 5
|
243 | 1 | akiss | stack[i,j,int(zmax*marge+z[i,j])]=1 |
244 | 1 | akiss | stack = SpatialImage(stack) |
245 | 1 | akiss | stack.resolution = resolution |
246 | 1 | akiss | return z, stack
|
247 | 1 | akiss | |
248 | 1 | akiss | |
249 | 1 | akiss | |
250 | 1 | akiss | def create_artificial_sepal_ellipse(AA, H, resolution): |
251 | 1 | akiss | '''
|
252 | 1 | akiss | # A = parameters of an ellipse, as projected on xy plane (2d array)
|
253 | 1 | akiss | # R = curvature radius in directions x and y (2d array)
|
254 | 1 | akiss | # (A and R are given in micrometers)
|
255 | 1 | akiss | # resolution = voxelsize of the output stack
|
256 | 1 | akiss | '''
|
257 | 1 | akiss | A = np.array([AA[i]/resolution[i] for i in [0,1]]) |
258 | 1 | akiss | h = H/resolution[2]
|
259 | 1 | akiss | zmax=h |
260 | 1 | akiss | marge = 0.2
|
261 | 1 | akiss | # creating the stack and the surface
|
262 | 1 | akiss | s = (int(A[0]*2*(1+marge)), int(A[1]*2*(1+marge)), int(zmax*(1+5*marge))) |
263 | 1 | akiss | cm = np.array(s)/2
|
264 | 1 | akiss | x = np.array(range(0,s[0])) |
265 | 1 | akiss | y = np.array(range(0,s[1])) |
266 | 1 | akiss | xx = x - cm[0]
|
267 | 1 | akiss | yy = y - cm[1]
|
268 | 1 | akiss | #xgrid, ygrid = np.meshgrid(xx, yy, sparse=True) # make sparse output arrays
|
269 | 1 | akiss | #mask=(((xgrid**2)/float(A[0])**2+(ygrid**2)/float(A[1])**2)<1).astype('uint8')
|
270 | 1 | akiss | z = np.zeros((s[0],s[1])) |
271 | 1 | akiss | #z = -h*((xgrid**2)/float(A[0])**2+(ygrid**2)/float(A[1])**2)
|
272 | 1 | akiss | stack= np.zeros(s).astype('uint8')
|
273 | 1 | akiss | for i in x: |
274 | 1 | akiss | for j in y: |
275 | 1 | akiss | if xx[i]**2/float(A[0])**2+yy[j]**2/float(A[1])**2<=1 : |
276 | 1 | akiss | z[i,j] = -h*((xx[i]**2)/float(A[0])**2+(yy[j]**2)/float(A[1])**2-1) |
277 | 1 | akiss | stack[i,j,int(zmax*4*marge+z[i,j])]=1 |
278 | 1 | akiss | stack = SpatialImage(stack) |
279 | 1 | akiss | stack.voxelsize = resolution |
280 | 1 | akiss | return z, stack
|
281 | 1 | akiss | |
282 | 1 | akiss | # -------------------------------------------------------------------
|
283 | 1 | akiss | |
284 | 1 | akiss | def read_curve(filename) : |
285 | 1 | akiss | """
|
286 | 1 | akiss | Reads the coordinates of the point-list defining a 2D curve.
|
287 | 1 | akiss | **Returns**
|
288 | 1 | akiss | y : 2-column array
|
289 | 1 | akiss | defines a curve as an ordered list of points,
|
290 | 1 | akiss | each row of the array represents a point on the curve and contains
|
291 | 1 | akiss | its 2D cartesian coordinates
|
292 | 1 | akiss | pixelsize : tuple (res0, res1) in micrometers
|
293 | 1 | akiss | """
|
294 | 1 | akiss | x0 = [] |
295 | 1 | akiss | pixelsize = (1.0,1.0) |
296 | 1 | akiss | for line in file(filename): |
297 | 1 | akiss | if line[0] == "#" : |
298 | 1 | akiss | line = line.lstrip('# ')
|
299 | 1 | akiss | line = line.rstrip('\n')
|
300 | 1 | akiss | line_list = [float(x) for x in line.split(' ')] |
301 | 1 | akiss | pixelsize = (line_list[0], line_list[1]) |
302 | 1 | akiss | else :
|
303 | 1 | akiss | line = line.rstrip('\n')
|
304 | 1 | akiss | line_list = [float(x) for x in line.split(' ')] |
305 | 1 | akiss | x0.append(line_list) |
306 | 1 | akiss | y = np.array(x0) |
307 | 1 | akiss | return y, pixelsize
|
308 | 1 | akiss | |
309 | 1 | akiss | |
310 | 1 | akiss | |
311 | 1 | akiss | def distance(p1, p2): |
312 | 1 | akiss | return np.sqrt((p1[0]-p2[0])**2+(p1[1]-p2[1])**2) |
313 | 1 | akiss | |
314 | 1 | akiss | def distance_to_line(p1, p2, p0): |
315 | 1 | akiss | '''
|
316 | 1 | akiss | gives the distance of point p0 to the line defined by points p1 and p2 (in 2d)
|
317 | 1 | akiss | '''
|
318 | 1 | akiss | 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 | 1 | akiss | |
320 | 1 | akiss | def curvature(p1,p2,p3): |
321 | 1 | akiss | t1 = (p3[0]**2-p2[0]**2+p3[1]**2-p2[1]**2)/(2.0*(p3[1]-p2[1])) |
322 | 1 | akiss | t2 = (p2[0]**2-p1[0]**2+p2[1]**2-p1[1]**2)/(2.0*(p2[1]-p1[1])) |
323 | 1 | akiss | n1 = (p3[0]-p2[0])/(p3[1]-p2[1]) |
324 | 1 | akiss | n2 = (p2[0]-p1[0])/(p2[1]-p1[1]) |
325 | 1 | akiss | pcx = (t1-t2+p3[1]-p1[1])/(n1-n2) |
326 | 1 | akiss | pc = [pcx, -n1*pcx+t1/2+p3[1]/2+p1[1]/2] |
327 | 1 | akiss | R = distance(p1, pc) |
328 | 1 | akiss | return 1.0/R, pc |
329 | 1 | akiss | |
330 | 1 | akiss | |
331 | 1 | akiss | def curvature2(p1,p2,p3): |
332 | 1 | akiss | # http://www.ambrsoft.com/TrigoCalc/Circle3D.htm
|
333 | 1 | akiss | A = p1[0]*(p2[1]-p3[1])-p1[1]*(p2[0]-p3[0])+p2[0]*p3[1]-p3[0]*p2[1] |
334 | 1 | akiss | 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 | 1 | akiss | 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 | 1 | akiss | 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 | 1 | akiss | x = -B/(2*A)
|
338 | 1 | akiss | y = C/(2*A)
|
339 | 1 | akiss | pc = [x, y] |
340 | 1 | akiss | R = distance(p1, pc) |
341 | 1 | akiss | return 1.0/R, pc |
342 | 1 | akiss | |
343 | 1 | akiss | |
344 | 1 | akiss | def curve_perle(y, first, last, step): |
345 | 1 | akiss | yy=[] |
346 | 1 | akiss | for i in range(first, last, step): |
347 | 1 | akiss | if y[i][1]>0: |
348 | 1 | akiss | yy.append(y[i]) |
349 | 1 | akiss | if i<last:
|
350 | 1 | akiss | yy.append(y[last]) |
351 | 1 | akiss | return np.array(yy)
|
352 | 1 | akiss | |
353 | 1 | akiss | |
354 | 1 | akiss | |
355 | 1 | akiss | def compute_curvature_radius(x,y): |
356 | 1 | akiss | # coordinates of the barycenter
|
357 | 1 | akiss | x_m = np.mean(x) |
358 | 1 | akiss | y_m = np.mean(y) |
359 | 1 | akiss | def calc_R(c): |
360 | 1 | akiss | """ calculate the distance of each 2D points from the center c=(xc, yc) """
|
361 | 1 | akiss | return np.sqrt((x-c[0])**2 + (y-c[1])**2) |
362 | 1 | akiss | #
|
363 | 1 | akiss | def calc_ecart(c): |
364 | 1 | akiss | """ calculate the algebraic distance between the 2D points and the mean circle centered at c=(xc, yc) """
|
365 | 1 | akiss | Ri = calc_R(c) |
366 | 1 | akiss | return Ri - Ri.mean()
|
367 | 1 | akiss | #
|
368 | 1 | akiss | center_estimate = x_m, y_m |
369 | 1 | akiss | center_2, ier = optimize.leastsq(calc_ecart, center_estimate) |
370 | 1 | akiss | #
|
371 | 1 | akiss | xc_2, yc_2 = center_2 |
372 | 1 | akiss | Ri_2 = calc_R(center_2) |
373 | 1 | akiss | R_2 = Ri_2.mean() |
374 | 1 | akiss | residu_2 = sum((Ri_2 - R_2)**2) |
375 | 1 | akiss | pc=[xc_2, yc_2] |
376 | 1 | akiss | return R_2, pc
|
377 | 1 | akiss | |
378 | 1 | akiss | |
379 | 1 | akiss | def analyze_curve1(name, y, pixelsize, outfilename, graph_name='graph.png'): |
380 | 1 | akiss | # isotropic pixels
|
381 | 1 | akiss | y[:,0] = y[:,0]*pixelsize[0] |
382 | 1 | akiss | y[:,1] = y[:,1]*pixelsize[1] |
383 | 1 | akiss | maxv = [y[:,i].max() for i in [0,1]] |
384 | 1 | akiss | # find first and last points on the curve
|
385 | 1 | akiss | step = 5
|
386 | 1 | akiss | sep_indices = np.where(y[:,1])[0] |
387 | 1 | akiss | first = sep_indices[0]#+step/2 |
388 | 1 | akiss | last = sep_indices[-1]#-step/2 |
389 | 1 | akiss | # compute flat length
|
390 | 1 | akiss | flatlength = distance(y[first],y[last]) |
391 | 1 | akiss | print("flat length =", flatlength," um") |
392 | 1 | akiss | # compute curved length and height (maximal distance to the base)
|
393 | 1 | akiss | yy = curve_perle(y, first, last, step) |
394 | 1 | akiss | length = 0
|
395 | 1 | akiss | height = 0
|
396 | 1 | akiss | height_index = 0
|
397 | 1 | akiss | p1 = yy[0]
|
398 | 1 | akiss | p2 = yy[-1]
|
399 | 1 | akiss | for i in range(0, len(yy)-1): |
400 | 1 | akiss | length = length + distance(yy[i+1],yy[i])
|
401 | 1 | akiss | d = distance_to_line(p1, p2, yy[i]) |
402 | 1 | akiss | if d>height :
|
403 | 1 | akiss | height = d |
404 | 1 | akiss | height_index = i |
405 | 1 | akiss | print("length = ",length," um") |
406 | 1 | akiss | print("height = ",height," um") |
407 | 1 | akiss | middle_point = yy[int(len(yy)/2)] |
408 | 1 | akiss | # compute curvature radius by fitting the sepal section to a circle
|
409 | 1 | akiss | yyy=y[first:last] |
410 | 1 | akiss | R, pc = compute_curvature_radius(yyy[:,0],yyy[:,1]) |
411 | 1 | akiss | print("R=",R," um") |
412 | 1 | akiss | # cutting curve in pieces in order to estimate curvature radius on portions of the curve
|
413 | 1 | akiss | slength=len(yyy)
|
414 | 1 | akiss | y21=yyy[0:int(slength/2)] |
415 | 1 | akiss | y22=yyy[int(slength/2):slength] |
416 | 1 | akiss | y41=yyy[0:int(slength/4)] |
417 | 1 | akiss | y423=yyy[int(slength/4):3*int(slength/4)] |
418 | 1 | akiss | y44=yyy[3*int(slength/4):slength] |
419 | 1 | akiss | # and computing the curvature radius for each portion
|
420 | 1 | akiss | R21, pc = compute_curvature_radius(y21[:,0],y21[:,1]) |
421 | 1 | akiss | R22, pc = compute_curvature_radius(y22[:,0],y22[:,1]) |
422 | 1 | akiss | R41, pc = compute_curvature_radius(y41[:,0],y41[:,1]) |
423 | 1 | akiss | R423, pc = compute_curvature_radius(y423[:,0],y423[:,1]) |
424 | 1 | akiss | R44, pc = compute_curvature_radius(y44[:,0],y44[:,1]) |
425 | 1 | akiss | fig = plt.figure() |
426 | 1 | akiss | plt.plot(yy[:,0], yy[:,1], 'bo') |
427 | 1 | akiss | plt.plot(y[:,0], y[:,1], 'r') |
428 | 1 | akiss | plt.plot(y[first][0], y[first][1], 'ro') |
429 | 1 | akiss | plt.plot(middle_point[0], middle_point[1], 'ro') |
430 | 1 | akiss | plt.plot(y[last][0], y[last][1], 'ro') |
431 | 1 | akiss | plt.plot(yy[height_index][0], yy[height_index][1], 'go') |
432 | 1 | akiss | plt.plot(pc[0], pc[1], 'bx') |
433 | 1 | akiss | plt.gca().set_aspect('equal', adjustable='box') |
434 | 1 | akiss | #plt.show()
|
435 | 1 | akiss | fig.savefig(graph_name) |
436 | 1 | akiss | #plt.close()
|
437 | 1 | akiss | # write the data into a file
|
438 | 1 | akiss | FILE = open(outfilename,"a") |
439 | 1 | akiss | FILE.write(name+';'+str(length)+';'+str(R)+';'+str(flatlength)+';'+str(height)+'\n') |
440 | 1 | akiss | FILE.close() |
441 | 1 | akiss | return length, flatlength, height, R, R21, R22, R41, R423, R44
|
442 | 1 | akiss | |
443 | 1 | akiss | def imsave2D(filename, matrix): |
444 | 1 | akiss | fig = plt.figure() |
445 | 1 | akiss | plt.gca().imshow(np.transpose(matrix), interpolation='none')
|
446 | 1 | akiss | fig.savefig(filename) |
447 | 1 | akiss | return |