Showing
2 changed files
with
116 additions
and
1 deletions
straight-up/src/AnalysisPose.js
0 → 100644
1 | +//두 좌표 사이의 거리를 반환하는 함수 | ||
2 | +function distance(x1, y1, x2, y2) { | ||
3 | + var x = Math.abs(x1 - x2); | ||
4 | + var y = Math.abs(y1 - y2); | ||
5 | + var result = Math.hypot(x, y); | ||
6 | + return result; | ||
7 | +} | ||
8 | + | ||
9 | +//두 길이의 차이를 %비로 반환하는 함수 | ||
10 | +function difference(d1, d2) { | ||
11 | + if (d1 > d2) { | ||
12 | + return (1 - (d2 / d1)) * 100; | ||
13 | + } else if (d1 < d2) { | ||
14 | + return (1 - (d1 / d2)) * 100; | ||
15 | + } else if (d1 === d2) { | ||
16 | + return 0; | ||
17 | + } | ||
18 | +} | ||
19 | + | ||
20 | +//객체와 방향정보를 받아 자세정보를 반환하는 함수 | ||
21 | +const checkStraight = (resData, position) => { //resData: API로 받은 JSON 객체, position: 사진의 방향정보 | ||
22 | + var trust_value = []; //17개의 신체부위 좌표에 대한 신뢰도를 저장할 배열 | ||
23 | + var x_position = []; //17개의 신체부위의 X좌표값을 저장할 배열 | ||
24 | + var y_position = []; //17개의 신체부위의 Y좌표값을 저장할 배열 | ||
25 | + const neck_maximum_angle = (180 * 30) / Math.PI; //어깨-귀 각도가 30도 이상일 경우 > 거북목 | ||
26 | + const back_minimum_angle = (180 * 70) / Math.PI; //엉덩이-어깨 각도가 70도 이하일 경우 > 굽은등 | ||
27 | + let ear = 3; | ||
28 | + let shoulder = 5; | ||
29 | + let hip = 11; | ||
30 | + for (let i = 0; i < 49; i += 3) { | ||
31 | + x_position.push(resData[i]); | ||
32 | + y_position.push(resData[i + 1]); | ||
33 | + trust_value.push(resData[i + 2]); | ||
34 | + } | ||
35 | + if (position === 'front') { //정면 사진일 경우 | ||
36 | + //사용할 데이터의 신뢰도가 0.4 미만이면 실행하지 않음 | ||
37 | + if (trust_value[ear] < 0.4) { | ||
38 | + return 'error_low_trust_value (keypoint:left_ear:4)' | ||
39 | + } | ||
40 | + if (trust_value[ear+1] < 0.4) { | ||
41 | + return 'error_low_trust_value (keypoint:right_ear:5)' | ||
42 | + } | ||
43 | + if (trust_value[shoulder] < 0.4) { | ||
44 | + return 'error_low_trust_value (keypoint:left_shoulder:6)' | ||
45 | + } | ||
46 | + if (trust_value[shoulder+1] < 0.4) { | ||
47 | + return 'error_low_trust_value (keypoint:right_shoulder_7)' | ||
48 | + } | ||
49 | + | ||
50 | + //왼쪽귀(4)-왼쪽어깨(6) 거리와 오른쪽귀(5)-오른쪽어깨(7) 거리가 30% 이상 차이날 경우 > 좌우편향 | ||
51 | + var d_left = distance(x_position[ear], y_position[ear], x_position[shoulder], y_position[shoulder]); | ||
52 | + var d_right = distance(x_position[ear+1], y_position[ear+1], x_position[shoulder+1], y_position[shoulder+1]); | ||
53 | + var gap = difference(d_left, d_right); | ||
54 | + | ||
55 | + if (gap >= 30) { //기운 각도가 30도를 넘을 경우 | ||
56 | + if (d_left > d_right) { //오른쪽으로 기울인 경우 | ||
57 | + return 'leaning right by ' + gap + 'percent.'; | ||
58 | + } else if (d_left < d_right) { //왼쪽으로 기울인 경우 | ||
59 | + return 'leaning left by ' + gap + 'percent.'; | ||
60 | + } | ||
61 | + } else { //기운 각도가 30도 미만인 경우 | ||
62 | + return 'okay'; | ||
63 | + } | ||
64 | + | ||
65 | + | ||
66 | + } | ||
67 | + else { | ||
68 | + if (position === 'right') { | ||
69 | + ear++; | ||
70 | + shoulder++; | ||
71 | + hip++; | ||
72 | + } | ||
73 | + if (trust_value[hip] < 0.4) { //사용할 데이터의 신뢰도가 0.4 미만이면 실행하지 않음 | ||
74 | + return `error_low_trust_value (keypoint:${position}hip)`; | ||
75 | + } | ||
76 | + if (trust_value[shoulder] < 0.4) { | ||
77 | + return `error_low_trust_value (keypoint:${position}shoulder)`; | ||
78 | + } | ||
79 | + if (trust_value[ear] < 0.4) { | ||
80 | + return `error_low_trust_value (keypoint:${position}ear)`; | ||
81 | + } | ||
82 | + //엉덩이(12)-어깨(6) 각도가 70도 이하일 경우 > 굽은등 | ||
83 | + | ||
84 | + var back_d1 = Math.abs(x_position[hip] - x_position[shoulder]); | ||
85 | + var back_d2 = Math.abs(y_position[hip] - y_position[shoulder]); | ||
86 | + var back_angle = Math.atan(back_d2 / back_d1); | ||
87 | + var back_angle_rad = (180 * back_angle) / Math.PI; //라디안 > 육십분법 변환 | ||
88 | + if (back_angle_rad <= back_minimum_angle) { | ||
89 | + return 'bent_back'; | ||
90 | + } | ||
91 | + //어깨(6)-귀(4) 각도가 30도 이상일 경우 > 거북목 | ||
92 | + var neck_d1 = Math.abs(y_position[ear] - y_position[shoulder]); | ||
93 | + var neck_d2 = Math.abs(x_position[ear] - x_position[shoulder]); | ||
94 | + var neck_angle = Math.atan(neck_d2 / neck_d1); | ||
95 | + var neck_angle_rad = (180 * neck_angle) / Math.PI; //라디안 > 육십분법 변환 | ||
96 | + if (neck_angle_rad >= neck_maximum_angle) { | ||
97 | + return 'bent_neck'; | ||
98 | + } | ||
99 | + //굽은등, 거북목 모두 없을 경우 | ||
100 | + return 'okay'; | ||
101 | + } | ||
102 | +} | ||
103 | + | ||
104 | +export default checkStraight; | ||
105 | +/* | ||
106 | +console.log(check_straight(response,'front')); | ||
107 | +console.log(check_straight(response,'left')); | ||
108 | +console.log(check_straight(response,'right')); | ||
109 | +*/ | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | import React, { useState } from 'react' | 1 | import React, { useState } from 'react' |
2 | import Header from './components/Header'; | 2 | import Header from './components/Header'; |
3 | +import checkStraight from './AnalysisPose'; | ||
3 | import './style/Main.css'; | 4 | import './style/Main.css'; |
4 | require('dotenv').config(); | 5 | require('dotenv').config(); |
5 | 6 | ||
... | @@ -37,7 +38,12 @@ export default function Main() { | ... | @@ -37,7 +38,12 @@ export default function Main() { |
37 | }, | 38 | }, |
38 | data: imageFormData | 39 | data: imageFormData |
39 | }).then(function (response) { | 40 | }).then(function (response) { |
40 | - console.log(JSON.stringify(response.data)); | 41 | + const resdata = response.data[0].keypoints; |
42 | + console.log(resdata[0]); | ||
43 | + const result = checkStraight(resdata, 'front'); | ||
44 | + console.log(result); | ||
45 | + | ||
46 | + // console.log(resdata[0] === ) | ||
41 | }).catch(function (error) { | 47 | }).catch(function (error) { |
42 | if (error.response) { | 48 | if (error.response) { |
43 | // 요청이 이루어졌으며 서버가 2xx의 범위를 벗어나는 상태 코드로 응답했습니다. | 49 | // 요청이 이루어졌으며 서버가 2xx의 범위를 벗어나는 상태 코드로 응답했습니다. | ... | ... |
-
Please register or login to post a comment