Spaces:
Build error
Build error
# Copyright (c) OpenMMLab. All rights reserved. | |
import cv2 | |
import numpy as np | |
def apply_bugeye_effect(img, | |
pose_results, | |
left_eye_index, | |
right_eye_index, | |
kpt_thr=0.5): | |
"""Apply bug-eye effect. | |
Args: | |
img (np.ndarray): Image data. | |
pose_results (list[dict]): The pose estimation results containing: | |
- "bbox" ([K, 4(or 5)]): detection bbox in | |
[x1, y1, x2, y2, (score)] | |
- "keypoints" ([K,3]): keypoint detection result in [x, y, score] | |
left_eye_index (int): Keypoint index of left eye | |
right_eye_index (int): Keypoint index of right eye | |
kpt_thr (float): The score threshold of required keypoints. | |
""" | |
xx, yy = np.meshgrid(np.arange(img.shape[1]), np.arange(img.shape[0])) | |
xx = xx.astype(np.float32) | |
yy = yy.astype(np.float32) | |
for pose in pose_results: | |
bbox = pose['bbox'] | |
kpts = pose['keypoints'] | |
if kpts[left_eye_index, 2] < kpt_thr or kpts[right_eye_index, | |
2] < kpt_thr: | |
continue | |
kpt_leye = kpts[left_eye_index, :2] | |
kpt_reye = kpts[right_eye_index, :2] | |
for xc, yc in [kpt_leye, kpt_reye]: | |
# distortion parameters | |
k1 = 0.001 | |
epe = 1e-5 | |
scale = (bbox[2] - bbox[0])**2 + (bbox[3] - bbox[1])**2 | |
r2 = ((xx - xc)**2 + (yy - yc)**2) | |
r2 = (r2 + epe) / scale # normalized by bbox scale | |
xx = (xx - xc) / (1 + k1 / r2) + xc | |
yy = (yy - yc) / (1 + k1 / r2) + yc | |
img = cv2.remap( | |
img, | |
xx, | |
yy, | |
interpolation=cv2.INTER_AREA, | |
borderMode=cv2.BORDER_REPLICATE) | |
return img | |
def apply_sunglasses_effect(img, | |
pose_results, | |
sunglasses_img, | |
left_eye_index, | |
right_eye_index, | |
kpt_thr=0.5): | |
"""Apply sunglasses effect. | |
Args: | |
img (np.ndarray): Image data. | |
pose_results (list[dict]): The pose estimation results containing: | |
- "keypoints" ([K,3]): keypoint detection result in [x, y, score] | |
sunglasses_img (np.ndarray): Sunglasses image with white background. | |
left_eye_index (int): Keypoint index of left eye | |
right_eye_index (int): Keypoint index of right eye | |
kpt_thr (float): The score threshold of required keypoints. | |
""" | |
hm, wm = sunglasses_img.shape[:2] | |
# anchor points in the sunglasses mask | |
pts_src = np.array([[0.3 * wm, 0.3 * hm], [0.3 * wm, 0.7 * hm], | |
[0.7 * wm, 0.3 * hm], [0.7 * wm, 0.7 * hm]], | |
dtype=np.float32) | |
for pose in pose_results: | |
kpts = pose['keypoints'] | |
if kpts[left_eye_index, 2] < kpt_thr or kpts[right_eye_index, | |
2] < kpt_thr: | |
continue | |
kpt_leye = kpts[left_eye_index, :2] | |
kpt_reye = kpts[right_eye_index, :2] | |
# orthogonal vector to the left-to-right eyes | |
vo = 0.5 * (kpt_reye - kpt_leye)[::-1] * [-1, 1] | |
# anchor points in the image by eye positions | |
pts_tar = np.vstack( | |
[kpt_reye + vo, kpt_reye - vo, kpt_leye + vo, kpt_leye - vo]) | |
h_mat, _ = cv2.findHomography(pts_src, pts_tar) | |
patch = cv2.warpPerspective( | |
sunglasses_img, | |
h_mat, | |
dsize=(img.shape[1], img.shape[0]), | |
borderValue=(255, 255, 255)) | |
# mask the white background area in the patch with a threshold 200 | |
mask = cv2.cvtColor(patch, cv2.COLOR_BGR2GRAY) | |
mask = (mask < 200).astype(np.uint8) | |
img = cv2.copyTo(patch, mask, img) | |
return img | |