Я работаю над приложением для отслеживания, в котором я использую фильтр opencv kalman для проверки моего текущего измерения положения. Я использую код из этого вопроса:
Сначала я вычисляю скорость (v) и ускорение (a) моего движущегося объекта в точке (x, y). Эти 4 значения используются в качестве моего состояния Калмана. Я запускаю фильтр Калмана следующим образом:
(np.eye(n,m)
генерирует единичную матрицу с размерами nxm):
def initKalman(init_state, fps):
kalman = cv.KalmanFilter(4, 4, 2)
kalman.transitionMatrix = np.array([[1., 0., 1/fps, 0.],
[0., 1., 0., 1/fps],
[0., 0., 1., 0.],
[0, 0., 0., 1.]])
kalman.measurementMatrix = 1. * np.eye(2, 4)
kalman.measurementNoiseCov = 1e-3 * np.eye(2, 2)
kalman.processNoiseCov = 1e-5 * np.eye(4, 4)
kalman.errorCovPost = 1e-1 * np.eye(4, 4)
kalman.statePost = init_state.reshape(4, 1)
return kalman
kinematics = np.array((velocity, acceleration), dtype=np.float32)
kalman_state = np.concatenate((point, kinematics))
kalman_filter = initKalman(kalman_state, fps = 15)
Во время работы коррекция выполняется следующим образом:
def correct_kalman(kalman, state):
measurement = (np.dot(kalman.measurementNoiseCov, np.random.randn(2, 1))).reshape(-1)
measurement = np.dot(kalman.measurementMatrix, state) + measurement
return kalman.correct(measurement)
kinematics = np.array((velocity, acceleration), dtype=np.float32)
kalman_state = np.concatenate((point, kinematics))
correct_kalman(kalman_filter, kalman_state)
Кажется, ведьма работает отлично, но я пытаюсь понять, почему. В моем понимании это не должно работать, потому что в correct_kalman()
скорость и ускорение опущены в этой строке кода:
measurement = np.dot(kalman.measurementMatrix, state) + measurement
, потому что матрица измерения составляет всего 2 x 4. (Фактически, если я установлю ускорение и скорость в 0, поведение фильтра не меняется.)
Например, возьмите kalman_state = np.array([10., 20., 25., 75.])
и вычислите скалярное произведение с помощью measurementMatrix = 1. * np.eye(2, 4)
, тогда measurement = np.dot(kalman.measurementMatrix, kalman_state)
равно
>>> measurement
array([10., 20.])
v и a пропали.
Таким образом, я изменил свой MeasureMatrix и мой measureNoiseCov на 4 x 4
размерность и скорректировал свою коррекцию соответственно с помощью np.random.randn(4, 1)
но теперь фильтр Калмана является слагой sh и отстает от измерения.
Почему первый подход работает, если v и a не используются?
Как изменить матрицу измерений более целенаправленно, чем просто итеративно корректировать значения?
Спасибо за помощь!