enotkrutoy's picture
Upload folder using huggingface_hub
e5ba844 verified
# coding: utf-8
import cv2
import numpy as np
class BBox(object):
# bbox is a list of [left, right, top, bottom]
def __init__(self, bbox):
self.left = bbox[0]
self.right = bbox[1]
self.top = bbox[2]
self.bottom = bbox[3]
self.x = bbox[0]
self.y = bbox[2]
self.w = bbox[1] - bbox[0]
self.h = bbox[3] - bbox[2]
# scale to [0,1]
def projectLandmark(self, landmark):
landmark_ = np.asarray(np.zeros(landmark.shape))
for i, point in enumerate(landmark):
landmark_[i] = ((point[0]-self.x)/self.w, (point[1]-self.y)/self.h)
return landmark_
# landmark of (5L, 2L) from [0,1] to real range
def reprojectLandmark(self, landmark):
landmark_ = np.asarray(np.zeros(landmark.shape))
for i, point in enumerate(landmark):
x = point[0] * self.w + self.x
y = point[1] * self.h + self.y
landmark_[i] = (x, y)
return landmark_
def drawLandmark(img, bbox, landmark):
'''
Input:
- img: gray or RGB
- bbox: type of BBox
- landmark: reproject landmark of (5L, 2L)
Output:
- img marked with landmark and bbox
'''
img_ = img.copy()
cv2.rectangle(img_, (bbox.left, bbox.top),
(bbox.right, bbox.bottom), (0, 0, 255), 2)
for x, y in landmark:
cv2.circle(img_, (int(x), int(y)), 3, (0, 255, 0), -1)
return img_
def drawLandmark_multiple(img, bbox, landmark):
'''
Input:
- img: gray or RGB
- bbox: type of BBox
- landmark: reproject landmark of (5L, 2L)
Output:
- img marked with landmark and bbox
'''
cv2.rectangle(img, (bbox.left, bbox.top),
(bbox.right, bbox.bottom), (0, 0, 255), 2)
for x, y in landmark:
cv2.circle(img, (int(x), int(y)), 2, (0, 255, 0), -1)
return img
def drawLandmark_Attribute(img, bbox, landmark, gender, age):
'''
Input:
- img: gray or RGB
- bbox: type of BBox
- landmark: reproject landmark of (5L, 2L)
Output:
- img marked with landmark and bbox
'''
cv2.rectangle(img, (bbox.left, bbox.top),
(bbox.right, bbox.bottom), (0, 0, 255), 2)
for x, y in landmark:
cv2.circle(img, (int(x), int(y)), 3, (0, 255, 0), -1)
if gender.argmax() == 0:
# -1->female, 1->male; -1->old, 1->young
cv2.putText(img, 'female', (int(bbox.left), int(bbox.top)),
cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 0), 3)
else:
cv2.putText(img, 'male', (int(bbox.left), int(bbox.top)),
cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 0), 3)
if age.argmax() == 0:
cv2.putText(img, 'old', (int(bbox.right), int(bbox.bottom)),
cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 0), 3)
else:
cv2.putText(img, 'young', (int(bbox.right), int(bbox.bottom)),
cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 0), 3)
return img
def drawLandmark_only(img, landmark):
'''
Input:
- img: gray or RGB
- bbox: type of BBox
- landmark: reproject landmark of (5L, 2L)
Output:
- img marked with landmark and bbox
'''
img_ = img.copy()
# cv2.rectangle(img_, (bbox.left, bbox.top), (bbox.right, bbox.bottom), (0,0,255), 2)
for x, y in landmark:
cv2.circle(img_, (int(x), int(y)), 3, (0, 255, 0), -1)
return img_
def processImage(imgs):
'''
Subtract mean and normalize, imgs [N, 1, W, H]
'''
imgs = imgs.astype(np.float32)
for i, img in enumerate(imgs):
m = img.mean()
s = img.std()
imgs[i] = (img-m)/s
return imgs
def flip(face, landmark):
'''
flip a face and its landmark
'''
face_ = cv2.flip(face, 1) # 1 means flip horizontal
landmark_flip = np.asarray(np.zeros(landmark.shape))
for i, point in enumerate(landmark):
landmark_flip[i] = (1-point[0], point[1])
# for 5-point flip
landmark_flip[[0, 1]] = landmark_flip[[1, 0]]
landmark_flip[[3, 4]] = landmark_flip[[4, 3]]
# for 19-point flip
# landmark_flip[[0,9]] = landmark_flip[[9,0]]
# landmark_flip[[1,8]] = landmark_flip[[8,1]]
# landmark_flip[[2,7]] = landmark_flip[[7,2]]
# landmark_flip[[3,6]] = landmark_flip[[6,3]]
# landmark_flip[[4,11]] = landmark_flip[[11,4]]
# landmark_flip[[5,10]] = landmark_flip[[10,5]]
# landmark_flip[[12,14]] = landmark_flip[[14,12]]
# landmark_flip[[15,17]] = landmark_flip[[17,15]]
return (face_, landmark_flip)
def scale(landmark):
'''
scale the landmark from [0,1] to [-1,1]
'''
landmark_ = np.asarray(np.zeros(landmark.shape))
lanmark_ = (landmark-0.5)*2
return landmark_
def check_bbox(img, bbox):
'''
Check whether bbox is out of the range of the image
'''
img_w, img_h = img.shape
if bbox.x > 0 and bbox.y > 0 and bbox.right < img_w and bbox.bottom < img_h:
return True
else:
return False
def rotate(img, bbox, landmark, alpha):
"""
given a face with bbox and landmark, rotate with alpha
and return rotated face with bbox, landmark (absolute position)
"""
center = ((bbox.left+bbox.right)/2, (bbox.top+bbox.bottom)/2)
rot_mat = cv2.getRotationMatrix2D(center, alpha, 1)
img_rotated_by_alpha = cv2.warpAffine(img, rot_mat, img.shape)
landmark_ = np.asarray([(rot_mat[0][0]*x+rot_mat[0][1]*y+rot_mat[0][2],
rot_mat[1][0]*x+rot_mat[1][1]*y+rot_mat[1][2]) for (x, y) in landmark])
face = img_rotated_by_alpha[bbox.top:bbox.bottom+1, bbox.left:bbox.right+1]
return (face, landmark_)