Download data_tool/pose_estimation.py from vegagoto123/gha: direct link, hf CLI and curl.
- Browser
- Download file 5.39 kB
-
https://huggingface.co/vegagoto123/gha/resolve/main/data_tool/pose_estimation.py
- Command line
-
hf download hf://vegagoto123/gha/data_tool/pose_estimation.py
-
curl -L -o pose_estimation.py https://huggingface.co/vegagoto123/gha/resolve/main/data_tool/pose_estimation.py
5.39 kB
| import cv2 | |
| import dlib | |
| import numpy as np | |
| from scipy.optimize import least_squares | |
| # 加载dlib的预训练人脸检测器和关键点检测器模型 | |
| detector = dlib.get_frontal_face_detector() | |
| predictor = dlib.shape_predictor('/data_160TB/2021/yangkun/gaussian-splatting-main-copy/flame/shape_predictor_68_face_landmarks.dat') | |
| # 定义3D模型点(根据68个关键点) | |
| model_points = np.array([ | |
| (0.0, 0.0, 0.0), # 鼻尖 | |
| (0.0, -330.0, -65.0), # 下巴 | |
| (-225.0, 170.0, -135.0), # 左眼角 | |
| (225.0, 170.0, -135.0), # 右眼角 | |
| (-150.0, -150.0, -125.0), # 左嘴角 | |
| (150.0, -150.0, -125.0) # 右嘴角 | |
| ], dtype=np.float32)//1000 | |
| # 定义相机内参矩阵 | |
| # 这里 fx, fy 代表焦距,cx, cy 代表光心坐标 | |
| fx, fy, cx, cy = 2183.5264, 2183.5264, 256, 256 # 示例值,请根据实际相机参数调整 | |
| camera_matrix = np.array([ | |
| [fx, 0, cx], | |
| [0, fy, cy], | |
| [0, 0, 1] | |
| ], dtype=np.float32) | |
| # 假设无畸变 | |
| dist_coeffs = np.zeros((4, 1)) | |
| # 准备图像列表 | |
| image_files = ['/data_160TB/2021/yangkun/gaussian-splatting-main-copy/eg3d_human/test/person_0/masked/0000.png', | |
| '/data_160TB/2021/yangkun/gaussian-splatting-main-copy/eg3d_human/test/person_0/masked/0030.png', | |
| '/data_160TB/2021/yangkun/gaussian-splatting-main-copy/eg3d_human/test/person_0/masked/0060.png', | |
| '/data_160TB/2021/yangkun/gaussian-splatting-main-copy/eg3d_human/test/person_0/masked/0090.png'] # 示例文件名列表 | |
| image_points_list = [] | |
| # 提取每张图像中的关键点 | |
| for file in image_files: | |
| img = cv2.imread(file) | |
| if img is None: | |
| print(f"Error: Could not read image {file}") | |
| continue | |
| gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) | |
| faces = detector(gray) | |
| if len(faces) == 0: | |
| print(f"Warning: No face detected in image {file}") | |
| continue | |
| for face in faces: | |
| shape = predictor(gray, face) | |
| image_points = np.array([ | |
| (shape.part(30).x, shape.part(30).y), # 鼻尖 | |
| (shape.part(8).x, shape.part(8).y), # 下巴 | |
| (shape.part(36).x, shape.part(36).y), # 左眼角 | |
| (shape.part(45).x, shape.part(45).y), # 右眼角 | |
| (shape.part(48).x, shape.part(48).y), # 左嘴角 | |
| (shape.part(54).x, shape.part(54).y) # 右嘴角 | |
| ], dtype=np.float32) | |
| image_points_list.append(image_points) | |
| break | |
| if len(image_points_list) == 0: | |
| print("Error: No faces detected in any image") | |
| exit() | |
| # 假设第一个图像是原点,计算相对于第一张图像的相机姿态 | |
| initial_poses = [] | |
| for i, image_points in enumerate(image_points_list): | |
| success, rotation_vector, translation_vector = cv2.solvePnP( | |
| model_points, image_points, camera_matrix, dist_coeffs) | |
| if not success: | |
| print(f"Error: solvePnP failed for image {i+1}") | |
| continue | |
| initial_poses.append((rotation_vector, translation_vector)) | |
| # 转换为优化问题的参数格式 | |
| def pack_params(poses): | |
| params = [] | |
| for rvec, tvec in poses: | |
| params.append(rvec.ravel()) | |
| params.append(tvec.ravel()) | |
| return np.concatenate(params) | |
| def unpack_params(params): | |
| poses = [] | |
| for i in range(0, len(params), 6): | |
| rvec = params[i:i+3].reshape(3, 1) | |
| tvec = params[i+3:i+6].reshape(3, 1) | |
| poses.append((rvec, tvec)) | |
| return poses | |
| # 损失函数 | |
| def reprojection_error(params, model_points, image_points_list, camera_matrix, dist_coeffs): | |
| poses = unpack_params(params) | |
| errors = [] | |
| for (rvec, tvec), img_points in zip(poses, image_points_list): | |
| projected_points, _ = cv2.projectPoints(model_points, rvec, tvec, camera_matrix, dist_coeffs) | |
| error = img_points - projected_points.reshape(-1, 2) | |
| errors.append(error.ravel()) | |
| return np.concatenate(errors) | |
| # 优化相机姿态 | |
| initial_params = pack_params(initial_poses) | |
| result = least_squares(reprojection_error, initial_params, args=(model_points, image_points_list, camera_matrix, dist_coeffs)) | |
| # 获取优化后的相机姿态 | |
| optimized_poses = unpack_params(result.x) | |
| poses = [] | |
| # 输出结果 | |
| for i, (rvec, tvec) in enumerate(optimized_poses): | |
| pose = np.ones((4, 4)) | |
| rotation_matrix, _ = cv2.Rodrigues(rvec) | |
| print(f"Image {i+1} - Rotation Vector:\n{rotation_matrix}\nTranslation Vector:\n{tvec}") | |
| pose[0:3, 0:3] = rotation_matrix | |
| pose[0:3, 3] = tvec[0] | |
| poses.append(pose) | |
| poses = np.stack(poses, 0) | |
| np.save('/data_160TB/2021/yangkun/gaussian-splatting-main-copy/eg3d_human/test/camera_4.npy', poses) | |
| # 可视化(以第一张图像为基准) | |
| # img = cv2.imread(image_files[0]) | |
| # if img is None: | |
| # print(f"Error: Could not read image {image_files[0]}") | |
| # exit() | |
| # for i, (rvec, tvec) in enumerate(optimized_poses): | |
| # axis = np.float32([[200, 0, 0], [0, 200, 0], [0, 0, 200]]) | |
| # imgpts, _ = cv2.projectPoints(axis, rvec, tvec, camera_matrix, dist_coeffs) | |
| # imgpts = np.int32(imgpts).reshape(-1, 2) | |
| # img = cv2.line(img, tuple(image_points_list[0][0]), tuple(imgpts[0]), (255, 0, 0), 5) | |
| # img = cv2.line(img, tuple(image_points_list[0][0]), tuple(imgpts[1]), (0, 255, 0), 5) | |
| # img = cv2.line(img, tuple(image_points_list[0][0]), tuple(imgpts[2]), (0, 0, 255), 5) | |
| # cv2.imshow('Optimized Result', img) | |
| # cv2.waitKey(0) | |
| # cv2.destroyAllWindows() | |