MrMirror21

refactor analysis function & connect with main-page

//두 좌표 사이의 거리를 반환하는 함수
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;
}
}
//객체와 방향정보를 받아 자세정보를 반환하는 함수
const checkStraight = (resData, position) => { //resData: API로 받은 JSON 객체, position: 사진의 방향정보
var trust_value = []; //17개의 신체부위 좌표에 대한 신뢰도를 저장할 배열
var x_position = []; //17개의 신체부위의 X좌표값을 저장할 배열
var y_position = []; //17개의 신체부위의 Y좌표값을 저장할 배열
const neck_maximum_angle = (180 * 30) / Math.PI; //어깨-귀 각도가 30도 이상일 경우 > 거북목
const back_minimum_angle = (180 * 70) / Math.PI; //엉덩이-어깨 각도가 70도 이하일 경우 > 굽은등
let ear = 3;
let shoulder = 5;
let hip = 11;
for (let i = 0; i < 49; i += 3) {
x_position.push(resData[i]);
y_position.push(resData[i + 1]);
trust_value.push(resData[i + 2]);
}
if (position === 'front') { //정면 사진일 경우
//사용할 데이터의 신뢰도가 0.4 미만이면 실행하지 않음
if (trust_value[ear] < 0.4) {
return 'error_low_trust_value (keypoint:left_ear:4)'
}
if (trust_value[ear+1] < 0.4) {
return 'error_low_trust_value (keypoint:right_ear:5)'
}
if (trust_value[shoulder] < 0.4) {
return 'error_low_trust_value (keypoint:left_shoulder:6)'
}
if (trust_value[shoulder+1] < 0.4) {
return 'error_low_trust_value (keypoint:right_shoulder_7)'
}
//왼쪽귀(4)-왼쪽어깨(6) 거리와 오른쪽귀(5)-오른쪽어깨(7) 거리가 30% 이상 차이날 경우 > 좌우편향
var d_left = distance(x_position[ear], y_position[ear], x_position[shoulder], y_position[shoulder]);
var d_right = distance(x_position[ear+1], y_position[ear+1], x_position[shoulder+1], y_position[shoulder+1]);
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 === 'right') {
ear++;
shoulder++;
hip++;
}
if (trust_value[hip] < 0.4) { //사용할 데이터의 신뢰도가 0.4 미만이면 실행하지 않음
return `error_low_trust_value (keypoint:${position}hip)`;
}
if (trust_value[shoulder] < 0.4) {
return `error_low_trust_value (keypoint:${position}shoulder)`;
}
if (trust_value[ear] < 0.4) {
return `error_low_trust_value (keypoint:${position}ear)`;
}
//엉덩이(12)-어깨(6) 각도가 70도 이하일 경우 > 굽은등
var back_d1 = Math.abs(x_position[hip] - x_position[shoulder]);
var back_d2 = Math.abs(y_position[hip] - y_position[shoulder]);
var back_angle = Math.atan(back_d2 / back_d1);
var back_angle_rad = (180 * back_angle) / Math.PI; //라디안 > 육십분법 변환
if (back_angle_rad <= back_minimum_angle) {
return 'bent_back';
}
//어깨(6)-귀(4) 각도가 30도 이상일 경우 > 거북목
var neck_d1 = Math.abs(y_position[ear] - y_position[shoulder]);
var neck_d2 = Math.abs(x_position[ear] - x_position[shoulder]);
var neck_angle = Math.atan(neck_d2 / neck_d1);
var neck_angle_rad = (180 * neck_angle) / Math.PI; //라디안 > 육십분법 변환
if (neck_angle_rad >= neck_maximum_angle) {
return 'bent_neck';
}
//굽은등, 거북목 모두 없을 경우
return 'okay';
}
}
export default checkStraight;
/*
console.log(check_straight(response,'front'));
console.log(check_straight(response,'left'));
console.log(check_straight(response,'right'));
*/
\ No newline at end of file
import React, { useState } from 'react'
import Header from './components/Header';
import checkStraight from './AnalysisPose';
import './style/Main.css';
require('dotenv').config();
......@@ -37,7 +38,12 @@ export default function Main() {
},
data: imageFormData
}).then(function (response) {
console.log(JSON.stringify(response.data));
const resdata = response.data[0].keypoints;
console.log(resdata[0]);
const result = checkStraight(resdata, 'front');
console.log(result);
// console.log(resdata[0] === )
}).catch(function (error) {
if (error.response) {
// 요청이 이루어졌으며 서버가 2xx의 범위를 벗어나는 상태 코드로 응답했습니다.
......