Functions.js
6.04 KB
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
var response = JSON.parse([
`{
"area": 101090.2833,
"bbox": [719.4526, 244.1255, 182.7314, 553.2178],
"category_id": 1,
"keypoints": [
805.4897, 256.4165, 0.8422, 819.5366, 245.0034, 0.8773, 795.8325, 244.1255, 0.8664, 845.8745, 254.6606, 0.8105, 788.8091, 251.1489, 0.5631, 885.3813, 320.5054, 0.7525, 749.3022, 331.9185, 0.7706, 898.5503, 377.5708, 0.7825, 719.4526, 414.4438, 0.7897, 901.1841, 435.5142, 0.7782, 749.3022, 443.4155, 0.8086, 852.02, 504.8706, 0.6854, 785.2974, 511.894, 0.6738, 833.5835, 644.4614, 0.7899, 800.2222, 659.3862, 0.7655, 833.5835, 796.3433, 0.7055, 824.8042, 743.6675, 0.5165
],
"score": 0.7185
}`
]);
console.log(response);
//두 좌표 사이의 거리를 반환하는 함수
function distance(x1,y1,x2,y2){
var x = Math.abs(x1-x2);
var y = Math.abs(y1-y2);
var result = Math.hypot(x,y);
return result;
}
//두 길이의 차이를 %비로 반환하는 함수
function difference(d1, d2){
if(d1 > d2){
return (1 - (d2 / d1)) * 100;
}else if(d1 < d2){
return (1 - (d1 / d2)) * 100;
}else if(d1 == d2){
return 0;
}
}
//객체와 방향정보를 받아 자세정보를 반환하는 함수
function check_straight(jsonObj,position){ //jsonObj: API로 받은 JSON 객체, position: 사진의 방향정보
var trust_value = []; //17개의 신체부위 좌표에 대한 신뢰도를 저장할 배열
for(i=2; i<51; i+=3){
trust_value.push(jsonObj.keypoints[i]);
}
var x_position = []; //17개의 신체부위의 X좌표값을 저장할 배열
for(i=0; i<49; i+=3){
x_position.push(jsonObj.keypoints[i]);
}
var y_position = []; //17개의 신체부위의 Y좌표값을 저장할 배열
for(i=1; i<50; i+=3){
y_position.push(jsonObj.keypoints[i]);
}
if(position == 'front'){ //정면 사진일 경우
//사용할 데이터의 신뢰도가 0.4 미만이면 실행하지 않음
if(trust_value[3] < 0.4){
return 'error_low_trust_value (keypoint:4)'
}
if(trust_value[4] < 0.4){
return 'error_low_trust_value (keypoint:5)'
}
if(trust_value[5] < 0.4){
return 'error_low_trust_value (keypoint:6)'
}
if(trust_value[6] < 0.4){
return 'error_low_trust_value (keypoint:7)'
}
//왼쪽귀(4)-왼쪽어깨(6) 거리와 오른쪽귀(5)-오른쪽어깨(7) 거리가 30% 이상 차이날 경우 > 좌우편향
var d_left = distance(x_position[3], y_position[3], x_position[5], y_position[5]);
var d_right = distance(x_position[4], y_position[4], x_position[6], y_position[6]);
var gap = difference(d_left, d_right);
if(gap >= 30){ //기운 각도가 30도를 넘을 경우
if(d_left > d_right){ //오른쪽으로 기울인 경우
return 'leaning right by ' + gap + 'percent.';
}else if(d_left < d_right){ //왼쪽으로 기울인 경우
return 'leaning left by ' + gap + 'percent.';
}
}else{ //기운 각도가 30도 미만인 경우
return 'okay';
}
}else if(position == 'left'){ //좌측 측면 사진일 경우
//사용할 데이터의 신뢰도가 0.4 미만이면 실행하지 않음
if(trust_value[11] < 0.4){
return 'error_low_trust_value (keypoint:12)'
}
if(trust_value[5] < 0.4){
return 'error_low_trust_value (keypoint:6)'
}
if(trust_value[3] < 0.4){
return 'error_low_trust_value (keypoint:4)'
}
//엉덩이(12)-어깨(6) 각도가 70도 이하일 경우 > 굽은등
var minimum_angle1 = (180 * 70) / Math.PI;
var d1 = Math.abs(x_position[11]-x_position[5]);
var d2 = Math.abs(y_position[11]-y_position[5]);
var angle1 = Math.atan(d2/d1);
angle1 = (180 * angle1) / Math.PI; //라디안 > 육십분법 변환
if(angle1 <= minimum_angle1){
return 'bent_back';
}
//어깨(6)-귀(4) 각도가 30도 이상일 경우 > 거북목
var maximum_angle2 = (180 * 30) / Math.PI;
var d1 = Math.abs(y_position[3] - y_position[5]);
var d2 = Math.abs(x_position[3] - x_position[5]);
var angle2 = Math.atan(d2/d1);
angle2 = (180 * angle2) / Math.PI; //라디안 > 육십분법 변환
if(angle2 >= maximum_angle2){
return 'bent_neck';
}
//굽은등, 거북목 모두 없을 경우
return 'okay';
}else if(position == 'right'){ //우측 측면 사진일 경우
//사용할 데이터의 신뢰도가 0.4 미만이면 실행하지 않음
if(trust_value[12] < 0.4){
return 'error_low_trust_value (keypoint:13)'
}
if(trust_value[6] < 0.4){
return 'error_low_trust_value (keypoint:7)'
}
if(trust_value[4] < 0.4){
return 'error_low_trust_value (keypoint:5)'
}
//엉덩이(13)-어깨(7) 각도가 70도 이하일 경우 > 굽은등
var minimum_angle1 = (180 * 70) / Math.PI;
var d1 = Math.abs(x_position[12]-x_position[6]);
var d2 = Math.abs(y_position[12]-y_position[6]);
var angle1 = Math.atan(d2/d1);
angle1 = (180 * angle1) / Math.PI; //라디안 > 육십분법 변환
if(angle1 <= minimum_angle1){
return 'bent_back';
}
//어깨(7)-귀(5) 각도가 30도 이상일 경우 > 거북목
var maximum_angle2 = (180 * 30) / Math.PI;
var d1 = Math.abs(y_position[4] - y_position[6]);
var d2 = Math.abs(x_position[4] - x_position[6]);
var angle2 = Math.atan(d2/d1);
angle2 = (180 * angle2) / Math.PI; //라디안 > 육십분법 변환
if(angle2 >= maximum_angle2){
return 'bent_neck';
}
//굽은등, 거북목 모두 없을 경우
return 'okay';
}
}
console.log(check_straight(response,'front'));
console.log(check_straight(response,'left'));
console.log(check_straight(response,'right'));