Skip to content

Commit b31c871

Browse files
committed
Point_cloud processing work
1 parent 2707ecf commit b31c871

File tree

1 file changed

+160
-18
lines changed

1 file changed

+160
-18
lines changed

3D_printer/src/printer3d_pointCloud_processing/nodes/point_cloud_processing_node.py

Lines changed: 160 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@
1919
import numpy as np
2020
import pyvista as pv
2121
import matplotlib.pyplot as plt
22-
import matplotlib
22+
import matplotlib as mpl
2323
import random
24+
import pyransac3d as pyrsc
2425

2526
""" parametres du noeuds ROS, à mettre dans un fichier de config a la fin"""
2627
basic_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):
134256
if __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

Comments
 (0)