1919import numpy as np
2020import pyvista as pv
2121import matplotlib .pyplot as plt
22- import matplotlib
22+ import matplotlib as mpl
2323import random
24+ import pyransac3d as pyrsc
2425
2526""" parametres du noeuds ROS, à mettre dans un fichier de config a la fin"""
2627basic_limit_for_reflexions = 12
@@ -42,6 +43,12 @@ class PointCloudProcessingNode(Node):
4243 def __init__ (self ):
4344 """PointCloudProcessingNode class constructor."""
4445 super ().__init__ ('point_cloud_processing_node' )
46+ self .xinf = - 100000
47+ self .xsup = 100000
48+ self .x1 = - 100000
49+ self .x2 = 100000
50+ self .y1 = - 100000
51+ self .y2 = 100000
4552
4653 def load_scan (self ,fileName ):
4754 data = np .squeeze (np .load (fileName ))
@@ -53,13 +60,7 @@ def load_scan(self,fileName):
5360 data [i ,j ,1 ] = i * 0.3
5461 return data
5562
56- def decimate_point_cloud (self ,inputPointCloud ,decimationRate ):
57- shapes = inputPointCloud .shape
58- interPointCloud = self .flatten_point_cloud (inputPointCloud )
59- indexList = [i for i in range (0 ,interPointCloud .shape [0 ])]
60- deletedElementsIndex = random .sample (indexList ,int (len (indexList )* decimationRate ))
61- outputPointCloud = np .delete (interPointCloud , deletedElementsIndex ,axis = 0 )
62- return outputPointCloud
63+
6364
6465 def flatten_point_cloud (self ,inputPointCloud ):
6566 if len (inputPointCloud .shape ) == 2 :
@@ -68,16 +69,25 @@ def flatten_point_cloud(self,inputPointCloud):
6869 outputPointCloud = np .reshape (inputPointCloud ,(inputPointCloud .shape [0 ]* inputPointCloud .shape [1 ],inputPointCloud .shape [2 ]))
6970 return outputPointCloud
7071
71- def filter_point_cloud (self ,inputPointCloud ):
72+ def remove_non_used_plate_points (self ,inputPointCloud ):
7273 treatedPointCloud = self .remove_inf_value (inputPointCloud )
7374 shapes = treatedPointCloud .shape
7475 savedPoints = []
7576 for i in range (0 ,shapes [0 ]):
76- if treatedPointCloud [i ,0 ]> self .filter_coordinates [ 0 ][ 0 ] and treatedPointCloud [i ,0 ]< self .filter_coordinates [ 1 ][ 0 ] and treatedPointCloud [ i , 1 ] > self . filter_coordinates [ 0 ][ 1 ] and treatedPointCloud [ i , 1 ] < self . filter_coordinates [ 1 ][ 1 ] :
77+ if treatedPointCloud [i ,0 ]> self .xinf and treatedPointCloud [i ,0 ]< self .xsup :
7778 savedPoints .append (treatedPointCloud [i ,:])
7879 savedPoints = np .array (savedPoints )
79- self .plot_point_cloud (savedPoints )
80- return 0
80+ return savedPoints
81+
82+ def select_layer_points (self ,inputPointCloud ):
83+ treatedPointCloud = self .remove_inf_value (inputPointCloud )
84+ shapes = treatedPointCloud .shape
85+ savedPoints = []
86+ for i in range (0 ,shapes [0 ]):
87+ if treatedPointCloud [i ,0 ]> self .x1 and treatedPointCloud [i ,0 ]< self .x2 and treatedPointCloud [i ,1 ]> self .y1 and treatedPointCloud [i ,1 ]< self .y2 :
88+ savedPoints .append (treatedPointCloud [i ,:])
89+ savedPoints = np .array (savedPoints )
90+ return savedPoints
8191
8292 def remove_inf_value (self ,inputPointCloud ):
8393 inputPointCloud = self .flatten_point_cloud (inputPointCloud )
@@ -88,6 +98,15 @@ def remove_inf_value(self,inputPointCloud):
8898 outputPointCloud .append (inputPointCloud [i ,:])
8999 return np .array (outputPointCloud )
90100
101+ def remove_value_above (self ,inputPointCloud ,threshold ):
102+ inputPointCloud = self .flatten_point_cloud (inputPointCloud )
103+ shapes = inputPointCloud .shape
104+ outputPointCloud = []
105+ for i in range (0 ,shapes [0 ]):
106+ if inputPointCloud [i ,2 ]< threshold :
107+ outputPointCloud .append (inputPointCloud [i ,:])
108+ return np .array (outputPointCloud )
109+
91110 def plot_point_cloud (self ,inputPointCloud ):
92111 data = self .remove_inf_value (inputPointCloud )
93112 data = self .decimate_point_cloud (data , 0.95 )
@@ -97,7 +116,7 @@ def plot_point_cloud(self,inputPointCloud):
97116
98117 fig = plt .figure (figsize = (8 , 8 ))
99118 ax = fig .add_subplot (111 , projection = '3d' ,aspect = 'auto' )
100- im = ax .scatter (x , y , z , c = z )
119+ im = ax .scatter (x , y , z , c = z , cmap = mpl . colormaps [ 'jet' ] )
101120 plt .xlabel ('x (mm)' )
102121 plt .ylabel ('y (mm)' )
103122 fig .colorbar (im )
@@ -106,8 +125,104 @@ def plot_point_cloud(self,inputPointCloud):
106125 ax .set_zlim (min ([min (x ), min (y ), min (z )]), max ([max (x ), max (y ), max (z )]))
107126 plt .show ()
108127 return 0
128+
129+ def barycentre_calculation (self ,layer_point_cloud ):
130+ self .xg = 0
131+ self .yg = 0
132+ layerShape = layer_point_cloud .shape
133+ for i in range (0 ,layerShape [0 ]):
134+ self .xg += layer_point_cloud [i ][0 ]
135+ self .yg += layer_point_cloud [i ][1 ]
136+ self .xg /= layerShape [0 ]
137+ self .yg /= layerShape [0 ]
138+ return 0
139+
140+ def transformation_creation (self ,plate_point_cloud ):
141+ self .rotation_matrix = np .zeros ((3 ,3 ))
142+ self .translation_matrix = np .array ([0 , 0 , 0 ])
143+
144+ plane1 = pyrsc .Plane ()
145+ best_eq , best_inliers = plane1 .fit (plate_point_cloud , 0.01 )
146+ if best_eq [3 ] > 0 :
147+ best_eq [3 ] = - best_eq [3 ]
148+
149+ if best_eq [2 ]< 0 :
150+ self .rotation_matrix [2 ,0 ] = - best_eq [0 ]
151+ self .rotation_matrix [2 ,1 ] = - best_eq [1 ]
152+ self .rotation_matrix [2 ,2 ] = - best_eq [2 ]
153+ self .translation_matrix [2 ] = best_eq [3 ]
154+ self .zVector = best_eq [0 :3 ]
155+ self .zVector [0 ] = - self .zVector [0 ]
156+ self .zVector [1 ] = - self .zVector [1 ]
157+ self .zVector [2 ] = - self .zVector [2 ]
158+ else :
159+ self .rotation_matrix [2 ,0 ] = best_eq [0 ]
160+ self .rotation_matrix [2 ,1 ] = best_eq [1 ]
161+ self .rotation_matrix [2 ,2 ] = best_eq [2 ]
162+ self .translation_matrix [2 ] = best_eq [3 ]
163+ self .zVector = best_eq [0 :3 ]
164+
165+ self .xVector = plate_point_cloud [10 ,:]- plate_point_cloud [0 ,:]
166+ self .xVector /= np .sqrt (self .xVector [0 ]** 2 + self .xVector [1 ]** 2 + self .xVector [2 ]** 2 )
167+
168+ self .yVector = [0 , 0 , 0 ]
169+
170+ self .yVector [0 ] = self .zVector [1 ]* self .xVector [2 ] - self .zVector [2 ]* self .xVector [1 ]
171+ self .yVector [1 ] = self .zVector [2 ]* self .xVector [0 ] - self .zVector [0 ]* self .xVector [2 ]
172+ self .yVector [2 ] = self .zVector [0 ]* self .xVector [1 ] - self .zVector [1 ]* self .xVector [0 ]
173+
174+ self .rotation_matrix [0 ,0 ] = self .xVector [0 ]
175+ self .rotation_matrix [0 ,1 ] = self .xVector [1 ]
176+ self .rotation_matrix [0 ,2 ] = self .xVector [2 ]
177+
178+ self .rotation_matrix [1 ,0 ] = self .yVector [0 ]
179+ self .rotation_matrix [1 ,1 ] = self .yVector [1 ]
180+ self .rotation_matrix [1 ,2 ] = self .yVector [2 ]
181+
182+ return 0
183+
184+ def tranform_point_cloud (self ,inputPointCloud ):
185+ outputPointCloud = np .zeros (inputPointCloud .shape )
186+
187+ inputShape = inputPointCloud .shape
188+ for i in range (0 ,inputShape [0 ]):
189+ outputPointCloud [i ,:] = np .dot (self .rotation_matrix , inputPointCloud [i ,:]) - self .translation_matrix
190+
191+ return outputPointCloud
192+
193+ def decimate_point_cloud (self ,inputPointCloud ,decimationRate ):
194+ shapes = inputPointCloud .shape
195+ interPointCloud = self .flatten_point_cloud (inputPointCloud )
196+ indexList = [i for i in range (0 ,interPointCloud .shape [0 ])]
197+ deletedElementsIndex = random .sample (indexList ,int (len (indexList )* decimationRate ))
198+ outputPointCloud = np .delete (interPointCloud , deletedElementsIndex ,axis = 0 )
199+ return outputPointCloud
200+
201+ def ask_for_plate_limits (self ,inputPointCloud ):
202+ data = self .remove_inf_value (inputPointCloud )
203+ data = self .decimate_point_cloud (data , 0.95 )
204+ x = data [:,0 ]
205+ y = data [:,1 ]
206+ z = data [:,2 ]
207+ fig = plt .figure (figsize = (8 , 8 ))
208+ ax = fig .add_subplot (111 ,aspect = 'equal' )
209+ im = ax .scatter (x , y , c = z ,s = 1 )
210+ plt .xlabel ('x (mm)' )
211+ plt .ylabel ('y (mm)' )
212+ fig .colorbar (im )
213+ ax .set_xlim (min (x )- 10 , max (x )+ 10 )
214+ ax .set_ylim (min (y )- 10 , max (y )+ 10 )
215+ cid = fig .canvas .mpl_connect ('button_press_event' , onclick )
216+ plt .show ()
217+ global coords
218+ self .xinf = coords [0 ][0 ]
219+ self .xsup = coords [1 ][0 ]
220+ self .get_logger ().info ("xinf : " + str (self .xinf ))
221+ self .get_logger ().info ("xsup : " + str (self .xsup ))
222+ coords = []
223+ return 0
109224
110- def ask_for_limits (self ,inputPointCloud ):
225+ def ask_for_points_of_plate (self ,inputPointCloud ):
111226 data = self .remove_inf_value (inputPointCloud )
112227 data = self .decimate_point_cloud (data , 0.95 )
113228 x = data [:,0 ]
@@ -124,7 +239,14 @@ def ask_for_limits(self,inputPointCloud):
124239 cid = fig .canvas .mpl_connect ('button_press_event' , onclick )
125240 plt .show ()
126241 global coords
127- self .filter_coordinates = coords
242+ self .x1 = coords [0 ][0 ]
243+ self .x2 = coords [1 ][0 ]
244+ self .y1 = coords [0 ][1 ]
245+ self .y2 = coords [1 ][1 ]
246+ self .get_logger ().info ("x1 : " + str (self .x1 ))
247+ self .get_logger ().info ("x2 : " + str (self .x2 ))
248+ self .get_logger ().info ("y1 : " + str (self .y1 ))
249+ self .get_logger ().info ("y2 : " + str (self .y2 ))
128250 coords = []
129251 return 0
130252
@@ -134,7 +256,27 @@ def extract_reference_base_change(self):
134256if __name__ == '__main__' :
135257 rclpy .init ()
136258 point_cloud_processing_node = PointCloudProcessingNode ()
137- scan = point_cloud_processing_node .load_scan ("/home/gulltor/Ramsai_Robotics/history/impression_base_avec_retraction_20_pourcents/scan/layer_scan_4.npy" )
138- point_cloud_processing_node .ask_for_limits (scan )
139- filtered_scan = point_cloud_processing_node .filter_point_cloud (scan )
259+ reference_layer = point_cloud_processing_node .load_scan ("/home/gulltor/Ramsai_Robotics/history/impression_base_avec_retraction_20_pourcents/scan/layer_scan_0.npy" )
260+ layer_3 = point_cloud_processing_node .load_scan ("/home/gulltor/Ramsai_Robotics/history/impression_base_avec_retraction_20_pourcents/scan/layer_scan_3.npy" )
261+ layer_3 = point_cloud_processing_node .remove_value_above (layer_3 , - 70 )
262+
263+ #point_cloud_processing_node.ask_for_plate_limits(layer_3)
264+ point_cloud_processing_node .xinf = - 40.311554355006095
265+ point_cloud_processing_node .xsup = 4
266+ filtered_scan = point_cloud_processing_node .remove_non_used_plate_points (layer_3 )
267+ reference_layer_filtered = point_cloud_processing_node .remove_non_used_plate_points (reference_layer )
268+ point_cloud_processing_node .transformation_creation (reference_layer_filtered )
269+ layer_3_transformed = point_cloud_processing_node .tranform_point_cloud (filtered_scan )
270+ point_cloud_processing_node .plot_point_cloud (layer_3_transformed )
271+ """
272+ point_cloud_processing_node.ask_for_points_of_plate(filtered_scan)
273+ layer_points = point_cloud_processing_node.select_layer_points(filtered_scan)
274+ point_cloud_processing_node.barycentre_calculation(layer_points)
275+ point_cloud_processing_node.plot_point_cloud(layer_points)
276+ point_cloud_list = [None]*122
277+ for i in range(0,122):
278+ point_cloud_list[i] = point_cloud_processing_node.load_scan('/home/gulltor/Ramsai_Robotics/history/impression_base_avec_retraction_20_pourcents/scan/layer_scan_'+str(i)+'.npy')
279+ point_cloud_list[i] = point_cloud_processing_node.remove_non_used_plate_points(point_cloud_list[i])
280+ point_cloud_processing_node.get_logger().info('layer : '+str(i))
281+ """
140282 rclpy .shutdown ()
0 commit comments