Browse Source

one cam combine

zhangkang 9 months ago
parent
commit
a42c95ba34

BIN
config/cam_params_1.pkl


BIN
config/cam_params_4.pkl


+ 16 - 0
config/cfg_3freq_wafer_1.json

@@ -0,0 +1,16 @@
1
+{
2
+    "cam_num":1,
3
+    "screen_square_size": 29,
4
+    "screen_chessboard_size": [10, 7],
5
+    "world_chessboard_size": [8, 8],
6
+    "d": -20.7,
7
+    "num_freq": 3,
8
+    "screenPixelSize": [1920, 1080],
9
+    "screenorigin_point": [1320, 300],
10
+    "Axis_conversion": [[-1, 1]],
11
+    "k": 32.0,
12
+    "pixelSize_mm": 0.363745,
13
+    "grid_spacing": 1,
14
+    "cam_params": "cam_params_1.pkl",
15
+    "screen_params":"screen_params_1.pkl"
16
+}

+ 17 - 0
config/cfg_3freq_wafer_4.json

@@ -0,0 +1,17 @@
1
+{
2
+    "cam_num":4,
3
+    "screen_square_size": 25.31,
4
+    "screen_chessboard_size": [10, 6],
5
+    "world_chessboard_size": [6, 6],
6
+    "world_square_size": 35.2,
7
+    "d": -2.5,
8
+    "num_freq": 3,
9
+    "screenPixelSize": [1600, 1200],
10
+    "screenorigin_point": [649, 550],
11
+    "Axis_conversion": [[-1, -1]],
12
+    "k": 32.0,
13
+    "pixelSize_mm": 0.253125,
14
+    "grid_spacing":1,
15
+    "cam_params": "cam_params_4.pkl",
16
+    "screen_params":"screen_params_4.pkl"
17
+}

+ 16 - 0
config/cfg_3freq_wafer_matlab.json

@@ -0,0 +1,16 @@
1
+{
2
+    "cam_num":1,
3
+    "screen_square_size": 9,
4
+    "screen_chessboard_size": [10, 7],
5
+    "world_chessboard_size": [8, 8],
6
+    "d": 10.04,  
7
+    "num_freq": 3,
8
+    "screenPixelSize": [2160, 1215],
9
+    "screenorigin_point": [1512.5,121.5],
10
+    "Axis_conversion": [[-1, 1]],
11
+    "k": 32.0,
12
+    "pixelSize_mm": 0.095955,
13
+    "grid_spacing": 1,
14
+    "cam_params": "cam_params_1.pkl",
15
+    "screen_params":"screen_params_1.pkl"
16
+}

BIN
config/screen_params_1.pkl


BIN
config/screen_params_4.pkl


+ 133 - 34
pmd.py

@@ -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
     

+ 2 - 0
src/calibration/calibrate.py

@@ -7,6 +7,8 @@ def map_screen_to_world(data_screen, date_world):
7 7
     A = date_world['camera_matrix']
8 8
     Rw2c = date_world['rotation_matrix']
9 9
     Tw2c = date_world['translation_vector']
10
+    # print('Rv2c = ', Rv2c)
11
+    # print('Tv2c = ', Tv2c)
10 12
 
11 13
     # print(Rv2c.shape, Tv2c.shape, A.shape, Rw2c.shape, Tw2c.shape)
12 14
     # Rv2c = np.array([[0.965149963314468, -0.0425788059963296, 0.258210366937518],

+ 3 - 0
src/calibration/get_camera_params.py

@@ -169,6 +169,9 @@ def calibrate_world(calibration_images_path, cam_id, world_chessboard_size=(6,6)
169 169
     mean_error = total_error / len(all_object_points)
170 170
     #print(f"Mean re-projection error: {mean_error}")
171 171
 
172
+    print('rvecs[0] = ', rvecs[0])
173
+    #print('rvecs[0] = ', (rvecs[0]))
174
+
172 175
     # 获得第一张图片的旋转矩阵和平移向量
173 176
     R = cv2.Rodrigues(rvecs[0])[0]  # 转换为旋转矩阵
174 177
     T = tvecs[0]

+ 9 - 55
src/recons.py

@@ -311,7 +311,7 @@ def poisson_recons(x, y, gx, gy, debug=False):
311 311
 
312 312
 
313 313
 
314
-def reconstruction_cumsum(world_points, camera_points, screen_points, save_path, cam_id, debug=False, smooth=False, align=True, denoise=True):
314
+def reconstruction_cumsum(world_points, camera_points, screen_points, debug=False, smooth=False, align=True, denoise=True):
315 315
 
316 316
     x = world_points[:, 0]
317 317
     y = world_points[:, 1]
@@ -338,7 +338,6 @@ def reconstruction_cumsum(world_points, camera_points, screen_points, save_path,
338 338
 
339 339
     #print('normal_vector = ', normal_vector[0])
340 340
 
341
-
342 341
     # 计算法向量在X方向的梯度
343 342
     gradient_x = normal_vector[0]
344 343
 
@@ -347,6 +346,9 @@ def reconstruction_cumsum(world_points, camera_points, screen_points, save_path,
347 346
     #gradient_x = np.zeros(gradient_x.shape)
348 347
     #gradient_y = np.zeros(gradient_x.shape)
349 348
 
349
+    print('abs mean (gradient_x) = ', np.mean(abs(gradient_x)))
350
+    print('abs mean (gradient_y) = ', np.mean(abs(gradient_y)))
351
+
350 352
     #gradient_x = gradient_x - np.mean(gradient_x)
351 353
     #gradient_y = gradient_y - np.mean(gradient_y)
352 354
     # import pdb
@@ -355,18 +357,13 @@ def reconstruction_cumsum(world_points, camera_points, screen_points, save_path,
355 357
     z = np.zeros(len(x))
356 358
     z[0] = 0  # 初始点的z
357 359
     
358
-    #z_raw = poisson_recons(x, y, gradient_x, gradient_y)
359
-    z_raw = poisson_recons_with_smoothed_gradients(x, y, gradient_x, gradient_y)
360
+    z_raw = poisson_recons(x, y, gradient_x, gradient_y)
361
+    #z_raw = poisson_recons_with_smoothed_gradients(x, y, gradient_x, gradient_y)
362
+    #z_raw = z
360 363
 
361 364
     #print('gradient_x  = ', x.shape, y.shape, gradient_x.shape, gradient_y.shape)
362
-
363 365
     gradient_xy = np.column_stack((x, y, gradient_x, gradient_y))
364 366
     
365
-       # z_raw = least_squares_recons(x, y, gradient_x, gradient_y)
366
-        # import pdb; pdb.set_trace()
367
-    #print('-- point cloud: mean - {}; std - {}'.format(np.nanmean(z), np.nanstd(z)))
368
-    
369
-        #print('-- nanmean after smoothing: mean - {}; std - {}'.format(np.nanmean(smoothed_points[:, 2]), np.nanstd(smoothed_points[:, 2])))
370 367
     if align:
371 368
         #points_aligned, rotation_matrix = align2ref(smoothed_points)
372 369
         points_aligned, rotation_matrix = align2ref(np.column_stack((x, y, z_raw)))
@@ -389,31 +386,6 @@ def reconstruction_cumsum(world_points, camera_points, screen_points, save_path,
389 386
         # points_denoise = remove_noise(x, y, z, a, b, c, thresh=0.01)
390 387
 
391 388
     if debug:
392
-        #fig, axes = plt.subplots(1, 2, figsize=(12, 6))
393
-
394
-        # # 第一个子图
395
-        # cax0 = axes[0].scatter(x, y, c=gradient_x, cmap='viridis')
396
-        # axes[0].set_title('Visualization of x gradient')
397
-        # axes[0].set_xlabel('X Axis')
398
-        # axes[0].set_ylabel('Y Axis')
399
-        # fig.colorbar(cax0, ax=axes[0])
400
-
401
-        # cax1 = axes[1].scatter(x, y, c=gradient_y, cmap='viridis')
402
-        # axes[1].set_title('Visualization of y gradient')
403
-        # axes[1].set_xlabel('X Axis')
404
-        # axes[1].set_ylabel('Y Axis')
405
-        # fig.colorbar(cax1, ax=axes[1])
406
-        # #plt.savefig(os.path.join(save_path, "gradient.png"))
407
-        # # 调整子图之间的间距
408
-        # plt.tight_layout()
409
-        # # 显示图像
410
-        # plt.show()
411
-        # fig = plt.figure()
412
-        # ax = fig.add_subplot(111, projection='3d')
413
-        # # 绘制3D点云
414
-        # ax.scatter(x, y, z, c=z, cmap='viridis', marker='o')
415
-        # plt.show()
416
-
417 389
         fig = plt.figure()
418 390
         ax = fig.add_subplot(111, projection='3d')
419 391
 
@@ -431,27 +403,9 @@ def reconstruction_cumsum(world_points, camera_points, screen_points, save_path,
431 403
         ax.set_zlabel('Z (mm)')
432 404
         ax.set_title('raw 3D Point Cloud Visualization')
433 405
 
434
-        fig = plt.figure()
435
-        ax = fig.add_subplot(111, projection='3d')
436
-
437
-        # 提取 x, y, z 坐标
438
-        x_vals = x
439
-        y_vals = y
440
-        z_vals = points_smoothed[:,2]
441
-
442
-        # 绘制3D点云
443
-        ax.scatter(x_vals, y_vals, z_vals, c=z_vals, cmap='viridis', marker='o', s=1)
444
-
445
-        # 设置轴标签和标题
446
-        ax.set_xlabel('X (mm)')
447
-        ax.set_ylabel('Y (mm)')
448
-        ax.set_zlabel('Z (mm)')
449
-        ax.set_title('smooth 3D Point Cloud Visualization')
450 406
         plt.show()
451
-
452
-   
453
-    
454
-    return np.column_stack((x, y, z_raw)), points_aligned, points_smoothed, points_denoise, gradient_xy
407
+ 
408
+    return np.column_stack((x, y, z_raw)), gradient_xy
455 409
 
456 410
 
457 411
 

+ 69 - 37
src/utils.py

@@ -369,6 +369,7 @@ def get_world_points(contour_points, world_mat_contents, cam_id, grid_spacing, d
369 369
     Tc2w = -np.dot(np.linalg.inv(Rw2c), Tw2c)
370 370
     world_points_contours = affine_img2world(contour_points, A, Rc2w, Tc2w, d)
371 371
     
372
+    
372 373
     world_points_fit,  world_points_boundary = fit_sector(world_points_contours, grid_spacing, erosion_pixels)
373 374
     _,  world_points_boundary_3 = fit_sector(world_points_contours, grid_spacing, 3)
374 375
     # assert np.abs(world_contour_points[:, 0].max()-world_contour_points[:, 0].min()-(world_contour_points[:, 1].max()-world_contour_points[:, 1].min())) < 1
@@ -496,10 +497,10 @@ def get_screen_points(point_data, x_phase_unwrapped, y_phase_unwrapped, screen_p
496 497
                             0])
497 498
     abs_phasepoint_world = np.dot(Rs2w, arrow_abs_mm) + Ts2w.T
498 499
     
499
-    # print('abs_phasepoint 绝对相位值:')
500
-    # print(abs_phasepoint)
501
-    # print('abs_phasepoint_world 绝对相位值对应的世界坐标系的位置:')
502
-    # print(abs_phasepoint_world)
500
+    print('abs_phasepoint 绝对相位值:')
501
+    print(abs_phasepoint)
502
+    print('abs_phasepoint_world 绝对相位值对应的世界坐标系的位置:')
503
+    print(abs_phasepoint_world)
503 504
 
504 505
     # print('----------------------------------------')
505 506
 
@@ -582,7 +583,10 @@ def get_white_mask(white_path, bin_thresh=15, debug=False):
582 583
         max_index, max_contour = max(enumerate(valid_contours), key=lambda x: cv2.boundingRect(x[1])[2] * cv2.boundingRect(x[1])[3]) 
583 584
         cv2.drawContours(mask, [max_contour], -1, (255, 255, 255), thickness=cv2.FILLED)
584 585
     if debug:
585
-       
586
+        
587
+        cv2.namedWindow('gray',0)
588
+        cv2.imshow('gray', gray)
589
+        cv2.waitKey(0)
586 590
    
587 591
         cv2.namedWindow('mask',0)
588 592
         cv2.imshow('mask', mask)
@@ -801,12 +805,12 @@ def curve_fit_gaussian(points):
801 805
     # 提取拟合参数
802 806
     A, x0, y0, sigma = popt
803 807
     
804
-    #print(f"拟合参数: A={A}, x0={x0}, y0={y0}, sigma={sigma}")
805
-    x_mean = np.mean(x)
806
-    y_mean = np.mean(y)
807
-    x0 = x_mean
808
-    y0 = y_mean
809
-    sigma = 2 * sigma
808
+    print(f"拟合参数: A={A}, x0={x0}, y0={y0}, sigma={sigma}")
809
+    # x_mean = np.mean(x)
810
+    # y_mean = np.mean(y)
811
+    # x0 = x_mean
812
+    # y0 = y_mean
813
+    # sigma = 2 * sigma
810 814
     #print(f"拟合参数1: A={A}, x0={x0}, y0={y0}, sigma={sigma}")
811 815
     
812 816
 
@@ -1240,9 +1244,9 @@ def poisson_reconstruct(x_grad_expand, y_grad_expand):
1240 1244
 
1241 1245
 
1242 1246
 
1243
-def post_process_with_grad(img_folder, debug=False):
1247
+def post_process_with_grad(img_folder, n_cam, debug=False):
1244 1248
     total_point_grad = np.empty((0, 4))
1245
-    for i in range(4):
1249
+    for i in range(n_cam):
1246 1250
         txt_file = img_folder + str(i) + '_gradient.txt'
1247 1251
         total_point_grad = np.vstack([total_point_grad, np.loadtxt(os.path.join(txt_file), delimiter=',')])
1248 1252
      
@@ -1255,27 +1259,45 @@ def post_process_with_grad(img_folder, debug=False):
1255 1259
     x = total_point_grad[:,0]
1256 1260
     y = total_point_grad[:,1]
1257 1261
 
1258
-    x_gradient = total_point_grad[:,2]
1259
-    y_gradient = total_point_grad[:,3]
1262
+    x_gradient = total_point_grad[:,2] 
1263
+    y_gradient = total_point_grad[:,3] 
1264
+
1265
+    mean_x_grad = np.mean((x_gradient))
1266
+    mean_y_grad = np.mean((y_gradient))
1260 1267
 
1261
-    mean_x_grad = np.mean(x_gradient)
1262
-    mean_y_grad = np.mean(y_gradient)
1268
+    sum_x = np.sum(abs(x_gradient))
1269
+    sum_y = np.sum(abs(y_gradient))
1270
+
1271
+    print('sum x grad = ', sum_x)
1272
+    print('sum y grad = ', sum_y)
1273
+
1274
+    print('mean x grad = ', mean_x_grad)
1275
+    print('mean y grad = ', mean_y_grad)
1263 1276
 
1264 1277
     x_gradient =  (x_gradient - mean_x_grad)
1265 1278
     y_gradient =  (y_gradient - mean_y_grad)
1266 1279
     
1280
+    print('max min')
1281
+    print(max(x_gradient), min(x_gradient))
1282
+    print(max(y_gradient), min(y_gradient))
1283
+    print('max min')
1284
+    
1267 1285
     # 使用最小外接矩形,并填充梯度
1268 1286
     x_grad_expand, y_grad_expand, x_expand, y_expand = expand_to_rectangle_with_unit_spacing(x, y, x_gradient, y_gradient)   
1269 1287
     #print(x_grad_expand.shape, y_grad_expand.shape, x_expand.shape, y_expand.shape)
1270 1288
     # 调用 Southwell 重建函数
1271 1289
     #Z_reconstructed = southwell_integrate_smooth(x_grad_expand, y_grad_expand, x_expand, y_expand, (0, 0))
1272 1290
 
1273
-    Z_reconstructed = poisson_reconstruct(x_grad_expand, y_grad_expand)
1291
+    Z_reconstructed = np.cumsum(x_grad_expand, 1)*1 + np.cumsum(y_grad_expand, 0)*1
1292
+    print('min_z =', np.min(Z_reconstructed))
1293
+
1294
+    #Z_reconstructed = poisson_reconstruct(x_grad_expand, y_grad_expand)
1274 1295
     
1275 1296
     z1_lookup = {(x1, y1): z1 for x1, y1, z1 in np.column_stack((x_expand.reshape(-1,1), y_expand.reshape(-1,1), Z_reconstructed.reshape(-1,1)))}
1276 1297
 
1277 1298
     z1_values = np.array([z1_lookup.get((x, y), np.nan) for x, y in np.column_stack((x, y))])
1278
-    fitted_points = post_process(np.column_stack((x,y,z1_values)), debug=0)
1299
+    #fitted_points = post_process(np.column_stack((x,y,z1_values)), debug=0)
1300
+
1279 1301
 
1280 1302
     # 可视化梯度场
1281 1303
     if debug:
@@ -1283,12 +1305,12 @@ def post_process_with_grad(img_folder, debug=False):
1283 1305
         ax = fig.add_subplot(111, projection='3d')
1284 1306
 
1285 1307
         #提取 x, y, z 坐标
1286
-        x_vals = fitted_points[:,0]
1287
-        y_vals = fitted_points[:,1]
1288
-        z_vals = fitted_points[:,2]
1289
-        # x_vals = x
1290
-        # y_vals = y
1291
-        # z_vals = z1_values
1308
+        # x_vals = fitted_points[:,0]
1309
+        # y_vals = fitted_points[:,1]
1310
+        # z_vals = fitted_points[:,2]
1311
+        x_vals = x_expand
1312
+        y_vals = y_expand
1313
+        z_vals = x_grad_expand
1292 1314
         # 绘制3D点云
1293 1315
         ax.scatter(x_vals, y_vals, z_vals, c=z_vals, cmap='viridis', marker='o')
1294 1316
 
@@ -1299,7 +1321,8 @@ def post_process_with_grad(img_folder, debug=False):
1299 1321
         ax.set_title('post_process 3D Point Cloud Visualization')
1300 1322
         plt.show()
1301 1323
     
1302
-    return fitted_points
1324
+    #return fitted_points
1325
+    return np.column_stack((x,y,z1_values))
1303 1326
 
1304 1327
 
1305 1328
 
@@ -1420,7 +1443,7 @@ def find_best_circle(image, min_thresh, max_thresh):
1420 1443
 
1421 1444
 
1422 1445
 
1423
-def find_notch(white_path, cam_num):
1446
+def find_notch(white_path, cam_num, debug=0):
1424 1447
 
1425 1448
     image = cv2.imread(white_path)
1426 1449
     if cam_num == 1:
@@ -1450,15 +1473,16 @@ def find_notch(white_path, cam_num):
1450 1473
         angle_rad = np.arctan2(min_pt[1] - center_y, min_pt[0] - center_x)
1451 1474
 
1452 1475
         thresh_img = cv2.drawContours(background, [max_contour_ellipse], -1, (255, 255, 255), thickness=cv2.FILLED)
1453
-    
1454
-        cv2.circle(image, min_pt, 50, (0,255,255), 2)
1455
-        #print(min_pt)
1456
-        cv2.namedWindow('thresh_img', 0)
1457
-        cv2.imshow('thresh_img', thresh_img)
1458
-        cv2.namedWindow('contours', 0)
1459
-        cv2.imshow('contours', image)
1460
-    
1461
-        cv2.waitKey(0)
1476
+
1477
+        if debug:
1478
+            cv2.circle(image, min_pt, 50, (0,255,255), 2)
1479
+            #print(min_pt)
1480
+            cv2.namedWindow('thresh_img', 0)
1481
+            cv2.imshow('thresh_img', thresh_img)
1482
+            cv2.namedWindow('contours', 0)
1483
+            cv2.imshow('contours', image)
1484
+        
1485
+            cv2.waitKey(0)
1462 1486
         return angle_rad, thresh_img
1463 1487
     else:
1464 1488
         return 0
@@ -1870,7 +1894,15 @@ def img_diff():
1870 1894
         cv2.waitKey(0)
1871 1895
         
1872 1896
         
1873
-
1897
+def mat2pkl():
1898
+    from scipy.io import loadmat, savemat
1899
+    mat_path = 'D:\\code\\pmd-python\\config_1\\screen_params.mat'
1900
+    pkl_path = 'D:\\code\\pmd-python\\config\\screen_params_1.pkl'
1901
+    matdata = loadmat(mat_path)
1902
+    print(matdata)
1903
+    print([matdata])
1904
+    with open(pkl_path, 'wb') as pkl_file:
1905
+        pickle.dump([matdata], pkl_file)
1874 1906
 
1875 1907
 
1876 1908