Skip to content

kusitms-bugi/demo-FE

 
 

Repository files navigation

GBGR (거부기린)

실시간 웹캠 자세 인식을 통해 거북목과 같은 잘못된 자세를 교정하고 사용자에게 통계 피드백을 제공하는 웹 데모

거부기린 아이콘


🔗 데모 & 자료


✨ 핵심 요약 (TL;DR)

  • 문제 인식: 장시간 컴퓨터 사용으로 인해 무의식적으로 자세가 흐트러져 거북목, 어깨 비대칭 등의 문제를 겪는 사용자가 많습니다.
  • 핵심 해결 전략:
    • 웹캠을 통해 사용자의 자세를 실시간으로 분석하고 시각적으로 피드백합니다.
    • 잘못된 자세가 감지되면 알림을 보내 즉각적인 교정을 유도합니다.
    • 세션별 자세 데이터를 기록하고 통계 대시보드를 제공하여 장기적인 습관 개선을 돕습니다.
  • 프론트엔드 기술 포인트:
  • @mediapipe/tasks-vision을 활용하여 웹캠 영상에서 실시간으로 신체 키포인트를 추출하고 자세를 분석합니다.
  • Zustand를 사용해 세션, 알림, 카메라 등 복잡한 클라이언트 상태를 효율적으로 관리합니다.
  • Recharts를 이용해 사용자의 자세 점수, 패턴 등 통계 데이터를 시각화하여 제공합니다.

🧩 주요 기능

  1. 실시간 자세 분석 및 위젯

    • 설명: 웹캠을 통해 사용자의 자세를 실시간으로 분석하고, MediaPipe를 활용해 신체 키포인트를 추출합니다. 메인 화면과 데스크탑 위젯을 통해 현재 자세 상태(거북목/기린)를 실시간으로 확인하고 세션을 제어할 수 있습니다. 위젯은 항상 위에 표시되며 크기 조절이 가능합니다.
    • 기술 포인트: react-webcam, @mediapipe/tasks-vision, PostureClassifier
    • 주요 특징:
      • PI(Posture Index) 계산을 통한 정량적 자세 평가
      • EMA(Exponential Moving Average) 스무딩으로 노이즈 제거
      • ScoreProcessor를 통한 다단계 스무딩 (Moving Average → EMA(30) → EMA(70))
      • 히스테리시스 로직으로 채터링 방지 (enter_bad: 1.2, exit_bad: 0.8)
      • 정면성 검사(roll, centerRatio)로 측정 신뢰도 보장
      • 위젯 독립 동작: 메인 창이 없어도 위젯만으로 자세 판정 가능
      • 스마트 동기화: 메인 창이 활성화되어 있으면 위젯은 판정을 하지 않고 동기화만 수행
  2. 캘리브레이션 시스템

    • 설명: 사용자 개인의 정상 자세를 기준으로 설정하는 캘리브레이션 기능입니다. 측정 중 밝기, 자세 안정성 등을 검사하여 신뢰할 수 있는 기준값을 확보합니다.
    • 기술 포인트: trimmedStats (상하 5% 절사 평균 및 표준편차), errorChecks (밝기/안정성 검증)
  3. 통계 대시보드

    • 설명: 일별, 주별 데이터를 기반으로 자세 점수 변화, 주요 자세 패턴, 출석률, 평균 자세 점수, 레벨 진행도 등을 시각적으로 분석합니다. Recharts를 활용한 다양한 차트로 사용자의 장기적인 자세 개선 추이를 확인할 수 있습니다.
    • 기술 포인트: TanStack Query (서버 데이터 캐싱 및 동기화), Recharts (차트 시각화)
    • 주요 패널:
      • 평균 자세 점수 그래프 (시간대별 추이)
      • 자세 패턴 분석 (거북목/기린 비율)
      • 출석률 및 연속 출석 일수
      • 레벨 진행도 및 달성률
  4. 자세 교정 알림

    • 설명: 거북목이나 비대칭 자세가 일정 시간 이상 지속되면 데스크탑 알림을 보내 사용자가 인지하고 바로잡을 수 있도록 돕습니다. 알림 강도와 주기를 사용자가 설정할 수 있습니다.
    • 기술 포인트: Web Notification API, useNotificationScheduler 훅, Zustand (알림 상태 관리)
  5. 세션 관리

    • 설명: 자세 측정 세션을 시작, 일시정지, 재개, 종료할 수 있습니다. 세션 중 수집된 메트릭 데이터는 주기적으로 서버에 저장되며, 세션 종료 시 리포트를 제공합니다.
    • 기술 포인트: useAutoMetricsSender (자동 메트릭 전송), useSessionCleanup (세션 정리)

🛠 기술 스택

Frontend

  • Framework: React
  • Language: TypeScript
  • State Management: Zustand, TanStack Query
  • Styling: Tailwind CSS
  • Build/Bundle: Vite
  • Pose Detection: @mediapipe/tasks-vision

협업 & 기타

  • Version Control: Git, GitHub
  • CI: GitHub Actions
  • Package Manager: pnpm
  • Form Validation: react-hook-form, zod
  • Animation: framer-motion
  • Routing: react-router-dom

📁 프로젝트 구조

Vite + React 기반 단일 웹 앱이며, 실제 엔트리(루트)는 src/ 입니다.

src/
└── renderer/       # React 애플리케이션 (UI)
    └── src/
        ├── api/                  # API 요청 관련 훅 (TanStack Query)
        │   ├── dashboard/        # 대시보드 데이터 쿼리
        │   ├── session/          # 세션 관리 뮤테이션
        │   └── login/            # 인증 관련
        ├── assets/               # 이미지, 폰트 등 정적 에셋
        ├── entities/             # 비즈니스 엔티티 (FSD 아키텍처)
        │   └── posture/          # 자세 분석 엔티티
        │       └── lib/
        │           ├── PostureClassifier.ts    # 자세 분류 엔진
        │           ├── ScoreProcessor.ts       # 점수 처리 파이프라인
        │           ├── calculations.ts         # PI 계산, EMA 스무딩
        │           └── errorChecks.ts          # 캘리브레이션 검증
        │   ├── Button/           # 버튼 컴포넌트
        │   ├── Modal/            # 모달 컴포넌트
        │   └── ...
        ├── hooks/                # 커스텀 훅
        │   ├── useNotificationScheduler.ts  # 알림 스케줄링
        │   ├── useAutoMetricsSender.ts      # 자동 메트릭 전송
        │   └── useWidget.ts                 # 위젯 상태 관리
        ├── layout/               # 페이지 레이아웃 컴포넌트
        ├── pages/                # 라우팅 단위 페이지 컴포넌트
        │   ├── Main/             # 메인 대시보드 페이지
        │   ├── Widget/          # 위젯 페이지
        │   ├── Calibration/     # 캘리브레이션 페이지
        │   └── ...
        ├── store/                # Zustand 전역 스토어
        │   ├── usePostureStore.ts    # 자세 상태 관리
        │   ├── useCameraStore.ts     # 카메라 상태 관리
        │   └── useNotificationStore.ts  # 알림 설정 관리
        ├── styles/               # 전역 스타일 및 Tailwind 설정
        ├── types/                # 공용 타입 정의
        └── utils/                # 유틸리티 함수
  • 컴포넌트 설계: 페이지(Pages)가 비즈니스 로직과 데이터 페칭을 담당하고, 컴포넌트(Components)는 UI 표현에 집중하는 구조를 지향합니다. pose-detection 폴더에는 자세 인식 관련 핵심 로직이 클래스 기반으로 구현되어 있습니다.
  • 디자인 시스템: Button, Modal, TextField, ToggleSwitch 등 핵심 UI를 공통 컴포넌트로 만들어 일관성을 유지하고 재사용성을 높였습니다. clsxtailwind-merge를 활용해 조건부 스타일링을 관리합니다.
  • 상태 관리 전략:
    • Zustand로 클라이언트 상태(자세, 카메라, 알림 설정) 관리
    • TanStack Query로 서버 상태 캐싱 및 동기화
    • 위젯과 메인 윈도우 간 동기화는 localStoragestorage 이벤트 활용

🚀 실행 방법

# 1. 의존성 설치
pnpm install

# 2. 개발 서버 실행
pnpm dev

# 3. 빌드
pnpm build

# 4. 로컬 프리뷰
pnpm preview

📌 개발 의도 & 기술적 도전

  • 기술적 도전 과제:

    1. 실시간 영상 처리 성능: 저사양 컴퓨터에서도 부드럽게 작동하도록 웹캠 영상 분석 과정의 성능을 최적화하는 것이 중요했습니다.
    2. 메인/위젯 모드 동기화: 서로 다른 UI 컨텍스트에서 상태(세션, 시간 등)를 일관성 있게 동기화하는 것이 복잡했습니다.
    3. 웹 배포/호환성: 다양한 브라우저 환경에서 안정적으로 실행되도록 빌드/번들링 설정과 런타임 의존성을 관리했습니다.
  • 해결 과정:

    1. 성능 최적화:
    • MediaPipe의 detectForVideo를 프레임별로 호출하여 중복 처리 방지
    • ScoreProcessor의 다단계 스무딩 파이프라인으로 노이즈 제거 (Moving Average → EMA(30) → EMA(70))
    • 히스테리시스 로직으로 채터링 방지하여 안정적인 상태 전환
    • 점수 클램핑(-10 ~ 40)으로 이상치 제거
    1. 다중 윈도우 동기화:
    • 위젯과 메인 윈도우 간 자세 상태 동기화는 localStoragestorage 이벤트 활용 (IPC 대신 사용하여 간단하고 안정적으로 구현)
    • usePostureSyncWithLocalStorage 훅으로 위젯에서 메인 창의 상태 변경 감지
    • 스마트 판정 전략: 메인 창이 활성화되어 있으면 위젯은 판정을 하지 않고 메인 창의 결과만 동기화받음. 메인 창이 없으면 위젯이 독립적으로 판정 수행
    • 메인 창 활성화 상태는 localStorage의 타임스탬프로 추적 (2초 이내 업데이트가 없으면 비활성화로 간주)
    1. 웹 배포/호환성:
    • Vite 기반 번들링 및 코드 스플리팅으로 초기 로딩 최적화

👥 팀 구성 & 역할

프로필 역할 이름 GitHub
최호 프로필 Frontend 최호 @choihooo
이환석 프로필 Frontend 이환석 @hwanseok1014
손대현 프로필 Backend 손대현 @son-daehyeon

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • TypeScript 92.8%
  • CSS 6.0%
  • Other 1.2%