Я внедряю фильтр Калмана, который получает реальные измерения от отслеживания головы кулачкового переключения после предварительного обнаружения лица с помощью каскада Хаара. Я инициализирую переменные состояния до и после состояния из фильтра Калмана с положением головы из каскада Хаара и вызываю предсказание и исправление Калмана при выполнении кулачкового переключения, чтобы получить некоторое сглаживание. Проблема в том, что предсказанные и скорректированные значения всегда являются начальными значениями каскада Хаара. Должен ли я обновлять переменные состояния до или после состояния во время переключения распредвала?
private CvKalman Kf ;
public CvMat measurement = new CvMat(2,1, MatrixType.F32C1);
public int frameCounter = 0;
public float[] A = {1,0,1,0, 0,1,0,1, 0,0,1,0, 0,0,0,1};
public float[] H = {1,0,0,0, 0,1,0,0};
public float[] Q = {0.0001f,0,0,0, 0,0.0001f,0,0, 0,0,0.0001f,0, 0,0,0,0.0001f};
public float[] R = {0.2845f,0.0045f,0.0045f,0.0455f};
public float[] P = {100,0,0,0, 0,100,0,0, 0,0,100,0, 0,0,0,100};
initkalman вызывается один раз при выполнении каскада хаара, а окно отслеживания — это начальное положение головы.
void initKalman(CvRect trackinWindow){
Kf = new CvKalman (4, 2, 0);
Marshal.Copy (A, 0, Kf.TransitionMatrix.Data, A.Length);
Marshal.Copy (H, 0, Kf.MeasurementMatrix.Data, H.Length);
Marshal.Copy (Q, 0, Kf.ProcessNoiseCov.Data, Q.Length);
Marshal.Copy (R, 0, Kf.MeasurementNoiseCov.Data, R.Length);
Marshal.Copy (P, 0, Kf.ErrorCovPost.Data, P.Length);
measurement.mSet (0, 0, trackingWindow.X);
measurement.mSet (1, 0, trackingWindow.Y);
Kf.StatePost.mSet(0,0,trackingWindow.X);
Kf.StatePost.mSet(1,0,trackingWindow.Y);
Kf.StatePost.mSet(2, 0, 0);
Kf.StatePost.mSet(3, 0, 0);
}
Я вызываю функцию processKalman в каждой итерации camshift, теперь отслеживая фактическое положение головы в окне.
CvPoint processKalman(CvRect trackingwindow)
{
CvMat prediction = Cv.KalmanPredict(Kf);
CvPoint predictionPoint;
predictionPoint.X = (int)prediction.DataArraySingle [0];
predictionPoint.Y = (int)prediction.DataArraySingle [1];
Debug.Log (predictionPoint.X);
measurement.mSet (0, 0, trackingWindow.X);
measurement.mSet (1, 0, trackingWindow.Y);
CvMat estimated = Cv.KalmanCorrect(Kf,measurement);
CvPoint auxCP;
auxCP.X = (int)estimated.DataArraySingle [0];
auxCP.Y = (int)estimated.DataArraySingle [1];
return auxCP;
}
Это не работает и всегда возвращает только исходное положение головы. Парень из в этом отличном блоге перед вызовом функции прогнозирования пост о состоянии изменяется на фактическое измерение, но единственное, что меняется для меня при этом, это то, что прогнозируемые и скорректированные значения теперь идентичны положение головки распредвала для каждой рамы.