머신러닝
GestureKey
웹캠 입력을 운영체제 단축키로 바꿔 주는 실시간 손 제스처 인식 시스템입니다. ML 파이프라인을 통합한 깔끔한 계층형 구조로, 카메라 원본 프레임부터 시스템 동작까지 백그라운드 트레이 앱으로 실행됩니다.
문제
발표나 녹화 중에 키보드를 만지지 않고 컴퓨터를 제어하고 싶었습니다. 백그라운드에서 동작하는 제스처 기반 단축키 계층입니다. 핵심 과제는 조명 변화, 약간의 카메라 흔들림, 손 위치의 자연스러운 부정확함 같은 실제 환경에서도 쓸 수 있을 만큼 인식을 빠르고 안정적으로 만드는 것이었습니다.
주요 결정
자체 비전 파이프라인 대신 MediaPipe로 랜드마크 검출
MediaPipe는 CPU에서 10ms 이내에 손마다 정규화된 3D 랜드마크 21개를 반환합니다. OpenCV로 같은 것을 처음부터 만들었다면 몇 달이 걸리고 결과도 더 나빴을 것입니다. 손 검출은 이미 해결된 문제로 보고, 독창적인 작업은 그 위의 분류기와 제스처 엔진에 집중하는 것이 올바른 엔지니어링 결정이었습니다.
제스처 분류에 신경망 대신 Random Forest
CNN은 적당한 시간 안에 학습하려면 수천 장의 이미지와 GPU가 필요합니다. 하지만 MediaPipe가 이미 의미 있는 랜드마크, 즉 관절 21개의 상대 위치를 추출하므로 원시 픽셀은 필요하지 않습니다. 이런 구조화된 입력에서는 제스처당 200개 샘플로 학습한 Random Forest가 98% 이상의 정확도를 내고 2ms 이내에 추론합니다. 신경망은 정확도 향상 없이 복잡성, 학습 시간, 배포 용량만 늘렸을 것입니다.
다수결 윈도를 이용한 시간적 안정화
프레임 단위 예측에는 노이즈가 많습니다. 손가락이 한 픽셀만 움직여도 분류기가 잠깐 잘못된 클래스를 낼 수 있습니다. 원시 예측마다 운영체제 단축키를 실행하면 앱을 쓸 수 없게 됩니다. 안정화기는 최근 N개의 예측을 버퍼에 담고, 같은 제스처가 윈도 전체의 다수결에서 이길 때만 동작을 실행합니다. 체감할 만한 지연 없이 깜빡임을 없애 줍니다.
트레이 앱에 Tkinter나 Electron 대신 PyQt6
앱은 백그라운드에서 조용히 실행되면서 전역 키보드 단축키를 가로채고 운영체제 수준의 키 이벤트를 주입해야 하므로 네이티브 시스템 접근이 필요합니다. PyQt6는 시스템 트레이 API와 깔끔하게 통합되고 제대로 된 전역 단축키 훅을 제공합니다. Tkinter는 트레이를 지원하지 않습니다. 백그라운드 유틸리티에 Electron을 쓰는 것은 4MB짜리 네이티브 바이너리를 150MB짜리 Chromium으로 바꾸는 셈이라 말이 되지 않았습니다.
결과
GestureKey는 CPU나 메모리에 눈에 띄는 영향 없이 백그라운드 프로세스로 안정적으로 실행됩니다. 모델은 다양한 조명 조건과 학습 데이터에 없던 사용자에게도 잘 일반화됩니다. 이 프로젝트를 통해 ML이 가치를 더하는 곳은 고전적인 컴퓨터 비전을 대체하는 곳이 아니라, 이미 구조화된 특징이 있는 분류 단계라는 것을 더 분명히 알게 되었습니다.
주요 특징
- —모듈형 파이프라인: 카메라 → 트래커 → 분류기 → 제스처 엔진
- —손의 해부학적 랜드마크 21개로 학습한 Random Forest 모델
- —8가지 제스처: 스크롤, 볼륨, 확대/축소, 스크린샷, 작업 보기 등
- —프레임 단위 예측의 노이즈를 없애는 시간적 안정화기
- —PyQt6 시스템 트레이 앱 — 백그라운드에서 조용히 실행
파이프라인
제스처
데모
스크롤
볼륨
작업 보기
일시 정지
트레이 앱