Spaces:
Runtime error
Runtime error
| #2024-12-04 add forehead_chin_points_pair,estimate_rotatios | |
| #formart is first,second,middle | |
| #2024-12-05 deg to rad | |
| #2024-12-06 get_feature_ratios_cordinate | |
| #2024-12-08 create_detail_labels | |
| horizontal_points_pair = [ | |
| [ | |
| "inner-eye",133,362,6 | |
| ], | |
| [ | |
| "outer-eye",33,263,168 | |
| ], | |
| [ | |
| "mouth",61,291,13 | |
| ], | |
| [ | |
| "eyeblow",105,334,9 | |
| ],[ | |
| "nose",98,327,2 | |
| ],[ | |
| "contour",143,372,6 | |
| ], | |
| [ | |
| "chin",32,262,200 | |
| ], [ | |
| "cheek",123,352,5 | |
| ], [ | |
| "cheek2",192,416,0 | |
| ], [ | |
| "nose1",129,358,1 | |
| ], [ | |
| "nose2",47,277,195 | |
| ], [ | |
| "cheek3",206,426,2 | |
| ], [ | |
| "cheek4",101,330,5 | |
| ], [ | |
| "cheek5",153,380,6 | |
| ] | |
| ] | |
| def angle_between_points_and_x_axis(A, B): | |
| """ | |
| 2点A, Bを結ぶ線分とx軸の正方向との角度を計算する | |
| Args: | |
| A: A点の座標 (x, y) のタプルまたはNumPy配列 | |
| B: B点の座標 (x, y) のタプルまたはNumPy配列 | |
| Returns: | |
| 角度(ラジアン) | |
| """ | |
| x = B[0] - A[0] | |
| y = B[1] - A[1] | |
| return np.arctan2(y, x) | |
| vertical_points_pair=[ | |
| ["forehead-chin",8,1,199] | |
| ] | |
| #formart is first,second,third | |
| feature_ratios_indices=[ | |
| ["forehead",67,69,66], | |
| ["forehead",10,151,9], | |
| ["forehead",297,299,296], | |
| #["forehead-chin",8,1,199], | |
| #["middle-chin",168,199,2], | |
| ["middle",168,195,2], | |
| ["right",153,101,206], | |
| ["right2",133,47,129], | |
| ["left",380,330,426], | |
| ["left2",362,277,358], | |
| ["right-contour",143,123,192], | |
| ["left-contour",372,352,416], | |
| ["nose",4,1,2], | |
| ] | |
| feature_angles_indices =[ | |
| ["forehead1",9,6], | |
| ["forehead2",69,299], | |
| ["eyes1",133,362], | |
| ["eyes2",133,33], | |
| ["eyes3",362,263], | |
| ["nose1",6,2], | |
| ["nose1",98,327], | |
| ["nose1",2,1], | |
| ["nose1",1,6], | |
| ["lip",61,291], | |
| ["lip",0,17], | |
| ["jaw",152,199], | |
| ["jaw",194,418], | |
| ["cheek",118,214], | |
| ["cheek",347,434], | |
| ["contour",389,397], | |
| ["contour",127,172], | |
| ] | |
| def get_feature_angles_cordinate(face_landmarks,angles=feature_angles_indices): | |
| points = [get_normalized_cordinate(face_landmarks,i) for i in range(468)] | |
| return get_feature_angles_cordinate_points(points,angles) | |
| def get_feature_angles_cordinate_points(points,angles=feature_angles_indices): | |
| cordinates=[] | |
| result_angles = [] | |
| for indices in angles: | |
| points_cordinate = get_points_by_indices(points,indices[1:])#first one is label | |
| angle_rad =angle_between_points_and_x_axis(points_cordinate[0][:2],points_cordinate[1][:2]) | |
| result_angles.append(angle_rad) | |
| cordinates.append(points_cordinate) | |
| return cordinates,result_angles | |
| def get_feature_ratios_cordinate(face_landmarks,ratios=feature_ratios_indices): | |
| points = [get_normalized_cordinate(face_landmarks,i) for i in range(468)] | |
| return get_feature_angles_cordinate_points(points,ratios) | |
| def ratios_cordinates(cordinates): | |
| distance_a = calculate_distance(cordinates[0],cordinates[1]) | |
| distance_b = calculate_distance(cordinates[1],cordinates[2]) | |
| if distance_a == 0 or distance_b == 0: | |
| return 0 | |
| else: | |
| return distance_a/distance_b | |
| def get_feature_ratios_cordinate_points(points,ratios=feature_ratios_indices): | |
| cordinates=[] | |
| result_ratios = [] | |
| for indices in ratios: | |
| points_cordinate = get_points_by_indices(points,indices[1:])#first one is label | |
| result_ratios.append(ratios_cordinates(points_cordinate)) | |
| cordinates.append(points_cordinate) | |
| return cordinates,result_ratios | |
| #vertical-format | |
| forehead_chin_points_pair=[ | |
| [ | |
| "forehead-chin",8,1,199 | |
| ] | |
| ] | |
| horizontal_contour_points_pair=[ | |
| [ | |
| "contour",143,6,372 | |
| ] | |
| ] | |
| import math | |
| def calculate_distance(xy, xy2): | |
| return math.sqrt((xy2[0] - xy[0])**2 + (xy2[1] - xy[1])**2) | |
| def create_detail_labels(values,radian=False,pair_data=horizontal_points_pair): | |
| assert len(values) == len(pair_data) | |
| lines = [] | |
| for i,value in enumerate(values): | |
| if radian: | |
| value=math.degrees(value) | |
| lines.append(f"{pair_data[i][0]} = {value:.2f}") | |
| return "\n".join(lines) | |
| import numpy as np | |
| from mp_utils import get_normalized_cordinate | |
| def estimate_horizontal(face_landmarks,pair_data = horizontal_points_pair): | |
| points = [get_normalized_cordinate(face_landmarks,i) for i in range(468)] | |
| return estimate_horizontal_points(points,pair_data) | |
| def get_points_by_indices(face_landmark_points,indices): | |
| points = [face_landmark_points[index] for index in indices] | |
| return points | |
| def normalized_to_pixel(cordinates,width,height): | |
| pixel_point = [[pt[0]*width,pt[1]*height] for pt in cordinates] | |
| return pixel_point | |
| def estimate_horizontal_points(face_landmark_points,pair_data = horizontal_points_pair): | |
| z_angles=[] | |
| y_ratios = [] | |
| cordinates = [] | |
| for compare_point in pair_data: | |
| points_cordinate = get_points_by_indices(face_landmark_points,compare_point[1:])#first one is label | |
| cordinates.append(points_cordinate) | |
| angle_rad =angle_between_points_and_x_axis(points_cordinate[0][:2],points_cordinate[1][:2]) | |
| #angle_deg = np.degrees(angle_rad) | |
| z_angles.append(angle_rad) | |
| right_distance = calculate_distance(points_cordinate[0],points_cordinate[2]) | |
| left_distance = calculate_distance(points_cordinate[1],points_cordinate[2]) | |
| y_ratios.append(left_distance/(right_distance+left_distance)) | |
| return z_angles,y_ratios,cordinates,pair_data | |
| def estimate_vertical(face_landmarks,pair_data = vertical_points_pair): | |
| points = [get_normalized_cordinate(face_landmarks,i) for i in range(468)] | |
| return estimate_vertical_points(points,pair_data) | |
| def estimate_rotations_v2(face_landmarker_result): | |
| points = get_normalized_landmarks(face_landmarker_result.face_landmarks,True) | |
| values1_text=estimate_rotations_point(points) | |
| result3,ratios = get_feature_ratios_cordinate_points(points) | |
| key_cordinates,angles = get_feature_angles_cordinate_points(points) | |
| angles_str=[str(angle) for angle in angles] | |
| ratios_str=[str(ratio) for ratio in ratios] | |
| return f"{values1_text},{','.join(angles_str)},{','.join(ratios_str)}" | |
| from mp_utils import get_normalized_landmarks | |
| def estimate_rotations(face_landmarker_result): | |
| points = get_normalized_landmarks(face_landmarker_result.face_landmarks,True) | |
| return estimate_rotations_point(points) | |
| def estimate_rotations_point(points): | |
| z_angles,y_ratios,h_cordinates,_ =estimate_horizontal_points(points) | |
| z_angle = np.mean(z_angles) | |
| y_ratio = np.mean(y_ratios) | |
| _,x_ratios,h_cordinates,_ =estimate_vertical_points(points) | |
| x_ratio = np.mean(x_ratios) | |
| x_angle,_,_,_ =estimate_vertical_points(points,forehead_chin_points_pair) | |
| x_angle=np.mean(x_angle) | |
| length_ratio = estimate_ratio(points) | |
| result = f"{x_ratio:.6f},{y_ratio:.6f},{z_angle:.6f},{x_angle:.6f},{length_ratio:.6f}" | |
| return result | |
| def estimate_ratio(face_landmark_points,a_line=forehead_chin_points_pair,b_line=horizontal_contour_points_pair): | |
| points_cordinate_a = get_points_by_indices(face_landmark_points,a_line[0][1:])#for campatible | |
| points_cordinate_b = get_points_by_indices(face_landmark_points,b_line[0][1:]) | |
| distance_a = calculate_distance(points_cordinate_a[0],points_cordinate_a[2]) | |
| distance_b = calculate_distance(points_cordinate_b[0],points_cordinate_b[2]) | |
| if distance_a == 0 or distance_b == 0: | |
| return 0 | |
| else: | |
| return distance_a/distance_b | |
| def estimate_vertical_points(face_landmarks,pair_data = vertical_points_pair): | |
| angles = [] | |
| ratios = [] | |
| cordinates = [] | |
| for compare_point in pair_data: | |
| points_cordinate = get_points_by_indices(face_landmarks,compare_point[1:])#first one is label | |
| cordinates.append(points_cordinate) | |
| angle_rad =angle_between_points_and_x_axis(points_cordinate[0][:2],points_cordinate[2][:2]) | |
| #angle_deg = np.degrees(angle_rad) | |
| angles.append(angle_rad) | |
| up_distance = calculate_distance(points_cordinate[0],points_cordinate[1]) | |
| down_distance = calculate_distance(points_cordinate[1],points_cordinate[2]) | |
| ratios.append(down_distance/(down_distance+up_distance)) | |
| return angles,ratios,cordinates,pair_data | |
| def mean_std_label(values,radian=False): | |
| mean_value = np.mean(values) | |
| std_value = np.std(values) | |
| if radian: | |
| mean_value = math.degrees(mean_value) | |
| std_value = math.degrees(std_value) | |
| value_text = f"mean:{mean_value:.3f} std:{std_value:.3f}" | |
| return value_text |