| import cv2 |
| import math |
| import numpy as np |
| from skimage import transform as trans |
|
|
|
|
| def transform(data, center, output_size, scale, rotation): |
| scale_ratio = scale |
| rot = float(rotation) * np.pi / 180.0 |
| |
| t1 = trans.SimilarityTransform(scale=scale_ratio) |
| cx = center[0] * scale_ratio |
| cy = center[1] * scale_ratio |
| t2 = trans.SimilarityTransform(translation=(-1 * cx, -1 * cy)) |
| t3 = trans.SimilarityTransform(rotation=rot) |
| t4 = trans.SimilarityTransform(translation=(output_size / 2, |
| output_size / 2)) |
| t = t1 + t2 + t3 + t4 |
| M = t.params[0:2] |
| cropped = cv2.warpAffine(data, |
| M, (output_size, output_size), |
| borderValue=0.0) |
| return cropped, M |
|
|
|
|
| def trans_points2d(pts, M): |
| new_pts = np.zeros(shape=pts.shape, dtype=np.float32) |
| for i in range(pts.shape[0]): |
| pt = pts[i] |
| new_pt = np.array([pt[0], pt[1], 1.], dtype=np.float32) |
| new_pt = np.dot(M, new_pt) |
| |
| new_pts[i] = new_pt[0:2] |
|
|
| return new_pts |
|
|
|
|
| def trans_points3d(pts, M): |
| scale = np.sqrt(M[0][0] * M[0][0] + M[0][1] * M[0][1]) |
| |
| new_pts = np.zeros(shape=pts.shape, dtype=np.float32) |
| for i in range(pts.shape[0]): |
| pt = pts[i] |
| new_pt = np.array([pt[0], pt[1], 1.], dtype=np.float32) |
| new_pt = np.dot(M, new_pt) |
| |
| new_pts[i][0:2] = new_pt[0:2] |
| new_pts[i][2] = pts[i][2] * scale |
|
|
| return new_pts |
|
|
|
|
| def trans_points(pts, M): |
| if pts.shape[1] == 2: |
| return trans_points2d(pts, M) |
| else: |
| return trans_points3d(pts, M) |
|
|
| def estimate_affine_matrix_3d23d(X, Y): |
| ''' Using least-squares solution |
| Args: |
| X: [n, 3]. 3d points(fixed) |
| Y: [n, 3]. corresponding 3d points(moving). Y = PX |
| Returns: |
| P_Affine: (3, 4). Affine camera matrix (the third row is [0, 0, 0, 1]). |
| ''' |
| X_homo = np.hstack((X, np.ones([X.shape[0],1]))) |
| P = np.linalg.lstsq(X_homo, Y)[0].T |
| return P |
|
|
| def P2sRt(P): |
| ''' decompositing camera matrix P |
| Args: |
| P: (3, 4). Affine Camera Matrix. |
| Returns: |
| s: scale factor. |
| R: (3, 3). rotation matrix. |
| t: (3,). translation. |
| ''' |
| t = P[:, 3] |
| R1 = P[0:1, :3] |
| R2 = P[1:2, :3] |
| s = (np.linalg.norm(R1) + np.linalg.norm(R2))/2.0 |
| r1 = R1/np.linalg.norm(R1) |
| r2 = R2/np.linalg.norm(R2) |
| r3 = np.cross(r1, r2) |
|
|
| R = np.concatenate((r1, r2, r3), 0) |
| return s, R, t |
|
|
| def matrix2angle(R): |
| ''' get three Euler angles from Rotation Matrix |
| Args: |
| R: (3,3). rotation matrix |
| Returns: |
| x: pitch |
| y: yaw |
| z: roll |
| ''' |
| sy = math.sqrt(R[0,0] * R[0,0] + R[1,0] * R[1,0]) |
| |
| singular = sy < 1e-6 |
| |
| if not singular : |
| x = math.atan2(R[2,1] , R[2,2]) |
| y = math.atan2(-R[2,0], sy) |
| z = math.atan2(R[1,0], R[0,0]) |
| else : |
| x = math.atan2(-R[1,2], R[1,1]) |
| y = math.atan2(-R[2,0], sy) |
| z = 0 |
|
|
| |
| rx, ry, rz = x*180/np.pi, y*180/np.pi, z*180/np.pi |
| return rx, ry, rz |
|
|
|
|