File size: 4,185 Bytes
a4b5d57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import math

import mediapipe as mp
from mediapipe.tasks import python
from mediapipe.tasks.python import vision
from mediapipe.framework.formats import landmark_pb2
from mediapipe import solutions
import numpy as np


def calculate_distance(p1, p2):
  """

  """
  return math.sqrt((p2[0] - p1[0])**2 + (p2[1] - p1[1])**2)
def to_int_points(points):
    ints=[]
    for pt in points:
        #print(pt)
        value = [int(pt[0]),int(pt[1])]
        #print(value)
        ints.append(value)
    return ints

debug = False
def divide_line_to_points(points,divided): # return divided + 1
    total_length = 0
    line_length_list = []
    for i in range(len(points)-1):
        pt_length = calculate_distance(points[i],points[i+1])
        total_length += pt_length
        line_length_list.append(pt_length)
     
    splited_length = total_length/divided

    def get_new_point(index,lerp):
        pt1 = points[index]
        pt2 = points[index+1]
        diff = [pt2[0] - pt1[0], pt2[1]-pt1[1]]
        new_point = [pt1[0]+diff[0]*lerp,pt1[1]+diff[1]*lerp]
        if debug:
          print(f"pt1 ={pt1}  pt2 ={pt2} diff={diff} new_point={new_point}")

        return new_point

    if debug:
      print(f"{total_length} splitted = {splited_length} line-length-list = {len(line_length_list)}")
    splited_points=[points[0]]
    for i in range(1,divided):
        need_length = splited_length*i
        if debug:
          print(f"{i} need length = {need_length}")
        current_length = 0
        for j in range(len(line_length_list)):
            line_length = line_length_list[j]
            current_length+=line_length
            if current_length>need_length:
                if debug:
                  print(f"over need length index = {j} current={current_length}")
                diff = current_length - need_length
            
                lerp_point = 1.0 - (diff/line_length)
                if debug:
                  print(f"over = {diff} lerp ={lerp_point}")
                new_point = get_new_point(j,lerp_point)
                
                splited_points.append(new_point)
                break
        
    splited_points.append(points[-1]) # last one
    splited_points=to_int_points(splited_points)    
         
    if debug:
      print(f"sp={len(splited_points)}")
    return splited_points



def expand_bbox(bbox,left=5,top=5,right=5,bottom=5):
   left_pixel = bbox[2]*(float(left)/100)
   top_pixel = bbox[3]*(float(top)/100)
   right_pixel = bbox[2]*(float(right)/100)
   bottom_pixel = bbox[3]*(float(bottom)/100)
   new_box = list(bbox)
   new_box[0] -=left_pixel
   new_box[1] -=top_pixel
   new_box[2] +=left_pixel+right_pixel
   new_box[3] +=top_pixel+bottom_pixel
   return new_box

#normalized value index see mp_constants
def get_normalized_cordinate(face_landmarks_list,index):
    x=face_landmarks_list[0][index].x
    y=face_landmarks_list[0][index].y
    return x,y

def get_pixel_cordinate(face_landmarks_list,landmark,width,height):
    point = get_normalized_cordinate(face_landmarks_list,landmark)
    return int(point[0]*width),int(point[1]*height)

def get_pixel_cordinate_list(face_landmarks_list,indices,width,height):
   cordinates = []
   for index in indices:
      cordinates.append(get_pixel_cordinate(face_landmarks_list,index,width,height))
   return cordinates

def extract_landmark(image_data,model_path="face_landmarker.task"):
  BaseOptions = mp.tasks.BaseOptions
  FaceLandmarker = mp.tasks.vision.FaceLandmarker
  FaceLandmarkerOptions = mp.tasks.vision.FaceLandmarkerOptions
  VisionRunningMode = mp.tasks.vision.RunningMode

  options = FaceLandmarkerOptions(
      base_options=BaseOptions(model_asset_path=model_path),
      running_mode=VisionRunningMode.IMAGE
      ,min_face_detection_confidence=0, min_face_presence_confidence=0
      )
  
  with FaceLandmarker.create_from_options(options) as landmarker:
    if isinstance(image_data,str):
        mp_image = mp.Image.create_from_file(image_data)
    else:
        mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=np.asarray(image_data))
    face_landmarker_result = landmarker.detect(mp_image)
    return mp_image,face_landmarker_result