123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- import cv2
- import os
- import sys
- sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
- import time
- import glob
- import json
- import argparse
- import pickle
- import matplotlib.pyplot as plt
- from datetime import datetime
- import numpy as np
- import scipy.io as sio
- from scipy.io import savemat, loadmat
- np.random.seed(42)
- from src.utils import binarize, get_meshgrid, get_world_points, get_camera_points, get_screen_points, write_point_cloud, \
- get_white_mask, get_world_points_from_mask, get_meshgrid_contour, post_process
- from src.phase import extract_phase, unwrap_phase
- from src.recons import reconstruction_cumsum
- from src.calibration import calibrate_world, calibrate_screen, map_screen_to_world
- from src.vis import plot_coords
- from src.eval import get_eval_result, find_notch
- def list_directories(path):
- # List all items in the given directory and filter only directories
- return [item for item in os.listdir(path) if os.path.isdir(os.path.join(path, item))]
- def parse_args():
- parser = argparse.ArgumentParser(description="")
- parser.add_argument("--img_path", type=str, default='D:\\file\\20240913-data\\20240913105234292')
- parser.add_argument("--camera_path", type=str, default='D:\\file\\标定数据\\标定数据0913\\calibration_0913')
- parser.add_argument("--screen_path", type=str, default='D:\\file\\screen0920')
- parser.add_argument("--cfg", type=str, default="config/cfg_3freq_wafer.json")
- #parser.add_argument("--cfg", type=str, default="D:\code\pmdrecons-python\config\cfg_3freq_wafer.json")
- parser.add_argument("--save_path", type=str, default="debug")
- parser.add_argument("--grid_spacing", type=int, default=1)
- parser.add_argument("--debug", action='store_true')
- parser.add_argument("--smooth", action='store_true')
- parser.add_argument("--align", action='store_true')
- parser.add_argument("--denoise", action='store_true')
- args = parser.parse_args()
- return args
- def main(cfg, img_folder, camera_path, screen_path, save_path, grid_spacing, debug):
- n_cam = 4
- num_freq = cfg['num_freq']
- start_time = time.time()
- #debug = True
- print(f"开始执行时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
- print("\n1. 相机标定")
- preprocess_start = time.time()
-
- camera_subdir = list_directories(camera_path)
- camera_subdir.sort()
- assert len(camera_subdir) == 4, f"found {len(camera_subdir)} cameras, should be 4"
- cam_para_path = os.path.join(camera_path, "cam_params.pkl")
- if os.path.exists(cam_para_path):
- with open(cam_para_path, 'rb') as pkl_file:
- cam_params = pickle.load(pkl_file)
- else:
- cam_params = []
- for i in range(n_cam):
- cam_img_path = glob.glob(os.path.join(camera_path, camera_subdir[i], "*.bmp"))
- cam_img_path.sort()
- cam_param_raw = calibrate_world(cam_img_path, i, cfg['world_chessboard_size'], cfg['world_square_size'], debug=False)
- cam_params.append(cam_param_raw)
- with open(cam_para_path, 'wb') as pkl_file:
- pickle.dump(cam_params, pkl_file)
-
- preprocess_end = time.time()
- print(f" 完成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
- print(f" 耗时: {preprocess_end - preprocess_start:.2f} 秒")
- # import pdb; pdb.set_trace()
-
- print("\n2. 屏幕标定")
- screen_cal_start = time.time()
- screen_img_path = glob.glob(os.path.join(screen_path, "*.bmp"))
- screen_para_path = os.path.join(screen_path, "screen_params.pkl")
- if os.path.exists(screen_para_path):
- with open(screen_para_path, 'rb') as pkl_file:
- screen_params = pickle.load(pkl_file)[0]
- else:
- screen_params = calibrate_screen(screen_img_path, cam_params[0]['camera_matrix'], cam_params[0]['distortion_coefficients'], cfg['screen_chessboard_size'], cfg['screen_square_size'], debug=True)
- with open(screen_para_path, 'wb') as pkl_file:
- pickle.dump([screen_params], pkl_file)
- screen_to_world = map_screen_to_world(screen_params, cam_params[0])
- screen_cal_end = time.time()
- print(f" 完成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
- print(f" 耗时: {screen_cal_end - screen_cal_start:.2f} 秒")
-
- print("\n3. 相位提取,相位展开")
- phase_start = time.time()
- x_uns, y_uns = [], []
- binary_masks = []
- for cam_id in range(n_cam):
- white_path = os.path.join(img_folder, f'{cam_id}_frame_24.bmp')
- binary = get_white_mask(white_path)
- binary_masks.append(binary)
- phases = extract_phase(img_folder, cam_id, binary, cam_params[cam_id]['camera_matrix'], cam_params[cam_id]['distortion_coefficients'], num_freq=num_freq)
- x_un, y_un = unwrap_phase(phases, save_path, num_freq, debug=False)
- x_uns.append(x_un)
- y_uns.append(y_un)
-
- phase_end = time.time()
- print(f" 完成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
- print(f" 耗时: {phase_end - phase_start:.2f} 秒")
-
- print("\n4. 获得不同坐标系下点的位置")
- get_point_start = time.time()
- total_cloud_point = np.empty((0, 3))
- for i in range(n_cam):
- if i > 5:
- continue
- contours_point = get_meshgrid_contour(binary_masks[i], grid_spacing, save_path, debug=False)
- world_points = get_world_points(contours_point, cam_params[i], grid_spacing, cfg['d'], save_path, debug=debug)
- camera_points, u_p, v_p = get_camera_points(world_points, cam_params[i], save_path, i, debug=debug)
-
- point_data = {'x_w': world_points[:, 0], 'y_w': world_points[:, 1], 'z_w': world_points[:, 2],
- 'x_c': camera_points[:, 0], 'y_c': camera_points[:, 1], 'z_c': camera_points[:, 2],
- 'u_p': u_p, 'v_p': v_p}
-
- screen_points = get_screen_points(point_data, x_uns[i], y_uns[i], screen_params, screen_to_world, cfg, save_path, i, debug=debug)
- #plot_coords(world_points, camera_points, screen_points)
- z, smoothed, aligned, denoise = reconstruction_cumsum(world_points, camera_points, screen_points, save_path, i, debug=debug, smooth=args.smooth, align=args.align, denoise=args.denoise)
- write_point_cloud(os.path.join(img_folder, str(i) + '_cloudpoint.txt'), world_points[:, 0], world_points[:, 1], 1000 * denoise[:,2])
- total_cloud_point = np.vstack([total_cloud_point, np.column_stack((denoise[:, 0], denoise[:, 1], 1000 * denoise[:,2]))])
- print('point cloud has been written in file')
- write_point_cloud(os.path.join(img_folder, 'cloudpoint.txt'), total_cloud_point[:, 0], total_cloud_point[:, 1], total_cloud_point[:,2])
-
- if debug:
- fig = plt.figure()
- ax = fig.add_subplot(111, projection='3d')
- # 提取 x, y, z 坐标
- x_vals = total_cloud_point[:, 0]
- y_vals = total_cloud_point[:, 1]
- z_vals = total_cloud_point[:, 2]
- # 绘制3D点云
- ax.scatter(x_vals, y_vals, z_vals, c=z_vals, cmap='viridis', marker='o')
- # 设置轴标签和标题
- ax.set_xlabel('X (mm)')
- ax.set_ylabel('Y (mm)')
- ax.set_zlabel('Z (mm)')
- ax.set_title('3D Point Cloud Visualization')
- plt.show()
- get_point_end = time.time()
- print(f" 完成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
- print(f" 耗时: {get_point_end - get_point_start:.2f} 秒")
-
- print("\n5. 后处理")
- post_process_start = time.time()
- post_process(args.img_path, debug)
- post_process_end = time.time()
- print(f" 完成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
- print(f" 耗时: {post_process_end - post_process_start:.2f} 秒")
- print("\n6. 评估")
- eval_start = time.time()
- point_cloud_path = os.path.join(img_folder, str(i) + '_cloudpoint.txt')
- json_path = os.path.join(img_folder, str(i) + 'result.json')
- theta_notch = 0
- get_eval_result(point_cloud_path, json_path, theta_notch)
- post_process(args.img_path, debug)
- eval_end = time.time()
- print(f" 完成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
- print(f" 耗时: {eval_end - eval_start:.2f} 秒")
- return True
-
- if __name__ == '__main__':
- start_time = time.time()
-
- args = parse_args()
- img_folder = args.img_path
-
-
- cfg = json.load(open(args.cfg, 'r'))
- if not os.path.exists(args.save_path):
- os.makedirs(args.save_path)
-
- args.smooth = True
- args.align = True
- args.denoise = True
- args.debug = 0
- main(cfg, img_folder, args.camera_path, args.screen_path, args.save_path, args.grid_spacing, args.debug)
- end_time = time.time()
- print(f"总运行时间: {end_time - start_time:.2f} 秒")
-
|