summaryrefslogtreecommitdiff
path: root/megapixels/commands/demo/face_landmarks_2d.py
blob: 145a12a6db210ecbc7f959b6e9ad3a1528db4fc0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
"""
Crop images to prepare for training
"""

import click

from app.settings import types
from app.utils import click_utils
from app.settings import app_cfg as cfg


@click.command()
@click.option('-i', '--input', 'opt_fp_in', default=None, required=True,
  help='Image filepath')
@click.option('--size', 'opt_size', 
  type=(int, int), default=(300, 300),
  help='Output image size')
@click.option('--display/--no-display', 'opt_display', is_flag=True, default=True,
  help='Display detections to debug')
@click.pass_context
def cli(ctx, opt_fp_in, opt_size, opt_display):
  """2D 68-point landmarks"""
  
  import sys
  import os
  from os.path import join
  from pathlib import Path
  import time
  
  from tqdm import tqdm
  import numpy as np
  import pandas as pd
  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


  # -------------------------------------------------
  # init here


  log = logger_utils.Logger.getLogger()

  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.DetectorCVDNN()
  log.info('detecting face...')
  st = time.time()
  bboxes = face_detector.detect(im_resized, largest=True)
  bbox_norm = bboxes[0]
  dim = im_resized.shape[:2][::-1]
  bbox_dim = bbox_norm.to_dim(dim)
  if not bbox_norm:
    log.error('no face detected')
    return
  else:
    log.info(f'Detected face in {(time.time() - st):.2f}s')
  

  # ----------------------------------------------------------------------------
  # generate 68 point landmarks using dlib
  
  log.info('initializing face landmarks 68 dlib...')
  landmark_detector_2d_68 = face_landmarks.Dlib2D_68()
  log.info('generating 2D 68PT landmarks...')
  st = time.time()
  points_norm = landmark_detector_2d_68.landmarks(im_resized, bbox_norm)
  log.info(f'generated 2D 68PT face landmarks in {(time.time() - st):.2f}s')


  # ----------------------------------------------------------------------------
  # display

  if opt_display:

    # draw 2d landmarks
    im_lmarks = im_resized.copy()
    im_lmarks = draw_utils.draw_bbox(im_lmarks, bbox_norm)
    im_lmarks = draw_utils.draw_landmarks2D(im_lmarks, points_norm)

    # show all images here
    cv.imshow('2D 68PT Landmarks', im_lmarks)
    display_utils.handle_keyboard()