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