김원진

functions for the straight-up project / WonjinKim

1 +var response = JSON.parse([
2 + `{
3 + "area": 101090.2833,
4 + "bbox": [719.4526, 244.1255, 182.7314, 553.2178],
5 + "category_id": 1,
6 + "keypoints": [
7 + 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
8 + ],
9 + "score": 0.7185
10 + }`
11 +]);
12 +console.log(response);
13 +
14 +//두 좌표 사이의 거리를 반환하는 함수
15 +function distance(x1,y1,x2,y2){
16 + var x = Math.abs(x1-x2);
17 + var y = Math.abs(y1-y2);
18 + var result = Math.hypot(x,y);
19 + return result;
20 +}
21 +
22 +//두 길이의 차이를 %비로 반환하는 함수
23 +function difference(d1, d2){
24 + if(d1 > d2){
25 + return (1 - (d2 / d1)) * 100;
26 + }else if(d1 < d2){
27 + return (1 - (d1 / d2)) * 100;
28 + }else if(d1 == d2){
29 + return 0;
30 + }
31 +}
32 +
33 +//객체와 방향정보를 받아 자세정보를 반환하는 함수
34 +function check_straight(jsonObj,position){ //jsonObj: API로 받은 JSON 객체, position: 사진의 방향정보
35 + var trust_value = []; //17개의 신체부위 좌표에 대한 신뢰도를 저장할 배열
36 + for(i=2; i<51; i+=3){
37 + trust_value.push(jsonObj.keypoints[i]);
38 + }
39 + var x_position = []; //17개의 신체부위의 X좌표값을 저장할 배열
40 + for(i=0; i<49; i+=3){
41 + x_position.push(jsonObj.keypoints[i]);
42 + }
43 + var y_position = []; //17개의 신체부위의 Y좌표값을 저장할 배열
44 + for(i=1; i<50; i+=3){
45 + y_position.push(jsonObj.keypoints[i]);
46 + }
47 +
48 + if(position == 'front'){ //정면 사진일 경우
49 + //사용할 데이터의 신뢰도가 0.4 미만이면 실행하지 않음
50 + if(trust_value[3] < 0.4){
51 + return 'error_low_trust_value (keypoint:4)'
52 + }
53 + if(trust_value[4] < 0.4){
54 + return 'error_low_trust_value (keypoint:5)'
55 + }
56 + if(trust_value[5] < 0.4){
57 + return 'error_low_trust_value (keypoint:6)'
58 + }
59 + if(trust_value[6] < 0.4){
60 + return 'error_low_trust_value (keypoint:7)'
61 + }
62 +
63 + //왼쪽귀(4)-왼쪽어깨(6) 거리와 오른쪽귀(5)-오른쪽어깨(7) 거리가 30% 이상 차이날 경우 > 좌우편향
64 + var d_left = distance(x_position[3], y_position[3], x_position[5], y_position[5]);
65 + var d_right = distance(x_position[4], y_position[4], x_position[6], y_position[6]);
66 + var gap = difference(d_left, d_right);
67 +
68 + if(gap >= 30){ //기운 각도가 30도를 넘을 경우
69 + if(d_left > d_right){ //오른쪽으로 기울인 경우
70 + return 'leaning right by ' + gap + 'percent.';
71 + }else if(d_left < d_right){ //왼쪽으로 기울인 경우
72 + return 'leaning left by ' + gap + 'percent.';
73 + }
74 + }else{ //기운 각도가 30도 미만인 경우
75 + return 'okay';
76 + }
77 +
78 +
79 + }else if(position == 'left'){ //좌측 측면 사진일 경우
80 + //사용할 데이터의 신뢰도가 0.4 미만이면 실행하지 않음
81 + if(trust_value[11] < 0.4){
82 + return 'error_low_trust_value (keypoint:12)'
83 + }
84 + if(trust_value[5] < 0.4){
85 + return 'error_low_trust_value (keypoint:6)'
86 + }
87 + if(trust_value[3] < 0.4){
88 + return 'error_low_trust_value (keypoint:4)'
89 + }
90 +
91 + //엉덩이(12)-어깨(6) 각도가 70도 이하일 경우 > 굽은등
92 + var minimum_angle1 = (180 * 70) / Math.PI;
93 + var d1 = Math.abs(x_position[11]-x_position[5]);
94 + var d2 = Math.abs(y_position[11]-y_position[5]);
95 + var angle1 = Math.atan(d2/d1);
96 + angle1 = (180 * angle1) / Math.PI; //라디안 > 육십분법 변환
97 + if(angle1 <= minimum_angle1){
98 + return 'bent_back';
99 + }
100 +
101 + //어깨(6)-귀(4) 각도가 30도 이상일 경우 > 거북목
102 + var maximum_angle2 = (180 * 30) / Math.PI;
103 + var d1 = Math.abs(y_position[3] - y_position[5]);
104 + var d2 = Math.abs(x_position[3] - x_position[5]);
105 + var angle2 = Math.atan(d2/d1);
106 + angle2 = (180 * angle2) / Math.PI; //라디안 > 육십분법 변환
107 + if(angle2 >= maximum_angle2){
108 + return 'bent_neck';
109 + }
110 +
111 + //굽은등, 거북목 모두 없을 경우
112 + return 'okay';
113 +
114 + }else if(position == 'right'){ //우측 측면 사진일 경우
115 + //사용할 데이터의 신뢰도가 0.4 미만이면 실행하지 않음
116 + if(trust_value[12] < 0.4){
117 + return 'error_low_trust_value (keypoint:13)'
118 + }
119 + if(trust_value[6] < 0.4){
120 + return 'error_low_trust_value (keypoint:7)'
121 + }
122 + if(trust_value[4] < 0.4){
123 + return 'error_low_trust_value (keypoint:5)'
124 + }
125 +
126 + //엉덩이(13)-어깨(7) 각도가 70도 이하일 경우 > 굽은등
127 + var minimum_angle1 = (180 * 70) / Math.PI;
128 + var d1 = Math.abs(x_position[12]-x_position[6]);
129 + var d2 = Math.abs(y_position[12]-y_position[6]);
130 + var angle1 = Math.atan(d2/d1);
131 + angle1 = (180 * angle1) / Math.PI; //라디안 > 육십분법 변환
132 + if(angle1 <= minimum_angle1){
133 + return 'bent_back';
134 + }
135 +
136 + //어깨(7)-귀(5) 각도가 30도 이상일 경우 > 거북목
137 + var maximum_angle2 = (180 * 30) / Math.PI;
138 + var d1 = Math.abs(y_position[4] - y_position[6]);
139 + var d2 = Math.abs(x_position[4] - x_position[6]);
140 + var angle2 = Math.atan(d2/d1);
141 + angle2 = (180 * angle2) / Math.PI; //라디안 > 육십분법 변환
142 + if(angle2 >= maximum_angle2){
143 + return 'bent_neck';
144 + }
145 +
146 + //굽은등, 거북목 모두 없을 경우
147 + return 'okay';
148 + }
149 +
150 +}
151 +
152 +console.log(check_straight(response,'front'));
153 +console.log(check_straight(response,'left'));
154 +console.log(check_straight(response,'right'));
...\ No newline at end of file ...\ No newline at end of file