fasd / tddfa /utils /functions.py
ozyman's picture
added depth model
ddadf19
# coding: utf-8
__author__ = 'cleardusk'
import numpy as np
import cv2
from math import sqrt
import matplotlib.pyplot as plt
RED = (0, 0, 255)
GREEN = (0, 255, 0)
BLUE = (255, 0, 0)
def get_suffix(filename):
"""a.jpg -> jpg"""
pos = filename.rfind('.')
if pos == -1:
return ''
return filename[pos:]
def crop_img(img, roi_box):
h, w = img.shape[:2]
sx, sy, ex, ey = [int(round(_)) for _ in roi_box]
dh, dw = ey - sy, ex - sx
if len(img.shape) == 3:
res = np.zeros((dh, dw, 3), dtype=np.uint8)
else:
res = np.zeros((dh, dw), dtype=np.uint8)
if sx < 0:
sx, dsx = 0, -sx
else:
dsx = 0
if ex > w:
ex, dex = w, dw - (ex - w)
else:
dex = dw
if sy < 0:
sy, dsy = 0, -sy
else:
dsy = 0
if ey > h:
ey, dey = h, dh - (ey - h)
else:
dey = dh
res[dsy:dey, dsx:dex] = img[sy:ey, sx:ex]
return res
def calc_hypotenuse(pts):
bbox = [min(pts[0, :]), min(pts[1, :]), max(pts[0, :]), max(pts[1, :])]
center = [(bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2]
radius = max(bbox[2] - bbox[0], bbox[3] - bbox[1]) / 2
bbox = [center[0] - radius, center[1] - radius, center[0] + radius, center[1] + radius]
llength = sqrt((bbox[2] - bbox[0]) ** 2 + (bbox[3] - bbox[1]) ** 2)
return llength / 3
def parse_roi_box_from_landmark(pts):
"""calc roi box from landmark"""
bbox = [min(pts[0, :]), min(pts[1, :]), max(pts[0, :]), max(pts[1, :])]
center = [(bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2]
radius = max(bbox[2] - bbox[0], bbox[3] - bbox[1]) / 2
bbox = [center[0] - radius, center[1] - radius, center[0] + radius, center[1] + radius]
llength = sqrt((bbox[2] - bbox[0]) ** 2 + (bbox[3] - bbox[1]) ** 2)
center_x = (bbox[2] + bbox[0]) / 2
center_y = (bbox[3] + bbox[1]) / 2
roi_box = [0] * 4
roi_box[0] = center_x - llength / 2
roi_box[1] = center_y - llength / 2
roi_box[2] = roi_box[0] + llength
roi_box[3] = roi_box[1] + llength
return roi_box
def parse_roi_box_from_bbox(bbox):
left, top, right, bottom = bbox[:4]
old_size = (right - left + bottom - top) / 2
center_x = right - (right - left) / 2.0
center_y = bottom - (bottom - top) / 2.0 + old_size * 0.14
size = int(old_size * 1.58)
roi_box = [0] * 4
roi_box[0] = center_x - size / 2
roi_box[1] = center_y - size / 2
roi_box[2] = roi_box[0] + size
roi_box[3] = roi_box[1] + size
return roi_box
def plot_image(img):
height, width = img.shape[:2]
plt.figure(figsize=(12, height / width * 12))
plt.subplots_adjust(left=0, right=1, top=1, bottom=0)
plt.axis('off')
plt.imshow(img[..., ::-1])
plt.show()
def draw_landmarks(img, pts, style='fancy', wfp=None, show_flag=False, **kwargs):
"""Draw landmarks using matplotlib"""
height, width = img.shape[:2]
plt.figure(figsize=(12, height / width * 12))
plt.imshow(img[..., ::-1])
plt.subplots_adjust(left=0, right=1, top=1, bottom=0)
plt.axis('off')
dense_flag = kwargs.get('dense_flag')
if not type(pts) in [tuple, list]:
pts = [pts]
for i in range(len(pts)):
if dense_flag:
plt.plot(pts[i][0, ::6], pts[i][1, ::6], 'o', markersize=0.4, color='c', alpha=0.7)
else:
alpha = 0.8
markersize = 4
lw = 1.5
color = kwargs.get('color', 'w')
markeredgecolor = kwargs.get('markeredgecolor', 'black')
nums = [0, 17, 22, 27, 31, 36, 42, 48, 60, 68]
# close eyes and mouths
plot_close = lambda i1, i2: plt.plot([pts[i][0, i1], pts[i][0, i2]], [pts[i][1, i1], pts[i][1, i2]],
color=color, lw=lw, alpha=alpha - 0.1)
plot_close(41, 36)
plot_close(47, 42)
plot_close(59, 48)
plot_close(67, 60)
for ind in range(len(nums) - 1):
l, r = nums[ind], nums[ind + 1]
plt.plot(pts[i][0, l:r], pts[i][1, l:r], color=color, lw=lw, alpha=alpha - 0.1)
plt.plot(pts[i][0, l:r], pts[i][1, l:r], marker='o', linestyle='None', markersize=markersize,
color=color,
markeredgecolor=markeredgecolor, alpha=alpha)
if wfp is not None:
plt.savefig(wfp, dpi=150)
print(f'Save visualization result to {wfp}')
if show_flag:
plt.show()
def cv_draw_landmark(img_ori, pts, box=None, color=GREEN, size=1):
img = img_ori.copy()
n = pts.shape[1]
if n <= 106:
for i in range(n):
cv2.circle(img, (int(round(pts[0, i])), int(round(pts[1, i]))), size, color, -1)
else:
sep = 1
for i in range(0, n, sep):
cv2.circle(img, (int(round(pts[0, i])), int(round(pts[1, i]))), size, color, 1)
if box is not None:
left, top, right, bottom = np.round(box).astype(np.int32)
left_top = (left, top)
right_top = (right, top)
right_bottom = (right, bottom)
left_bottom = (left, bottom)
cv2.line(img, left_top, right_top, BLUE, 1, cv2.LINE_AA)
cv2.line(img, right_top, right_bottom, BLUE, 1, cv2.LINE_AA)
cv2.line(img, right_bottom, left_bottom, BLUE, 1, cv2.LINE_AA)
cv2.line(img, left_bottom, left_top, BLUE, 1, cv2.LINE_AA)
return img