Spaces:
Configuration error
Configuration error
| # 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_) | |