comparison ReMarker.py @ 15:60ed96f5706e draft

Uploaded
author mb2013
date Tue, 20 May 2014 03:28:59 -0400
parents
children
comparison
equal deleted inserted replaced
14:70fc3c02ca14 15:60ed96f5706e
1 #Program for correcting landmarks.
2 #The object will be rotated, based on 3 symmetry points.
3 #The differences between the mirror points will be calculated and
4 # the coordinates will be corrected where needed.
5
6 #MB
7
8 import math
9 from math import *
10 import sys
11 import numpy
12 import os
13
14 # Main function
15 def main():
16 file_name = sys.argv[1] # dta file
17 file_connect = sys.argv[2] # connect file
18 side = sys.argv[3] # correct side of object
19
20 file_outputname5 = sys.argv[5] # output dta file
21 output5 = open(file_outputname5, 'w')
22
23 # to function 'open connect file'
24 sym1,sym2,sym3, listmirror, listspec = open_connect_file(file_connect)
25
26 # to function 'open dta file'
27 listdata = open_dta_file(file_name, output5)
28
29 # to function 'shift to zero'
30 shift_to_zero(listdata,sym1,sym2,sym3,listmirror,listspec, side, output5)
31
32 # Function for extracting values of connect file
33 def open_connect_file(file_connect):
34 mirrorpoints = open(file_connect)
35 lines= mirrorpoints.readlines()
36 listmirror = [] #with mirror points
37 listsym = [] #with symmetry points
38 listspec = [] #with spec points
39
40 #extracting symmetry landmarks and mirror landmarks of connect file
41 for x in range(0, len(lines)):
42 line = lines[x].strip()
43 if line == 'sym': # extract points on symmetry plane
44 for a in range(1,4):
45 listsym.append(lines[a].strip().split())
46 if line == 'mirror': # extract mirror points
47 for y in range(x + 1,len(lines)):
48 try:
49 if lines[y].strip() != 'spec':
50 if lines[y].strip() == '':
51 break
52 else:
53 listmirror.append(lines[y].strip().split()) # add mirror points
54
55 else:
56 break
57
58 except:
59 break
60 if line == 'spec':# if specs are present
61 for b in range(x+1, len(lines)):
62 listspec.append(lines[b].strip().split()) # add points in specs
63 #Symmetry points
64 sym1 = int(listsym[0][0]) -1
65 sym2 = int(listsym[1][0]) -1
66 sym3 = int(listsym[2][0]) -1
67
68 mirrorpoints.close()
69 return sym1, sym2, sym3, listmirror, listspec
70
71 # Function open .dta file
72 def open_dta_file(file_name, output5):
73 datapoints = open(file_name)#open file
74 datalines = datapoints.readlines()
75 listdata = [] # landmarklist
76 listdta = [] # coordinates
77 sublist = [] # sublist
78 for a in range(0,len(datalines)):
79 aline = datalines[a].strip()
80 listdta.append(datalines[a].strip().split(' ')) # notice space
81
82 #numbers in dta file to list
83 if len(listdta[a]) == 3:
84 sublist.append(float(listdta[a][0]))
85 sublist.append(float(listdta[a][1]))
86 sublist.append(float(listdta[a][2]))
87 listdata.append(sublist)
88 sublist = []
89
90 #write header of dta file to outputfile
91 else:
92 output5.write("%s\n"%(aline))
93
94 datapoints.close()
95 return listdata
96
97 # Function to calculate the values in the Z rotation matrix
98 def Rz_matrix(z_angle): # Rz rotation matrix
99 return [[cos(math.radians(z_angle)), -sin(math.radians(z_angle)), 0.0],[sin(math.radians(z_angle)),cos(math.radians(z_angle)),0.0],[0.0, 0.0, 1.0]]
100
101 # Function to calculate the new coordinates rotated with Z rotation matrix
102 def Z_rotation(point2, z_angle): # multiplication rotation matrix and coordinates
103 r_z = Rz_matrix(z_angle)
104 rotated_z = []
105 for i in range(3):
106 rotated_z.append((sum([r_z[i][j] * point2[j] for j in range(3)])))
107 return rotated_z
108
109 # Function to calculate the values in the X rotation matrix
110 def Rx_matrix(x_angle): #rotation matrix x-axis
111 return [[1, 0, 0],[0,cos(math.radians(x_angle)),-sin(math.radians(x_angle))],[0,sin(math.radians(x_angle)),cos(math.radians(x_angle))]]
112
113 # Function to calculate the new coordinates rotated with X rotation matrix
114 def X_rotation(point3, x_angle): #multiplication rotation matrix and coordinates
115 r_x = Rx_matrix(x_angle)
116 rotated_x = []
117 for i in range(3):
118 rotated_x.append((sum([r_x[i][j] * point3[j] for j in range(3)])))
119 return rotated_x
120
121 # Function to calculate the values in the Y rotation matrix
122 def Ry_matrix(y_angle): # Ry rotation matrix
123 return [[cos(math.radians(y_angle)), 0.0, sin(math.radians(y_angle))],[0.0, 1.0, 0.0],[-sin(math.radians(y_angle)),0.0, cos(math.radians(y_angle))]]
124
125 # Function to calculate the new coordinates rotated with Y rotation matrix
126 def Y_rotation(point4, y_angle): #multiplication rotation matrix and coordinates
127 r_y = Ry_matrix(y_angle)
128 rotated_y = []
129 for i in range(3):
130 rotated_y.append((sum([r_y[i][j] * point4[j] for j in range(3)])))
131 return rotated_y
132
133 # Function shift object to zeropoint
134 def shift_to_zero(listdata, sym1,sym2,sym3, listmirror, listspec, side,output5):
135 # shifting object that sym3 point will be the zeropoint #
136 zeropoint = int(sym3)
137 co_zeropoint = listdata[zeropoint] #coordinates of sym3
138
139 listdata2 = []
140 listdata3 = []
141
142 # minus x,y,z of point shift to zeropoint of every point
143 for x in range(0,len(listdata)):
144 listdata2.append(listdata[x][0] - co_zeropoint[0])
145 listdata2.append(listdata[x][1] - co_zeropoint[1])
146 listdata2.append(listdata[x][2] - co_zeropoint[2])
147 listdata3.append(listdata2)
148 listdata2 = []
149 rotate_z_axis(listdata3,sym1,sym2,sym3, listmirror, listspec, side, output5)
150
151
152 # Function for rotating the object around z axis
153 def rotate_z_axis(listdata3, sym1,sym2,sym3, listmirror, listspec, side, output5):
154 # If object is upside down, 180 degrees rotation around the Z axis is needed.#
155 listdatatemp = []
156
157 if listdata3[sym1][1] < listdata3[sym3][1]:
158 angle = 180
159 for coordinates in range(0,len(listdata3)):
160 listdatatemp.append(Z_rotation(listdata3[coordinates], angle))
161 listdata3 = listdatatemp
162
163
164 # calculate angle rotation z
165 len_z_a = listdata3[int(sym1)][0] - listdata3[int(sym3)][0]
166 len_z_b = listdata3[int(sym1)][1] - listdata3[int(sym3)][1]
167 z_angle = (math.degrees(math.atan(len_z_a/len_z_b)))
168
169 # calculate new coordinates with rotation matrix of Z
170 listdata4 = []
171 for coordinates in range(0, len(listdata3)):
172 listdata4.append(Z_rotation(listdata3[coordinates], z_angle))
173
174 rotate_x_axis(listdata4,sym1,sym2,sym3, listmirror, listspec, side, output5)
175
176 # Function for rotating the object around x axis
177 def rotate_x_axis(listdata4,sym1,sym2,sym3, listmirror, listspec, side, output5):
178 #calculate angle rotation x
179 len_x_a = listdata4[int(sym1)][2] - listdata4[int(sym3)][0]
180 len_x_b = listdata4[int(sym1)][1] - listdata4[int(sym3)][0]
181 x_angle = -(math.degrees(math.atan(len_x_a/len_x_b)))
182
183 # calculate new coordinates with rotation matrix of X
184 listdata5 = []
185 for d in range(0, len(listdata4)):
186 listdata5.append(X_rotation(listdata4[d], x_angle))
187
188 rotate_y_axis(listdata5,sym1,sym2,sym3, listmirror, listspec, side, output5)
189
190 # Function for rotating the object around y axis
191 def rotate_y_axis(listdata5,sym1,sym2,sym3,listmirror, listspec, side, output5):
192 #calculate angle rotation y
193 len_y_a = (listdata5[int(sym2)][0] - listdata5[int(sym3)][0])
194 len_y_b = (listdata5[int(sym2)][2] - listdata5[int(sym3)][2])
195 y_angle = -(math.degrees(math.atan(len_y_a/len_y_b)))
196
197 # calculate new coordinates with rotation matrix of Y
198 listdata6 = []
199 for d in range(0, len(listdata5)):
200 listdata6.append(Y_rotation(listdata5[d], y_angle))
201
202
203 #Rotate 180 degrees around y axis when object is backwards.#
204 listdatatemp = []
205 if listdata6[sym2][0] < listdata6[(int(listmirror[0][0]))][0]: #point sym2_x < point mirror 1_x
206 angle = 180
207 for coordinates in range(0,len(listdata6)):
208 listdatatemp.append(Y_rotation(listdata6[coordinates], angle))
209 listdata6 = listdatatemp
210 write_rotate_co(listdata6)
211
212 # to correcting the landmarks
213 if len(listspec) == 0:
214 correct_landmarks(listdata6, listmirror, side, output5)
215 else:
216 correct_specs(listdata6, listmirror, listspec, output5)
217
218 # Function writing rotated coordinates to file
219 def write_rotate_co(listdata6):
220 file_outputname4 = sys.argv[4]
221 output4 = open(file_outputname4, 'w')
222 #writing new coordinates to outputfile
223 for x in range(0,len(listdata6)):
224 output4.write("%.7f\t%.7f\t%.7f\n"%(listdata6[x][0], listdata6[x][1], listdata6[x][2]))
225
226 #Function for correcting the landmarks
227 def correct_landmarks(listdata6, listmirror, side,output5):
228
229 percentage_distance = []
230 #calculate marge of distance
231 for x in range(0,len(listmirror)):
232 left = listmirror[x][0] #left landmark
233 right = listmirror[x][1] #right landmark
234 co_left = listdata6[int(left)-1] #left landmark coordinates
235 co_left_x = co_left[0] # left landmark coordinate x
236 co_right = listdata6[int(right)-1]#right landmark coordinates
237 co_right_x = co_right[0] #right landmark coordinate x
238 distance_x = float(co_left[0]) + float(co_right[0])
239
240 # if left is correct
241 if int(side) == 0:
242 percentage_distance.append(abs(distance_x) / abs(co_left_x)) #percentage
243
244 # if right is correct
245 elif int(side) == 1:
246 percentage_distance.append(abs(distance_x) / abs(co_right_x)) #percentage
247 else:
248 print 'something wrong'
249
250
251 mean_percentage = numpy.mean(percentage_distance) #mean of percentages
252 std_percentage = numpy.std(percentage_distance)
253 #range of correct values
254 left_range = mean_percentage - std_percentage #left range mean minus one standard deviation
255 right_range = mean_percentage + std_percentage # rigth range mean plus one standard deviation
256
257 #correcting the landmarks coordinates#
258 for x in range(0,len(listmirror)):
259 left = listmirror[x][0]
260 right = listmirror[x][1]
261 co_left = listdata6[int(left)-1]
262 co_right = listdata6[int(right)-1]
263 #if there is to much deviation take correct coordinate and project it to the other side.
264 if (percentage_distance[x] > right_range) or (percentage_distance[x] < left_range):
265
266 #if left side is correct
267 if int(side) == 0:
268 listdata6[int(right)-1][0] = float(co_left[0]) * -1
269 listdata6[int(right)-1][1] = float(co_left[1])
270 listdata6[int(right)-1][2] = float(co_left[2])
271 #if right side is correct
272 if int(side) == 1:
273 listdata6[int(left)-1][0] = float(co_right[0]) * -1
274 listdata6[int(left)-1][1] = float(co_right[1])
275 listdata6[int(left)-1][2] = float(co_right[2])
276 write_output(listdata6,output5)
277
278 #Function for correcting landmarks, defined in specs
279 def correct_specs(listdata6, listmirror, listspec,output5):
280 for x in range(0,len(listspec)):
281 number = listspec[x][0]
282 for spec in range(0, len(listmirror)):
283 try:
284 pos = listmirror[spec].index(number) #find number in mirror list
285 #extracting the opposite landmark number
286 if pos == 0:
287 number2 = listmirror[spec][1]
288 elif pos == 1 :
289 number2 = listmirror[spec][0]
290 else:
291 print 'wrong'
292 #replace the wrong coordinates
293 listdata6[int(number)-1][0] = float(listdata6[int(number2)-1][0])*-1
294 listdata6[int(number)-1][1] = float(listdata6[int(number2)-1][1])
295 listdata6[int(number)-1][2] = float(listdata6[int(number2)-1][2])
296 except:
297 continue
298 write_output(listdata6,output5)
299
300 #Function for writing the corrected landmarks to outputfile
301 def write_output(listdata6,output5):
302
303 for x in range(0,len(listdata6)):
304 output5.write("%.7f %.7f %.7f\n"%(listdata6[x][0], listdata6[x][1], listdata6[x][2]))
305 output5.close()
306 main()