123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 |
- import cv2
- import numpy as np
- def get_similarity_transform(src_pts, dst_pts):
- """Get similarity transform matrix from src_pts to dst_pts
-
- Args:
- src_pts: Kx2 np.array
- source points matrix, each row is a pair of coordinates (x, y)
- dst_pts: Kx2 np.array
- destination points matrix, each row is a pair of coordinates (x, y)
-
- Returns:
- xform_matrix: 3x3 np.array
- transform matrix from src_pts to dst_pts
- """
- src_pts = np.asarray(src_pts)
- dst_pts = np.asarray(dst_pts)
- assert src_pts.shape == dst_pts.shape
- assert (src_pts.ndim == 2) and (src_pts.shape[-1] == 2)
-
- npts = src_pts.shape[0]
- src_x = src_pts[:, 0].reshape((-1, 1))
- src_y = src_pts[:, 1].reshape((-1, 1))
- tmp1 = np.hstack((src_x, -src_y, np.ones((npts, 1)), np.zeros((npts, 1))))
- tmp2 = np.hstack((src_y, src_x, np.zeros((npts, 1)), np.ones((npts, 1))))
- A = np.vstack((tmp1, tmp2))
- dst_x = dst_pts[:, 0].reshape((-1, 1))
- dst_y = dst_pts[:, 1].reshape((-1, 1))
- b = np.vstack((dst_x, dst_y))
- x = np.linalg.lstsq(A, b, rcond=-1)[0]
- x = np.squeeze(x)
- sc, ss, tx, ty = x[0], x[1], x[2], x[3]
- xform_matrix = np.array([
- [sc, -ss, tx],
- [ss, sc, ty],
- [ 0, 0, 1]
- ])
- return xform_matrix
-
-
- def align_and_crop(image, landmarks, std_landmarks, align_size,
- border_value=0, return_transform_matrix=False):
- landmarks = np.asarray(landmarks)
- std_landmarks = np.asarray(std_landmarks)
- xform_matrix = get_similarity_transform(landmarks, std_landmarks)
- landmarks_ex = np.pad(landmarks, ((0,0),(0,1)), mode='constant', constant_values=1)
- dst_landmarks = np.dot(landmarks_ex, xform_matrix[:2,:].T)
- dst_image = cv2.warpAffine(image, xform_matrix[:2,:], dsize=align_size,
- borderValue=border_value)
- if return_transform_matrix:
- return dst_image, dst_landmarks, xform_matrix
- else:
- return dst_image, dst_landmarks
-
-
|