Skip to content

Kalman filter

객체의 이전 상태를 사용하여 다음 상태를 예측한다.

칼만 필터(Kalman filter)는 잡음이 포함되어 있는 선형 역학계의 상태를 추적하는 재귀 필터로, 루돌프 칼만이 개발하였다. 칼만 필터는 컴퓨터 비전, 로봇 공학, 레이다 등의 여러 분야에 사용되며, 많은 경우에 매우 효율적인

이 알고리즘은 시간에 따라 진행한 측정을 기반으로 한다. 해당 순간에만 측정한 결과만 사용한 것보다는 좀 더 정확한 결과를 기대할 수 있다. 잡음까지 포함된 입력 데이터를 재귀적으로 처리하는 필터로서, 현재 상태에 대한 최적의 통계적 예측을 진행할 수 있다.

알고리즘 전체는 예측과 업데이트의 두 가지로 나눌 수 있다. 예측은 현재 상태의 예측을 말하며, 업데이트는 현재 상태에서 관측된 측정까지 포함한 값을 통해서 더 정확한 예측을 할 수 있는 것을 말한다.

확장 칼만 필터는 비선형 시스템을 기반으로 동작한다.

순서

  1. 측정(init) - 물체의 위치, 속도, 가속도 등을 측정
  2. 예측(predict) - 이전 값을 토대로 현재값을 추정(재귀적)
  3. 보정(correct, update) - 예측 상태와 실제 상태를 토대로 다시 계산

종류

선형 칼만필터 (LKF,Linear Kalman Filter)
실제환경은 비선형, 잡음도 비 가우시안 -> 잘 안맞음
확장 칼만필터 (EKF, Extended Kalman Filter)
선형화하는 기준점을 계속 갱신
어느 정도의 비선형 모델에 적용 가능, 네비게이션에서 거의 표준
무향 칼만 필터 (UKF, The unscented Kalman filter)
매우 비선형 인 경우 적용
계산이 많음, 속도 느림

Example

칼만 필터는 객체의 이전 상태를 사용하여 다음 상태를 예측합니다. 이 알고리즘은 선형 확률적 차이 방정식을 사용하여 다음 상태를 결정합니다.

import cv2
import numpy as np

measured=[]
predicted=[]
dr_frame = np.zeros((400,400,3), np.uint8)
mp = np.array((2,1), np.float32)
tp = np.zeros((2,1), np.float32)

def on_mouse(k,x,y,s,p):
    global mp,measured
    mp = np.array([[np.float32(x)],[np.float32(y)]])
    measured.append((x,y))

def paint_canvas():
    global dr_frame,measured,predicted
    for i in range(len(measured)-1): cv2.line(dr_frame,measured[i],measured[i+1],(0,100,0))
    for i in range(len(predicted)-1): cv2.line(dr_frame,predicted[i],predicted[i+1],(0,0,200))

def reset_canvas():
    global measured,predicted,dr_frame
    measured=[]
    predicted=[]
    dr_frame = np.zeros((400,400,3), np.uint8)

cv2.namedWindow("Sample")
cv2.setMouseCallback("Sample",on_mouse);
kalman_fil = cv2.KalmanFilter(4,2)
kalman_fil.measurementMatrix = np.array([[1,0,0,0],[0,1,0,0]],np.float32)
kalman_fil.transitionMatrix = np.array([[1,0,1,0],[0,1,0,1],[0,0,1,0],[0,0,0,1]],np.float32)
kalman_fil.processNoiseCov = np.array([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]],np.float32) * 0.03

while True:
    kalman_fil.correct(mp)
    tp = kalman_fil.predict()
    predicted.append((int(tp[0]),int(tp[1])))
    paint_canvas()
    cv2.imshow("Output",dr_frame)
    k = cv2.waitKey(30) &0xFF
    if k == 27: break
    if k == 32: reset_canvas()

See also

Favorite site

OpenCV Example

References


  1. Understanding_of_the_Kalman_Filter.pdf 

  2. Understanding_the_Basis_of_the_Kalman_Filter_Via_a_Simple_and_Intuitive_Derivation.pdf