Как установить матрицу измерений фильтра opencv kalman в зависимости от размеров измерений [OpenCV + Python] - PullRequest
0 голосов
/ 13 февраля 2020

Я работаю над приложением для отслеживания, в котором я использую фильтр 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 не используются?
Как изменить матрицу измерений более целенаправленно, чем просто итеративно корректировать значения?

Спасибо за помощь!

...