MediaPipe가 손을 추적하면 검지 끝의 좌표가 매 프레임 나온다. 이 좌표를 그대로 화면 커서에 연결하면 커서가 심하게 떨린다. ML 추론 결과에는 필연적으로 프레임 간 노이즈가 있다. 이걸 없애는 가장 단순한 방법은 저역통과 필터(low-pass filter)다. 고주파 성분, 즉 갑작스러운 변화를 깎아내는 필터다.
그런데 저역통과 필터는 부드러움을 얻는 대신 지연(lag)을 낸다. 커서가 손을 뒤따라오는 느낌이 생긴다. 부드러움과 지연은 반비례한다. 더 부드럽게 만들수록 더 뒤따라온다.
One Euro Filter(1€ 필터)는 이 트레이드오프를 끊는 알고리즘이다.
배경 — CHI 2012 논문
One Euro Filter는 2012년 Géry Casiez, Nicolas Roussel, Daniel Vogel이 ACM CHI(컴퓨터·인간 상호작용 학술대회)에 발표한 논문에서 나왔다. 원 제목은 "1€ Filter: A Simple Speed-based Low-pass Filter for Noisy Input in Interactive Systems"다. 1유로짜리 필터라는 이름은 알고리즘이 단순하고 싸다는 농담에서 왔다.
논문의 핵심 관찰은 이렇다. 사람이 손이나 펜을 움직일 때 두 가지 상태가 있다. 천천히, 혹은 멈춰서 정밀한 위치를 유지하려는 상태와 빠르게 이동하는 상태다. 정밀 위치 유지에서는 노이즈 제거(부드러움)가 중요하고, 빠른 이동에서는 즉각 반응(낮은 지연)이 중요하다. 고정 저역통과 필터는 두 상태를 구분하지 못해 하나만 잘 된다.
작동 원리 — 속도에 따라 컷오프를 바꾼다
저역통과 필터의 부드러움 정도는 컷오프 주파수(cutoff frequency)로 결정한다. 컷오프가 낮으면 더 부드럽지만 지연이 크고, 높으면 즉각 반응하지만 떨린다.
One Euro Filter의 아이디어는 이 컷오프를 고정하지 않고 입력 신호의 속도에 따라 동적으로 바꾸는 것이다.
cutoff = minCutoff + β × |속도|천천히 움직이거나 멈춰 있을 때는 속도가 0에 가까우므로 cutoff ≈ minCutoff, 즉 낮은 컷오프로 노이즈를 충분히 제거한다. 빠르게 움직일 때는 속도가 커지므로 컷오프가 높아져 즉각 반응한다.
β(베타)는 속도 가중치 파라미터다. β가 크면 빠른 움직임에서 컷오프가 더 많이 올라가 지연이 더 줄어들지만, 고속에서 약간 더 떨릴 수 있다. β가 0이면 고정 저역통과 필터와 같다.
minCutoff는 정지 상태에서의 최소 컷오프다. 이 값이 낮을수록 정밀 위치에서 더 부드럽다. 너무 낮으면 저속 노이즈가 커서에 남는다.
속도 추정 — 미분 필터링
속도를 구하려면 현재 위치와 이전 위치의 차이를 시간으로 나누면 된다. 그런데 위치 자체에 노이즈가 있으니 속도에는 노이즈가 더 크게 증폭된다. 미분은 노이즈를 키우는 연산이다.
One Euro Filter는 속도 추정에도 별도의 저역통과 필터를 쓴다. 이 필터의 컷오프는 dCutoff로 고정한다. 속도가 안정적으로 추정되어야 그걸 바탕으로 구한 컷오프도 안정적이기 때문이다. dCutoff는 보통 1Hz로 두는 것이 출발점이다.
전체 흐름을 정리하면 이렇다.
- 위치 차이 ÷ 시간 간격으로 날 속도(raw velocity)를 구한다.
dCutoff로 날 속도를 필터링해 안정적인 속도 추정값을 만든다.cutoff = minCutoff + β × |안정 속도|로 동적 컷오프를 계산한다.- 이 컷오프로 위치 자체를 필터링한다.
이 과정이 프레임마다 반복된다. 상태는 이전 위치, 이전 속도, 이전 타임스탬프 세 가지만 유지하면 된다.
왜 타임스탬프가 중요한가
고정 간격 필터는 매 샘플이 같은 시간 간격으로 들어온다고 가정한다. 실제 브라우저에서는 requestAnimationFrame이 화면 주사율과 시스템 부하에 따라 불규칙하게 발화한다. 프레임 간격이 16ms일 때도 있고 32ms일 때도 있다.
One Euro Filter는 실제 시간 간격 dt를 직접 계산에 쓴다. 따라서 프레임 타이밍이 불규칙해도 필터 동작이 일관하다. 이 점이 고정 지수 이동 평균(EMA, 단순 가중 평균)과 다른 부분이다. EMA는 프레임마다 같은 비율로 감쇠하므로, 프레임 간격이 길어지면 감쇠가 줄어 필터가 헐거워진다.
활용 분야
One Euro Filter는 인터랙티브 입력 신호를 다루는 곳에 넓게 쓰인다.
마우스 커서나 손끝 추적이 원형 사례다. 정밀 선택(느린 움직임)과 빠른 이동이 번갈아 나타나는 상황에 맞춤이다.
디지털 스타일러스나 태블릿 드로잉 앱도 마찬가지다. 천천히 그릴 때는 떨림 없이 부드럽고, 빠른 획에서는 지연 없이 붓이 따라와야 한다.
아이트래킹도 유사하다. 사람의 시선은 도약(saccade, 빠른 이동)과 고정(fixation, 멈춤)이 교차한다. 고정 중에는 노이즈를 눌러야 하고, 도약 중에는 즉각 반응해야 한다.
게임 컨트롤러 입력이나 VR 컨트롤러 포인팅에도 쓰인다.
공통점은 "사람이 의도적으로 움직이는 입력"이라는 것이다. 속도가 빠르면 의도적 이동, 속도가 느리면 정밀 위치 유지. 이 패턴이 있는 신호라면 One Euro Filter가 잘 맞는다.
파라미터 튜닝 지침
세 파라미터(minCutoff, β, dCutoff)는 신호의 성질과 쓰임에 따라 조정한다.
minCutoff를 낮추면 정지 시 더 부드럽지만, 너무 낮으면 저속 이동에서 뒤처지는 느낌이 난다. 1.0이 흔한 출발점이다.β를 높이면 빠른 이동에서 반응성이 좋아진다. 손끝처럼 갑작스러운 이동이 많은 신호에서는 0.01~0.1 범위가 자주 쓰인다. 손끝 좌표처럼 운동량이 큰 경우 0.03 정도면 지연이 눈에 띄지 않으면서도 떨림을 충분히 잡는다.dCutoff는 속도 추정에 쓰이는 컷오프로 보통 1.0에 두고 건드리지 않는다.
파라미터는 결국 실제 영상을 보면서 조정하는 게 가장 확실하다. 이론적인 최적값보다 특정 사용 맥락에서의 주관적 느낌이 더 중요하기 때문이다.
이점과 트레이드오프
이점은 단순하다. 단일 파라미터(속도)로 부드러움과 반응성을 동시에 잡는다. 구현이 상태 변수 셋(이전 위치, 이전 속도, 이전 시간)과 수십 줄 코드로 끝난다. 프레임 간격이 불규칙해도 일관하게 동작한다.
감수하는 것은 파라미터 조정이 필요하다는 점이다. minCutoff와 β를 어떻게 두느냐에 따라 체감이 달라진다. 정해진 공식이 없고 신호 특성과 응용 목적에 따라 달라진다. 또 1차원 신호 하나에 하나의 필터 인스턴스가 필요하다. X 좌표와 Y 좌표가 따로 있다면 필터도 두 개를 써야 한다.
'TIL' 카테고리의 다른 글
| requestAnimationFrame — 브라우저 렌더 루프의 작동 방식 (0) | 2026.06.08 |
|---|---|
| Face Blendshapes — 52개 숫자로 표정을 기술하는 법 (0) | 2026.06.08 |
| MediaPipe Tasks Vision — 브라우저에서 손과 얼굴을 추적하는 법 (0) | 2026.06.08 |
| WASM 온디바이스 추론 — 서버 없이 폰 안에서 모델 돌리기 (0) | 2026.06.07 |
| LoRA — 모델 전체를 재학습하지 않고 일부만 바꾸는 법 (0) | 2026.06.07 |