Kalman Filter (KF)
칼만 필터는 모델 예측과 노이즈가 있는 측정값을 결합하여 객체의 위치와 속도처럼 변화하는 상태를 추정합니다. 수학적 원리와 코드를 다룹니다.
칼만 필터(KF)는 노이즈가 있는 측정값의 스트림으로부터 물체의 위치와 속도처럼 변화하는 시스템의 숨겨진 상태를 추정하는 재귀 알고리즘입니다. 각 시간 단계에서 시스템의 움직임 모델을 바탕으로 다음 상태를 예측한 뒤, 불확실성을 고려해 새로운 측정값으로 예측을 보정합니다. Rudolf E. Kálmán은 1960년에 이 방법을 발표했으며, 가우시안 노이즈가 있는 선형 시스템에서 최소 평균 제곱 오차 추정치를 제공합니다. 칼만 필터는 GPS 수신기, 항공기 및 우주선 항법, 로봇 위치 추정, 그리고 컴퓨터 비전의 거의 모든 다중 객체 추적기에서 사용됩니다. 다중 객체 추적기에서는 칼만 필터가 흔들리는 탐지 결과를 평활화하고 각 객체가 다음에 나타날 위치를 예측합니다.
칼만 필터의 작동 방식#
필터는 두 가지 값을 유지합니다. 예를 들어 위치와 속도를 나타내는 상태 추정값 x과 추정값의 불확실성을 설명하는 공분산 행렬 P입니다. 각 주기는 두 단계로 구성됩니다.
- 예측: 동작 모델
F은 상태를x = F x만큼 앞으로 투영하고, 모델이 포착하지 못하는 움직임을 반영하는 프로세스 노이즈Q에 따라 불확실성이 증가합니다:P = F P Fᵀ + Q. - 업데이트: 새로운 측정값
z이 들어오며, 측정 모델H에 따라 상태와 연결됩니다. 필터는 잔차z − H x와 칼만 이득K = P Hᵀ (H P Hᵀ + R)⁻¹을 계산합니다. 여기서R는 측정 노이즈입니다. 보정된 상태는x + K (z − H x)이며, 불확실성은(I − K H) P으로 줄어듭니다.
칼만 이득은 모델과 센서 사이의 균형을 정합니다. 측정값이 예측에 비해 정밀하면 이득이 1에 가까워져 추정값이 측정값을 따르고, 측정값에 노이즈가 많으면 이득이 0에 가까워져 추정값이 예측을 따릅니다. 상태에는 직접 측정하지 않는 값도 포함될 수 있으므로 필터는 그런 값도 추론합니다. 위치만 관찰하는 추적기도 속도를 추정할 수 있습니다. 측정값이 없으면 필터는 업데이트를 건너뛰고 예측값을 따라갑니다.
객체 추적에서의 칼만 필터#
객체 추적에서는 각 트랙이 자체 칼만 필터를 유지합니다. 상태에는 바운딩 박스의 중심과 크기, 그리고 각각의 속도가 포함되며, 등속도 모델은 다음 프레임에서 박스가 나타날 위치를 예측합니다. 이러한 예측은 교집합 대비 합집합(IoU)을 기준으로 새로운 탐지 결과와 매칭되며, 매칭된 각 탐지 결과는 트랙을 업데이트하는 측정값이 됩니다. 객체가 몇 프레임 동안 가려져도 트랙은 예측 경로를 따라 계속 이동하므로, 객체가 다시 나타났을 때 탐지 결과가 예측 위치에 충분히 가까워 기존 ID를 유지할 수 있습니다.
Ultralytics YOLO의 모든 트래커는 track 모드에서 이러한 방식으로 작동합니다. ByteTrack의 KalmanFilterXYAH는 박스 중심, 종횡비, 높이와 각 항목의 속도로 이루어진 8차원 상태를 추적합니다. BoT-SORT와 TrackTrack은 너비와 높이를 사용하는 변형을 적용하며, 두 트래커 모두 박스 크기에 따라 노이즈를 조정하므로 크고 가까운 객체일수록 픽셀 단위의 큰 이동을 허용합니다. 박스 중심의 한 좌표에 대해 NumPy로 몇 줄만 작성하면 동일한 예측 및 업데이트 단계를 구현할 수 있습니다.
import numpy as np
F = np.array([[1.0, 1.0], [0.0, 1.0]]) # constant-velocity model, state = [position, velocity]
H = np.array([[1.0, 0.0]]) # the detector measures position only
Q = 0.001 * np.eye(2) # process noise: how far real motion may stray from the model
R = np.array([[25.0]]) # measurement noise: detections jitter by about 5 px
rng = np.random.default_rng(0)
truth = 100 + 3.0 * np.arange(60) # box center moving 3 px per frame
z = truth + rng.normal(0, 5.0, truth.size) # noisy detections
x, P = np.array([z[0], 0.0]), np.diag([25.0, 100.0]) # start from the first detection
estimates = [x[0]]
for measurement in z[1:]:
x, P = F @ x, F @ P @ F.T + Q # predict
K = P @ H.T @ np.linalg.inv(H @ P @ H.T + R) # Kalman gain
x = x + K @ (measurement - H @ x) # update with the weighted residual
P = (np.eye(2) - K @ H) @ P
estimates.append(x[0])
print(f"Detection error: {np.sqrt(np.mean((z - truth) ** 2)):.2f} px")
print(f"Kalman error: {np.sqrt(np.mean((np.array(estimates) - truth) ** 2)):.2f} px")
print(f"Estimated velocity: {x[1]:.2f} px/frame")출력 결과는 원시 탐지 결과의 제곱 평균 제곱근 오차가 4.50 px, 필터링된 추정값의 오차가 2.48 px임을 보여줍니다. 또한 속도를 측정하지 않았음에도 실제 속도인 프레임당 3 px에 가까운 프레임당 2.98 px의 추정 속도를 보여줍니다.
관련 필터#
표준 칼만 필터는 가우시안 노이즈가 있는 선형 동작 및 측정 모델을 가정합니다. 관련 필터는 이러한 가정을 완화합니다.
- 확장 칼만 필터(EKF): 각 단계에서 야코비안으로 현재 추정값 주변의 비선형 모델을 선형화하며, GPS 및 관성 항법에 표준적으로 사용됩니다.
- 무향 칼만 필터(UKF): 신중하게 선택한 소수의 샘플 포인트를 비선형 모델에 통과시킵니다. 일반적으로 선형화보다 정확하고 미분값이 필요하지 않습니다.
- 파티클 필터: 다수의 가중치가 있는 무작위 샘플로 상태 분포를 표현하므로, 로봇이 두 통로 중 어디에 있는지 확신하지 못하는 경우처럼 가우시안이 아니거나 다봉적인 믿음 상태를 처리할 수 있지만 계산 비용이 훨씬 큽니다.
- 은닉 마르코프 모델(HMM): 이산 상태에 대해 동일한 예측 및 업데이트 재귀를 사용합니다. 칼만 필터는 연속적인 선형 가우시안 상태에 대응하는 방법입니다.
추적 이외의 응용 분야#
- 로보틱스와 센서 융합: 로봇은 휠 오도메트리, IMU, 라이다, 카메라 데이터를 결합해 하나의 포즈 추정값을 산출하며, EKF 기반 방법은 동시적 위치 추정 및 지도 작성의 고전적인 접근 방식입니다.
- 증강 현실: 헤드셋은 머리 포즈 측정값을 필터링해 짧은 지연 시간으로 가상 객체를 안정적으로 표시합니다.
- 경제학 및 신호 처리: 분석가는 칼만 스무딩을 사용해 노이즈가 있는 시계열에서 관측되지 않은 추세를 추정합니다.
- 항법: 항공기, 선박, 드론, 휴대전화는 GPS와 관성 센서를 융합하여 위성 신호를 수신하는 사이에도 위치를 부드럽게 유지합니다. 항법은 칼만 필터의 첫 번째 주요 응용 분야이기도 합니다. 1960년대 초 NASA Ames의 Stanley F. Schmidt는 아폴로 항법 컴퓨터에서 비선형 궤적 추정을 수행하도록 칼만 필터를 수정했습니다.










