geopavlakos's picture
Initial commit
d7a991a
raw
history blame
3.91 kB
# 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