File size: 2,071 Bytes
901e379
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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

import cv2
import numpy as np
import torch
from face_landmark.MobileFaceNet import MobileFaceNet

model_landmark = MobileFaceNet(input_size=64, embedding_size=136)
model_landmark.load_state_dict(torch.load("./face_recognition/face_landmark/vfl_1.02_578_6.734591484069824.pth.tar", map_location=torch.device('cpu'))['state_dict'])
model_landmark.eval()

def get_face_landmark(gray_img, bounding_box):
    image = gray_img
    box = bounding_box

    nHeight, nWidth = image.shape

    rLeftMargin = 0.05
    rTopMargin = 0.00
    rRightMargin = 0.05
    rBottomMargin = 0.10

    rW = box[2] - box[0]
    rH = box[3] - box[1]
    cx = (box[0] + box[2]) / 2
    cy = (box[1] + box[3]) / 2
    sz = pow(rW * rH, 0.5)
    rX = cx - sz / 2
    rY = cy - sz / 2
    rW = sz
    rH = sz
    
    #get image range to get face landmark from face rect
    iExFaceX = int(rX - rLeftMargin * rW)
    iExFaceY = int(rY - rTopMargin * rH)
    iExFaceW = int((1 + (rLeftMargin + rRightMargin)) * rW)
    iExFaceH = int((1 + (rTopMargin + rBottomMargin)) * rH)

    iExFaceX = np.clip(iExFaceX, 0, nWidth - 1)
    iExFaceY = np.clip(iExFaceY, 0, nHeight - 1)
    iExFaceW = np.clip(iExFaceX + iExFaceW, 0, nWidth - 1) - iExFaceX
    iExFaceH = np.clip(iExFaceY + iExFaceH, 0, nHeight - 1) - iExFaceY

    #crop face image in range to face landmark
    image = image[iExFaceY:iExFaceY+iExFaceH, iExFaceX:iExFaceX+iExFaceW]
    #normalize croped face image
    image = cv2.resize(image, (64, 64), cv2.INTER_LINEAR)
    # cv2.imwrite("D:/crop.png", image)
    image = image / 256
    image = torch.from_numpy(image.astype(np.float32))
    #convert mask_align_image from type [n,n] to [1,1,n,n]
    image = image.unsqueeze(0).unsqueeze(0)

    #get landmark fron croped face image
    landmark = model_landmark(image)
    #reshape face landmark and convert to image coordinates
    landmark = landmark.reshape(68, 2)
    landmark[:,0] = landmark[:,0] * iExFaceW + iExFaceX
    landmark[:,1] = landmark[:,1] * iExFaceH + iExFaceY
    
    landmark = landmark.reshape(-1)

    return landmark