Statistiques
| Révision :

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