private float Correct(double value, ref KalmanFilter filter) { if (filter == null) { filter = factory.Create(); } var corrected = new float[2, 1]; var measurement = new Matrix<float>(1, 1) { [0, 0] = (float) value };
public KalmanFilter Create() { var filter = new KalmanFilter(2, 1, 0); transitionMatrix.Mat.CopyTo(filter.TransitionMatrix); measurementMatrix.SetIdentity(); measurementMatrix.Mat.CopyTo(filter.MeasurementMatrix); processNoiseCov.SetIdentity(new MCvScalar(1.0e-5)); processNoiseCov.Mat.CopyTo(filter.ProcessNoiseCov); measurementNoiseCov.SetIdentity(new MCvScalar(1.0e-2)); measurementNoiseCov.Mat.CopyTo(filter.MeasurementNoiseCov); errorCovPost.SetIdentity(); errorCovPost.Mat.CopyTo(filter.ErrorCovPost); filter.StatePost.SetTo(new float[] {0, 0}); return filter; }
//[Test] public void TestKalman() { Image<Bgr, Byte> img = new Image<Bgr, byte>(400, 400); SyntheticData syntheticData = new SyntheticData(); //Matrix<float> state = new Matrix<float>(new float[] { 0.0f, 0.0f}); //initial guess #region initialize Kalman filter KalmanFilter tracker = new KalmanFilter(2, 1, 0); syntheticData.TransitionMatrix.Mat.CopyTo(tracker.TransitionMatrix); syntheticData.MeasurementMatrix.Mat.CopyTo(tracker.MeasurementMatrix); syntheticData.ProcessNoise.Mat.CopyTo(tracker.ProcessNoiseCov); syntheticData.MeasurementNoise.Mat.CopyTo(tracker.MeasurementNoiseCov); syntheticData.ErrorCovariancePost.Mat.CopyTo(tracker.ErrorCovPost); tracker.StatePost.SetTo(new float[] { 0.0f, 0.0f }); #endregion System.Converter<double, PointF> angleToPoint = delegate(double radianAngle) { return new PointF( (float)(img.Width / 2 + img.Width / 3 * Math.Cos(radianAngle)), (float)(img.Height / 2 - img.Width / 3 * Math.Sin(radianAngle))); }; Action<PointF, Bgr> drawCross = delegate(PointF point, Bgr color) { img.Draw(new Cross2DF(point, 15, 15), color, 1); }; ImageViewer viewer = new ImageViewer(); System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer(); timer.Interval = 200; timer.Tick += new EventHandler(delegate(object sender, EventArgs e) { Matrix<float> measurement = syntheticData.GetMeasurement(); // adjust Kalman filter state tracker.Correct(measurement.Mat); tracker.Predict(); #region draw the state, prediction and the measurement float[] correctedState = new float[2]; float[] predictedState = new float[2]; tracker.StatePost.CopyTo(correctedState); tracker.StatePre.CopyTo(predictedState); PointF statePoint = angleToPoint(correctedState[0]); PointF predictPoint = angleToPoint(predictedState[0]); PointF measurementPoint = angleToPoint(measurement[0, 0]); img.SetZero(); //clear the image drawCross(statePoint, new Bgr(Color.White)); //draw current state in White drawCross(measurementPoint, new Bgr(Color.Red)); //draw the measurement in Red drawCross(predictPoint, new Bgr(Color.Green)); //draw the prediction (the next state) in green img.Draw(new LineSegment2DF(statePoint, predictPoint), new Bgr(Color.Magenta), 1); //Draw a line between the current position and prediction of next position //Trace.WriteLine(String.Format("Velocity: {0}", tracker.CorrectedState[1, 0])); #endregion syntheticData.GoToNextState(); viewer.Image = img; }); timer.Start(); viewer.Disposed += delegate(Object sender, EventArgs e) { timer.Stop(); }; viewer.Text = "Actual State: White; Measurement: Red; Prediction: Green"; viewer.ShowDialog(); }