Spaces:
Sleeping
Sleeping
import numpy as np | |
import cv2 | |
from PIL import ImageFile | |
ImageFile.LOAD_TRUNCATED_IMAGES = True | |
mean_face_lm5p_256 = np.array([ | |
[(30.2946+8)*2+16, 51.6963*2], # left eye pupil | |
[(65.5318+8)*2+16, 51.5014*2], # right eye pupil | |
[(48.0252+8)*2+16, 71.7366*2], # nose tip | |
[(33.5493+8)*2+16, 92.3655*2], # left mouth corner | |
[(62.7299+8)*2+16, 92.2041*2], # right mouth corner | |
], dtype=np.float32) | |
mean_box_lm4p_512 = np.array([ | |
[80, 80], | |
[80, 432], | |
[432, 432], | |
[432, 80], | |
], dtype=np.float32) | |
def get_box_lm4p(pts): | |
x1 = np.min(pts[:,0]) | |
x2 = np.max(pts[:,0]) | |
y1 = np.min(pts[:,1]) | |
y2 = np.max(pts[:,1]) | |
x_center = (x1+x2)*0.5 | |
y_center = (y1+y2)*0.5 | |
box_size = max(x2-x1, y2-y1) | |
x1 = x_center-0.5*box_size | |
x2 = x_center+0.5*box_size | |
y1 = y_center-0.5*box_size | |
y2 = y_center+0.5*box_size | |
return np.array([[x1, y1], [x1, y2], [x2, y2], [x2, y1]], dtype=np.float32) | |
def get_affine_transform(target_face_lm5p, mean_lm5p): | |
mat_warp = np.zeros((2,3)) | |
A = np.zeros((4,4)) | |
B = np.zeros((4)) | |
for i in range(5): | |
#sa[0][0] += a[i].x*a[i].x + a[i].y*a[i].y; | |
A[0][0] += target_face_lm5p[i][0] * target_face_lm5p[i][0] + target_face_lm5p[i][1] * target_face_lm5p[i][1] | |
#sa[0][2] += a[i].x; | |
A[0][2] += target_face_lm5p[i][0] | |
#sa[0][3] += a[i].y; | |
A[0][3] += target_face_lm5p[i][1] | |
#sb[0] += a[i].x*b[i].x + a[i].y*b[i].y; | |
B[0] += target_face_lm5p[i][0] * mean_lm5p[i][0] + target_face_lm5p[i][1] * mean_lm5p[i][1] | |
#sb[1] += a[i].x*b[i].y - a[i].y*b[i].x; | |
B[1] += target_face_lm5p[i][0] * mean_lm5p[i][1] - target_face_lm5p[i][1] * mean_lm5p[i][0] | |
#sb[2] += b[i].x; | |
B[2] += mean_lm5p[i][0] | |
#sb[3] += b[i].y; | |
B[3] += mean_lm5p[i][1] | |
#sa[1][1] = sa[0][0]; | |
A[1][1] = A[0][0] | |
#sa[2][1] = sa[1][2] = -sa[0][3]; | |
A[2][1] = A[1][2] = -A[0][3] | |
#sa[3][1] = sa[1][3] = sa[2][0] = sa[0][2]; | |
A[3][1] = A[1][3] = A[2][0] = A[0][2] | |
#sa[2][2] = sa[3][3] = count; | |
A[2][2] = A[3][3] = 5 | |
#sa[3][0] = sa[0][3]; | |
A[3][0] = A[0][3] | |
_, mat23 = cv2.solve(A, B, flags=cv2.DECOMP_SVD) | |
mat_warp[0][0] = mat23[0] | |
mat_warp[1][1] = mat23[0] | |
mat_warp[0][1] = -mat23[1] | |
mat_warp[1][0] = mat23[1] | |
mat_warp[0][2] = mat23[2] | |
mat_warp[1][2] = mat23[3] | |
return mat_warp | |
def transformation_from_points(points1, points2): | |
points1 = np.float64(np.matrix([[point[0], point[1]] for point in points1])) | |
points2 = np.float64(np.matrix([[point[0], point[1]] for point in points2])) | |
points1 = points1.astype(np.float64) | |
points2 = points2.astype(np.float64) | |
c1 = np.mean(points1, axis=0) | |
c2 = np.mean(points2, axis=0) | |
points1 -= c1 | |
points2 -= c2 | |
s1 = np.std(points1) | |
s2 = np.std(points2) | |
points1 /= s1 | |
points2 /= s2 | |
#points2 = np.array(points2) | |
#write_pts('pt2.txt', points2) | |
U, S, Vt = np.linalg.svd(points1.T * points2) | |
R = (U * Vt).T | |
return np.array(np.vstack([np.hstack(((s2 / s1) * R,c2.T - (s2 / s1) * R * c1.T)),np.matrix([0., 0., 1.])])[:2]) | |