import sys import os from os.path import join from pathlib import Path import time import numpy as np import cv2 as cv import dlib from PIL import Image import matplotlib.pyplot as plt from app.utils import logger_utils, file_utils, im_utils, display_utils, draw_utils from app.utils import plot_utils from app.processors import face_detector, face_landmarks from app.models.data_store import DataStore @celery.task(bind=True) def fullmonte_task(self, uuid_name): return # TOOD add selective testing opt_run_pose = True opt_run_2d_68 = True opt_run_3d_68 = True opt_run_3d_68 = True # ------------------------------------------------- # init here log = logger_utils.Logger.getLogger() # load image im = cv.imread(opt_fp_in) im_resized = im_utils.resize(im, width=opt_size[0], height=opt_size[1]) # ---------------------------------------------------------------------------- # detect face face_detector = face_detector.DetectorDLIBCNN(gpu=opt_gpu) # -1 for CPU log.info('detecting face...') st = time.time() bboxes = face_detector.detect(im_resized, largest=True) bbox = bboxes[0] dim = im_resized.shape[:2][::-1] bbox_dim = bbox.to_dim(dim) if not bbox: log.error('no face detected') return else: log.info(f'Detected face in {(time.time() - st):.2f}s') log.info('') # ---------------------------------------------------------------------------- # detect 3D landmarks log.info('loading 3D landmark generator files...') landmark_detector_3d_68 = face_landmarks.FaceAlignment3D_68(gpu=opt_gpu) # -1 for CPU log.info('generating 3D landmarks...') st = time.time() points_3d_68 = landmark_detector_3d_68.landmarks(im_resized, bbox_dim.to_xyxy()) log.info(f'generated 3D landmarks in {(time.time() - st):.2f}s') log.info('') # ---------------------------------------------------------------------------- # generate 3D GIF animation log.info('generating 3D animation...') if not opt_fp_out: fpp_im = Path(opt_fp_in) fp_out = join(fpp_im.parent, f'{fpp_im.stem}_anim.gif') else: fp_out = opt_fp_out st = time.time() plot_utils.generate_3d_landmark_anim(np.array(points_3d_68), fp_out, size=opt_gif_size, num_frames=opt_gif_frames) log.info(f'Generated animation in {(time.time() - st):.2f}s') log.info(f'Saved to: {fp_out}') log.info('') # ---------------------------------------------------------------------------- # generate face vectors, only to test if feature extraction works log.info('initialize face recognition model...') from app.processors import face_recognition face_rec = face_recognition.RecognitionDLIB() st = time.time() log.info('generating face vector...') vec = face_rec.vec(im_resized, bbox_dim) log.info(f'generated face vector in {(time.time() - st):.2f}s') log.info('') # ---------------------------------------------------------------------------- # generate 68 point landmarks using dlib log.info('initializing face landmarks 68 dlib...') from app.processors import face_landmarks landmark_detector_2d_68 = face_landmarks.Dlib2D_68() log.info('generating 2D 68PT landmarks...') st = time.time() points_2d_68 = landmark_detector_2d_68.landmarks(im_resized, bbox_dim) log.info(f'generated 2D 68PT face landmarks in {(time.time() - st):.2f}s') log.info('') # ---------------------------------------------------------------------------- # generate pose from 68 point 2D landmarks if opt_run_pose: log.info('initialize pose...') from app.processors import face_pose pose_detector = face_pose.FacePoseDLIB() log.info('generating pose...') st = time.time() pose_data = pose_detector.pose(points_2d_68, dim) log.info(f'generated pose {(time.time() - st):.2f}s') log.info('') # ---------------------------------------------------------------------------- # generate pose from 68 point 2D landmarks # done self.log.debug('Add age real') self.log.debug('Add age apparent') self.log.debug('Add gender') # 3DDFA self.log.debug('Add depth') self.log.debug('Add pncc') # TODO self.log.debug('Add 3D face model') self.log.debug('Add face texture flat') self.log.debug('Add ethnicity') # display if opt_display: # draw bbox # draw 3d landmarks im_landmarks_3d_68 = im_resized.copy() draw_utils.draw_landmarks3D(im_landmarks_3d_68, points_3d_68) draw_utils.draw_bbox(im_landmarks_3d_68, bbox_dim) # draw 2d landmarks im_landmarks_2d_68 = im_resized.copy() draw_utils.draw_landmarks2D(im_landmarks_2d_68, points_2d_68) draw_utils.draw_bbox(im_landmarks_2d_68, bbox_dim) # draw pose if opt_run_pose: im_pose = im_resized.copy() draw_utils.draw_pose(im_pose, pose_data['point_nose'], pose_data['points']) draw_utils.draw_degrees(im_pose, pose_data) # draw animated GIF im = Image.open(fp_out) im_frames = [] duration = im.info['duration'] try: while True: im.seek(len(im_frames)) mypalette = im.getpalette() im.putpalette(mypalette) im_jpg = Image.new("RGB", im.size) im_jpg.paste(im) im_np = im_utils.pil2np(im_jpg.copy()) im_frames.append(im_np) except EOFError: pass # end of GIF sequence n_frames = len(im_frames) frame_number = 0 while True: # show all images here cv.imshow('Original', im_resized) cv.imshow('2D 68PT Landmarks', im_landmarks_2d_68) cv.imshow('3D 68PT Landmarks', im_landmarks_3d_68) cv.imshow('Pose', im_pose) cv.imshow('3D 68pt GIF', im_frames[frame_number]) frame_number = (frame_number + 1) % n_frames k = cv.waitKey(duration) & 0xFF if k == 27 or k == ord('q'): # ESC cv.destroyAllWindows() sys.exit() elif k != 255: # any key to continue break