|
@@ -24,6 +24,9 @@ import cv2
|
24
|
24
|
from src.eval import get_eval_result
|
25
|
25
|
import pickle
|
26
|
26
|
from collections import defaultdict
|
|
27
|
+from scipy.io import loadmat, savemat
|
|
28
|
+
|
|
29
|
+
|
27
|
30
|
|
28
|
31
|
def pmdstart(config_path, img_folder):
|
29
|
32
|
start_time = time.time()
|
|
@@ -42,15 +45,15 @@ def main(config_path, img_folder):
|
42
|
45
|
os.chdir(current_dir)
|
43
|
46
|
|
44
|
47
|
cfg = json.load(open(config_path, 'r'))
|
45
|
|
- n_cam = 4
|
|
48
|
+ n_cam = cfg['cam_num']
|
46
|
49
|
num_freq = cfg['num_freq']
|
47
|
50
|
save_path = 'debug'
|
48
|
51
|
debug = False
|
49
|
52
|
grid_spacing = cfg['grid_spacing']
|
50
|
53
|
num_freq = cfg['num_freq']
|
51
|
|
- smooth = True
|
52
|
|
- align = True
|
53
|
|
- denoise = True
|
|
54
|
+ smooth = False
|
|
55
|
+ align = False
|
|
56
|
+ denoise = False
|
54
|
57
|
#cammera_img_path = 'D:\\data\\four_cam\\calibrate\\calibrate-1008'
|
55
|
58
|
screen_img_path = 'D:\\data\\four_cam\\calibrate\\cam3-screen-1008'
|
56
|
59
|
cammera_img_path = 'D:\\data\\four_cam\\calibrate\\calibrate-1016'
|
|
@@ -60,8 +63,10 @@ def main(config_path, img_folder):
|
60
|
63
|
print("\n1. 相机标定")
|
61
|
64
|
preprocess_start = time.time()
|
62
|
65
|
|
63
|
|
- #cam_para_path = os.path.join('config', cfg['cam_params'])
|
64
|
|
- cam_para_path = 'D:\\code\\pmd-python\\config\\cam_params.pkl'
|
|
66
|
+ cam_para_path = os.path.join(current_dir, 'config', cfg['cam_params'])
|
|
67
|
+ print('cam_para_path = ', cam_para_path)
|
|
68
|
+ print('current_dir = ', current_dir)
|
|
69
|
+ #cam_para_path = 'D:\\code\\pmd-python\\config\\cam_params.pkl'
|
65
|
70
|
if os.path.exists(cam_para_path):
|
66
|
71
|
#if False:
|
67
|
72
|
with open(cam_para_path, 'rb') as pkl_file:
|
|
@@ -77,8 +82,8 @@ def main(config_path, img_folder):
|
77
|
82
|
#print('cam_img_path = ', cam_img_path)
|
78
|
83
|
cam_param_raw = calibrate_world(cam_img_path, i, cfg['world_chessboard_size'], cfg['world_square_size'], debug=0)
|
79
|
84
|
cam_params.append(cam_param_raw)
|
80
|
|
- with open(cam_para_path, 'wb') as pkl_file:
|
81
|
|
- pickle.dump(cam_params, pkl_file)
|
|
85
|
+ # with open(cam_para_path, 'wb') as pkl_file:
|
|
86
|
+ # pickle.dump(cam_params, pkl_file)
|
82
|
87
|
|
83
|
88
|
print("\n2. 屏幕标定")
|
84
|
89
|
screen_cal_start = time.time()
|
|
@@ -91,10 +96,10 @@ def main(config_path, img_folder):
|
91
|
96
|
screen_params = pickle.load(pkl_file)[0]
|
92
|
97
|
else:
|
93
|
98
|
screen_params = calibrate_screen(screen_img_path, cam_params[3]['camera_matrix'], cam_params[3]['distortion_coefficients'], cfg['screen_chessboard_size'], cfg['screen_square_size'], debug=0)
|
94
|
|
- with open(screen_para_path, 'wb') as pkl_file:
|
95
|
|
- pickle.dump([screen_params], pkl_file)
|
|
99
|
+ # with open(screen_para_path, 'wb') as pkl_file:
|
|
100
|
+ # pickle.dump([screen_params], pkl_file)
|
|
101
|
+
|
96
|
102
|
|
97
|
|
- screen_to_world = map_screen_to_world(screen_params, cam_params[3])
|
98
|
103
|
screen_cal_end = time.time()
|
99
|
104
|
print(f" 完成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
100
|
105
|
print(f" 耗时: {screen_cal_end - screen_cal_start:.2f} 秒")
|
|
@@ -105,18 +110,109 @@ def main(config_path, img_folder):
|
105
|
110
|
binary_masks = []
|
106
|
111
|
for cam_id in range(n_cam):
|
107
|
112
|
print('cam_id = ', cam_id)
|
108
|
|
- white_path = os.path.join(img_folder, f'{cam_id}_frame_24.bmp')
|
109
|
|
- binary = get_white_mask(white_path, bin_thresh=12, debug=0)
|
|
113
|
+ #white_path = os.path.join(img_folder, f'{cam_id}_frame_24.bmp')
|
|
114
|
+ white_path = 'D:\\code\\code of PMD\\code of PMD\\picture\\white.bmp'
|
|
115
|
+ if n_cam == 3:
|
|
116
|
+ binary = get_white_mask(white_path, bin_thresh=12, debug=0)
|
|
117
|
+
|
|
118
|
+ elif n_cam == 1:
|
|
119
|
+ #angle_rad, binary = find_notch(white_path, n_cam, debug=0)
|
|
120
|
+ binary = get_white_mask(white_path, bin_thresh=12, debug=0)
|
|
121
|
+
|
110
|
122
|
binary_masks.append(binary)
|
111
|
|
- phases = extract_phase(img_folder, cam_id, binary, cam_params[cam_id]['camera_matrix'], cam_params[cam_id]['distortion_coefficients'], num_freq=num_freq)
|
112
|
|
- x_un, y_un = unwrap_phase(phases, save_path, num_freq, debug=0)
|
113
|
|
- x_uns.append(x_un)
|
114
|
|
- y_uns.append(y_un)
|
|
123
|
+
|
|
124
|
+ #phases = extract_phase(img_folder, cam_id, binary, cam_params[cam_id]['camera_matrix'], cam_params[cam_id]['distortion_coefficients'], num_freq=num_freq)
|
|
125
|
+ #x_un, y_un = unwrap_phase(phases, save_path, num_freq, debug=0)
|
|
126
|
+
|
|
127
|
+ #x_uns.append(x_un)
|
|
128
|
+ #y_uns.append(y_un)
|
115
|
129
|
|
116
|
130
|
phase_end = time.time()
|
117
|
131
|
print(f" 完成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
118
|
132
|
print(f" 耗时: {phase_end - phase_start:.2f} 秒")
|
119
|
|
-
|
|
133
|
+
|
|
134
|
+ # matlab align
|
|
135
|
+ #cam_params = loadmat('D:\\code\\code of PMD\\code of PMD\\calibration\\calibrationSessionworld.mat')
|
|
136
|
+ #screen_params = loadmat('D:\\code\\code of PMD\\code of PMD\\calibration\\calibrationSessionscreen.mat')
|
|
137
|
+
|
|
138
|
+ #print('cam_params = ', cam_params)
|
|
139
|
+ #print('screen_params = ', screen_params)
|
|
140
|
+
|
|
141
|
+ cam_params = []
|
|
142
|
+ screen_params = []
|
|
143
|
+ mtx = np.array([[6944.89018564351, 0, 2709.44699784446], [0, 6942.91962497637, 1882.05677580185], [0,0,1]])
|
|
144
|
+ R = cv2.Rodrigues(np.array([0.0732148059333282,-0.265812028310130,-0.0532640604086260]).reshape(3,1))[0]
|
|
145
|
+ T = np.array([-15.179977,-42.247126,246.92182]).reshape(3,1)
|
|
146
|
+
|
|
147
|
+ cam_calibration_data = {
|
|
148
|
+ 'camera_matrix': mtx,
|
|
149
|
+ 'distortion_coefficients': 0,
|
|
150
|
+ 'rotation_matrix': R,
|
|
151
|
+ 'translation_vector': T,
|
|
152
|
+ 'error': 0
|
|
153
|
+ }
|
|
154
|
+
|
|
155
|
+ mtx = np.array([[6944.89018564351, 0, 2709.44699784446], [0, 6942.91962497637, 1882.05677580185], [0,0,1]])
|
|
156
|
+ R = np.array([[0.96514996,-0.042578806,0.25821037],[0.029285983,0.99805061,0.055111798],[-0.26005361,-0.045629206,0.96451547]])
|
|
157
|
+ T = np.array([30.1970,-49.3108,507.4424]).reshape(3,1)
|
|
158
|
+
|
|
159
|
+ screen_calibration_data = {
|
|
160
|
+ 'screen_matrix': mtx,
|
|
161
|
+ 'screen_distortion': 0,
|
|
162
|
+ 'screen_rotation_matrix': R,
|
|
163
|
+ 'screen_translation_vector': T,
|
|
164
|
+ 'screen_error': 0
|
|
165
|
+ }
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+ cam_params.append(cam_calibration_data)
|
|
169
|
+ #screen_params.append(screen_calibration_data)
|
|
170
|
+ screen_params = screen_calibration_data
|
|
171
|
+
|
|
172
|
+ x_un = loadmat('D:\\code\\code of PMD\\code of PMD\\phase_information\\x_phase_unwrapped.mat')
|
|
173
|
+ y_un = loadmat('D:\\code\\code of PMD\\code of PMD\\phase_information\\y_phase_unwrapped.mat')
|
|
174
|
+
|
|
175
|
+ x_un = x_un['x_phase_unwrapped']
|
|
176
|
+ y_un = y_un['y_phase_unwrapped']
|
|
177
|
+
|
|
178
|
+ x_uns, y_uns = [], []
|
|
179
|
+ x_uns.append(x_un)
|
|
180
|
+ y_uns.append(y_un)
|
|
181
|
+
|
|
182
|
+ #fig, axes = plt.subplots(1, 2, figsize=(12, 6))
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+ # 第一个子图
|
|
186
|
+ # cax0 = axes[0].imshow(x_un)
|
|
187
|
+ # axes[0].set_title('x_phase_unwrapped')
|
|
188
|
+ # axes[0].set_xlabel('X Axis')
|
|
189
|
+ # axes[0].set_ylabel('Y Axis')
|
|
190
|
+ # fig.colorbar(cax0, ax=axes[0])
|
|
191
|
+
|
|
192
|
+ # # 第二个子图
|
|
193
|
+ # cax1 = axes[1].imshow(y_un)
|
|
194
|
+ # axes[1].set_title('y_phase_unwrapped')
|
|
195
|
+ # axes[1].set_xlabel('X Axis')
|
|
196
|
+ # axes[1].set_ylabel('Y Axis')
|
|
197
|
+ # fig.colorbar(cax0, ax=axes[1])
|
|
198
|
+
|
|
199
|
+ # # 调整子图之间的间距
|
|
200
|
+ # plt.tight_layout()
|
|
201
|
+ #plt.savefig(os.path.join(save_path, "phase_unwrapped.png"))
|
|
202
|
+ #plt.show()
|
|
203
|
+
|
|
204
|
+ #return 0
|
|
205
|
+ print('screen_params = ', screen_params)
|
|
206
|
+
|
|
207
|
+ if n_cam == 1:
|
|
208
|
+ screen_to_world = map_screen_to_world(screen_params, cam_params[0])
|
|
209
|
+ elif n_cam == 4:
|
|
210
|
+ screen_to_world = map_screen_to_world(screen_params, cam_params[3])
|
|
211
|
+ else:
|
|
212
|
+ print('camera number should be 1 or 4')
|
|
213
|
+ return 0
|
|
214
|
+
|
|
215
|
+
|
120
|
216
|
print("\n4. 获得不同坐标系下点的位置")
|
121
|
217
|
get_point_start = time.time()
|
122
|
218
|
total_cloud_point = np.empty((0, 3))
|
|
@@ -132,7 +228,7 @@ def main(config_path, img_folder):
|
132
|
228
|
'u_p': u_p, 'v_p': v_p}
|
133
|
229
|
screen_points = get_screen_points(point_data, x_uns[i], y_uns[i], screen_params, screen_to_world, cfg, save_path, i, debug=debug)
|
134
|
230
|
#plot_coords(world_points, camera_points, screen_points)
|
135
|
|
- z_raw, aligned, smoothed, denoised, gradient_xy = reconstruction_cumsum(world_points, camera_points, screen_points, save_path, i, debug=0, smooth=smooth, align=align, denoise=denoise)
|
|
231
|
+ z_raw, gradient_xy = reconstruction_cumsum(world_points, camera_points, screen_points, debug=0, smooth=smooth, align=align, denoise=denoise)
|
136
|
232
|
|
137
|
233
|
z_raw_xy = np.round(z_raw[:, :2]).astype(int)
|
138
|
234
|
|
|
@@ -161,12 +257,13 @@ def main(config_path, img_folder):
|
161
|
257
|
# z_raw_aligned = non_boundary_points @ rotation_matrix.T
|
162
|
258
|
# z_raw_aligned[:,2] = z_raw_aligned[:,2] - np.mean(z_raw_aligned[:, 2])
|
163
|
259
|
|
164
|
|
- z_raw_aligned = non_boundary_points
|
|
260
|
+ #z_raw_aligned = non_boundary_points
|
|
261
|
+ z_raw_aligned, _ = align2ref(non_boundary_points)
|
165
|
262
|
|
166
|
263
|
#non_boundary_points = smoothed
|
167
|
|
- write_point_cloud(os.path.join(img_folder, str(i) + '_cloudpoint.txt'), np.round(z_raw_aligned[:, 0]), np.round(z_raw_aligned[:, 1]), 1000*z_raw_aligned[:, 2])
|
|
264
|
+ write_point_cloud(os.path.join(img_folder, str(i) + '_cloudpoint.txt'), np.round(z_raw_aligned[:, 0]), np.round(z_raw_aligned[:, 1]), z_raw_aligned[:, 2])
|
168
|
265
|
np.savetxt(os.path.join(img_folder, str(i) + '_gradient.txt'), gradient_xy, fmt='%.10f', delimiter=',')
|
169
|
|
- total_cloud_point = np.vstack([total_cloud_point, np.column_stack((z_raw_aligned[:, 0], z_raw_aligned[:, 1], 1000*z_raw_aligned[:, 2]))])
|
|
266
|
+ total_cloud_point = np.vstack([total_cloud_point, np.column_stack((z_raw_aligned[:, 0], z_raw_aligned[:, 1], z_raw_aligned[:, 2]))])
|
170
|
267
|
total_gradient = np.vstack([total_gradient, np.column_stack((gradient_xy[:, 0], gradient_xy[:, 1], gradient_xy[:, 2], gradient_xy[:, 3]))])
|
171
|
268
|
|
172
|
269
|
if 0:
|
|
@@ -185,7 +282,7 @@ def main(config_path, img_folder):
|
185
|
282
|
ax.set_xlabel('X (mm)')
|
186
|
283
|
ax.set_ylabel('Y (mm)')
|
187
|
284
|
ax.set_zlabel('Z (mm)')
|
188
|
|
- ax.set_title('3D Point Cloud Visualization gradient')
|
|
285
|
+ ax.set_title('z_raw 3D Point Cloud Visualization gradient')
|
189
|
286
|
plt.show()
|
190
|
287
|
|
191
|
288
|
# fig = plt.figure()
|
|
@@ -215,13 +312,13 @@ def main(config_path, img_folder):
|
215
|
312
|
total_cloud_point[:,0] = np.round(total_cloud_point[:,0])
|
216
|
313
|
total_cloud_point[:,1] = np.round(total_cloud_point[:,1])
|
217
|
314
|
#fitted_points = post_process(total_cloud_point, debug=0)
|
218
|
|
- fitted_points = post_process_with_grad(img_folder, 0)
|
|
315
|
+ fitted_points = post_process_with_grad(img_folder, n_cam, 1)
|
219
|
316
|
#fitted_points = total_cloud_point
|
220
|
317
|
#align_fitted, _ = align2ref(fitted_points)
|
221
|
318
|
align_fitted = fitted_points
|
222
|
319
|
|
223
|
320
|
write_point_cloud(os.path.join(img_folder, 'cloudpoint.txt'), np.round(align_fitted[:, 0]-np.mean(align_fitted[:, 0])), np.round(align_fitted[:, 1]-np.mean(align_fitted[:, 1])), align_fitted[:,2]-np.min(align_fitted[:,2]))
|
224
|
|
- if 0:
|
|
321
|
+ if 1:
|
225
|
322
|
fig = plt.figure()
|
226
|
323
|
ax = fig.add_subplot(111, projection='3d')
|
227
|
324
|
|
|
@@ -230,6 +327,10 @@ def main(config_path, img_folder):
|
230
|
327
|
y_vals = np.round(fitted_points[:, 1]-np.mean(fitted_points[:, 1]))
|
231
|
328
|
z_vals = align_fitted[:,2]-np.min(align_fitted[:,2])
|
232
|
329
|
|
|
330
|
+ x_vals = fitted_points[:, 0]
|
|
331
|
+ y_vals = fitted_points[:, 1]
|
|
332
|
+ z_vals = fitted_points[:, 2]
|
|
333
|
+
|
233
|
334
|
# 绘制3D点云
|
234
|
335
|
ax.scatter(x_vals, y_vals, z_vals, c=z_vals, cmap='viridis', marker='o')
|
235
|
336
|
|
|
@@ -237,7 +338,7 @@ def main(config_path, img_folder):
|
237
|
338
|
ax.set_xlabel('X (mm)')
|
238
|
339
|
ax.set_ylabel('Y (mm)')
|
239
|
340
|
ax.set_zlabel('Z (mm)')
|
240
|
|
- ax.set_title('3D Point Cloud Visualization')
|
|
341
|
+ ax.set_title('post 3D Point Cloud Visualization')
|
241
|
342
|
plt.show()
|
242
|
343
|
|
243
|
344
|
post_process_end = time.time()
|
|
@@ -249,7 +350,7 @@ def main(config_path, img_folder):
|
249
|
350
|
point_cloud_path = os.path.join(img_folder, 'cloudpoint.txt')
|
250
|
351
|
json_path = os.path.join(img_folder, 'result.json')
|
251
|
352
|
theta_notch = 0
|
252
|
|
- get_eval_result(point_cloud_path, json_path, theta_notch, 0)
|
|
353
|
+ #get_eval_result(point_cloud_path, json_path, theta_notch, 0)
|
253
|
354
|
eval_end = time.time()
|
254
|
355
|
print(f" 完成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
255
|
356
|
print(f" 耗时: {eval_end - eval_start:.2f} 秒")
|
|
@@ -257,14 +358,14 @@ def main(config_path, img_folder):
|
257
|
358
|
return True
|
258
|
359
|
|
259
|
360
|
|
260
|
|
-
|
261
|
|
-
|
262
|
|
-
|
263
|
361
|
if __name__ == '__main__':
|
264
|
|
- config_path = 'config\\cfg_3freq_wafer.json'
|
|
362
|
+ config_path = 'config\\cfg_3freq_wafer_matlab.json'
|
265
|
363
|
#img_folder = 'D:\\data\\four_cam\\1008_storage\\pingjing_20241017092315228\\' #'D:\\data\\four_cam\\betone_1011\\20241011142348762-1'
|
266
|
364
|
# img_folder = 'D:\\huchao\\inspect_server_202409241013_py\\storage\\20241023193453708\\'
|
267
|
|
- img_folder = 'D:\\data\\four_cam\\betone_1011\\20241011144821292-4\\'
|
|
365
|
+ img_folder = 'D:\\data\\one_cam\\pingjing_20241024154405250\\'
|
|
366
|
+ #img_folder = 'D:\\data\\one_cam\\betone-20241025095352783\\'
|
|
367
|
+ #img_folder = 'D:\\data\\one_cam\\20241025113857041-neg\\'
|
|
368
|
+ #'
|
268
|
369
|
json_path = os.path.join(img_folder, 'result.json')
|
269
|
370
|
|
270
|
371
|
# 20241011142348762-1 20241011142901251-2 20241011143925746-3 20241011144821292-4
|
|
@@ -281,7 +382,5 @@ if __name__ == '__main__':
|
281
|
382
|
|
282
|
383
|
pmdstart(config_path, img_folder)
|
283
|
384
|
#fitted_points = post_process_with_grad(img_folder, 1)
|
284
|
|
-
|
285
|
|
-
|
286
|
385
|
|
287
|
386
|
|