Фильтр Калмана / OpenCV / Recog.ru - Распознавание образов для программистов


Фильтр Калмана

Фи́льтр Ка́лмана — эффективный рекурсивный фильтр, оценивающий вектор состояния динамической системы, используя ряд неполных и зашумленных измерений. Назван в честь Рудольфа Калмана.
В процессе анализа и обработке большого количества числовых данных, непременно возникают проблемы связанные с точностью обрабатываемой информации. Это значит, что какие бы это не были данные они имеют ошибки, связанные с погрешностью прибора, с помощью которого получается данная информация, или это кратковременный сбой, который привел к получению неточных данных. Так или иначе с этими неприятностями надо как то бороться. На помощь приходит очень полезный для данной цели алгоритм фильтра, построенный на основании метода Калмана.
Данный метод позволяет убрать из обрабатываемой последовательности данных шумы и лишнюю информацию.
Работа алгоритма включает два этапа: предсказание и корректировку.
На первом этапе предсказывается состояние системы и ошибка ковариации:



На втором этапе предсказанные значения корректируются за счет интеграции коэффициента усиления Калмана и получения текущего значения измеряемой величины.



x – это состояние системы, t – момент времени, u – управляющее воздействие, P – предсказание ошибки, z – результат замера или очередное входное значение, R — ковариация шума измерения (погрешность измерения), Q — ковариация шума процесса. Минус в верхнем индексе обозначает, что это предсказанное промежуточное значение.
Теперь рассмотрим матрицы(переменные) определяющие динамику системы.
F — матрица перехода между состояниями. Описывает динамику системы.
В — матрица применения управляющего воздействия. Если есть дополнительные факторы из-за которых может меняться состояние системы, то этот параметр бы определял как именно значение управляющего воздействия меняет состояние системы.
H — матрица измерений. Определяет отношение между измерениями и состоянием системы.
Данный фильтр реализуется средствами библиотеки OpenCV. Рассмотрим пример его реализации.

// Подключение необходимых модулей
#include "opencv2/video/tracking.hpp"
#include <Windows.h>
using namespace cv;
KalmanFilter KF(4, 2, 0);

// Инициализация объекта KF
KF.transitionMatrix = *(Mat_<float>(4, 4) << 1,0,1,0,   0,1,0,1,  0,0,1,0,  0,0,0,1);
Mat_<float> measurement(2,1); measurement.setTo(Scalar(0));
measurement(1) = 64;
measurement(0) = 64;


KF.statePre.at<float>(0) = 0; /////////////////
KF.statePre.at<float>(1) = 0; // Инициализация первых 
KF.statePre.at<float>(2) = 0; // предсказанных значений
KF.statePre.at<float>(3) = 0; /////////////////
setIdentity(KF.measurementMatrix); // Инициализация матрицы измерений
setIdentity(KF.processNoiseCov, Scalar::all(1e-4)); // Значение ковариации шума процесса
setIdentity(KF.measurementNoiseCov, Scalar::all(3)); // Значение ковариации шума измерения
setIdentity(KF.errorCovPost, Scalar::all(.1)); // обновление ошибки ковариации

vector<int> kalmanv;
kalmanv.clear();
Mat prediction = KF.predict();
int predictPt(prediction.at<float>(0)); // предсказанное значение

measurement(0) = recog_up3; // измеренное значение

// Обновление
Mat estimated = KF.correct(measurement);

int result = (int)estimated.at<float>(0); // обновленное значение


Здесь в переменную result записываются значения обработанные алгоритмом.



Результат работы фильтра наглядно демонстрируется на рисунке. Синяя линия построена по обрабатываемым значениям, а красная демонстрирует результат работы фильтра по этим же значениям.

Комментарии (0)

RSS свернуть / развернуть

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.