r"""Normalize face keypoints w.r.t. the reference face keypoints. Args: keypoints (Kx2 numpy array): target facial keypoints. ref_keypoints (Kx2 numpy array): reference facial keypoints. Returns: keypoints (Kx2 numpy array): normalized facial keypoints.
(keypoints, ref_keypoints,
dist_scale_x=None, dist_scale_y=None)
| 563 | |
| 564 | |
| 565 | def normalize_faces(keypoints, ref_keypoints, |
| 566 | dist_scale_x=None, dist_scale_y=None): |
| 567 | r"""Normalize face keypoints w.r.t. the reference face keypoints. |
| 568 | |
| 569 | Args: |
| 570 | keypoints (Kx2 numpy array): target facial keypoints. |
| 571 | ref_keypoints (Kx2 numpy array): reference facial keypoints. |
| 572 | Returns: |
| 573 | keypoints (Kx2 numpy array): normalized facial keypoints. |
| 574 | """ |
| 575 | if keypoints.shape[0] == 68: |
| 576 | central_keypoints = [8] |
| 577 | add_upper_face = False |
| 578 | part_list = [[0, 16], [1, 15], [2, 14], [3, 13], [4, 12], |
| 579 | [5, 11], [6, 10], [7, 9, 8], |
| 580 | [17, 26], [18, 25], [19, 24], [20, 23], [21, 22], |
| 581 | [27], [28], [29], [30], [31, 35], [32, 34], [33], |
| 582 | [36, 45], [37, 44], [38, 43], [39, 42], [40, 47], [41, 46], |
| 583 | [48, 54], [49, 53], [50, 52], [51], [55, 59], [56, 58], |
| 584 | [57], |
| 585 | [60, 64], [61, 63], [62], [65, 67], [66] |
| 586 | ] |
| 587 | if add_upper_face: |
| 588 | part_list += [[68, 82], [69, 81], [70, 80], [71, 79], [72, 78], |
| 589 | [73, 77], [74, 76, 75]] |
| 590 | elif keypoints.shape[0] == 126: |
| 591 | central_keypoints = [16] |
| 592 | part_list = [[i] for i in range(126)] |
| 593 | else: |
| 594 | raise ValueError('Input keypoints type not supported.') |
| 595 | |
| 596 | face_cen = np.mean(keypoints[central_keypoints, :], axis=0) |
| 597 | ref_face_cen = np.mean(ref_keypoints[central_keypoints, :], axis=0) |
| 598 | |
| 599 | def get_mean_dists(pts, face_cen): |
| 600 | r"""Get the mean xy distances of keypoints wrt face center.""" |
| 601 | mean_dists_x, mean_dists_y = [], [] |
| 602 | pts_cen = np.mean(pts, axis=0) |
| 603 | for p, pt in enumerate(pts): |
| 604 | mean_dists_x.append(np.linalg.norm(pt - pts_cen)) |
| 605 | mean_dists_y.append(np.linalg.norm(pts_cen - face_cen)) |
| 606 | mean_dist_x = sum(mean_dists_x) / len(mean_dists_x) + 1e-3 |
| 607 | mean_dist_y = sum(mean_dists_y) / len(mean_dists_y) + 1e-3 |
| 608 | return mean_dist_x, mean_dist_y |
| 609 | |
| 610 | if dist_scale_x is None: |
| 611 | dist_scale_x, dist_scale_y = [None] * len(part_list), \ |
| 612 | [None] * len(part_list) |
| 613 | |
| 614 | for i, pts_idx in enumerate(part_list): |
| 615 | pts = keypoints[pts_idx] |
| 616 | if dist_scale_x[i] is None: |
| 617 | ref_pts = ref_keypoints[pts_idx] |
| 618 | mean_dist_x, mean_dist_y = get_mean_dists(pts, face_cen) |
| 619 | ref_dist_x, ref_dist_y = get_mean_dists(ref_pts, ref_face_cen) |
| 620 | |
| 621 | dist_scale_x[i] = ref_dist_x / mean_dist_x |
| 622 | dist_scale_y[i] = ref_dist_y / mean_dist_y |
nothing calls this directly
no test coverage detected