Kalman2DPositionFilter.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using Emgu.CV;
  7. using Emgu.CV.Structure;
  8. namespace bbiwarg.Utility
  9. {
  10. class Kalman2DPositionFilter
  11. {
  12. private Kalman kalman;
  13. private float mXX, mXY, mYY, processNoiseFactor;
  14. private float fps;
  15. public bool Initialized { get; private set; }
  16. // state: x, y, v_x, v_y
  17. // x: current x position
  18. // y: current y position
  19. // v_x: velocity in x direction
  20. // v_y: velocity in y direction
  21. // a_x: acceleration in x direction
  22. // a_y: acceleration in y direction
  23. public Kalman2DPositionFilter(float mXX, float mXY, float mYY, float processNoiseFactor = 1.0e-4f, int fps = 30)
  24. {
  25. this.mXX = mXX;
  26. this.mXY = mXY;
  27. this.mYY = mYY;
  28. this.processNoiseFactor = processNoiseFactor;
  29. this.fps = fps;
  30. reset();
  31. }
  32. public void reset()
  33. {
  34. // 6 state variables and 2 measurements (0 controls)
  35. kalman = new Kalman(6, 2, 0);
  36. // time step (s)
  37. float t = 1 / fps;
  38. // transition matrix
  39. Matrix<float> transitionMatrix = new Matrix<float>(new float[,]
  40. { {1.0f, 0.0f, 1.0f * t, 0.0f, 0.5f * t * t, 0.0f},
  41. {0.0f, 1.0f, 0.0f, 1.0f * t, 0.0f, 0.5f * t * t},
  42. {0.0f, 0.0f, 1.0f, 0.0f, 1.0f * t, 0.0f},
  43. {0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f * t},
  44. {0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f},
  45. {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}});
  46. kalman.TransitionMatrix = transitionMatrix;
  47. // measurement matrix
  48. Matrix<float> measurementMatrix = new Matrix<float>(new float[,]
  49. { {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, // first measurement = x
  50. {0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f} // second measurement = y
  51. });
  52. kalman.MeasurementMatrix = measurementMatrix;
  53. // measurement noise covariance matrix
  54. Matrix<float> measurementNoiseCovarianceMatrix = new Matrix<float>(2, 2);
  55. measurementNoiseCovarianceMatrix[0, 0] = mXX;
  56. measurementNoiseCovarianceMatrix[0, 1] = measurementNoiseCovarianceMatrix[1, 0] = mXY;
  57. measurementNoiseCovarianceMatrix[1, 1] = mYY;
  58. kalman.MeasurementNoiseCovariance = measurementNoiseCovarianceMatrix;
  59. // process noise covariance matrix
  60. Matrix<float> processNoiseCovarianceMatrix = new Matrix<float>(6, 6);
  61. processNoiseCovarianceMatrix.SetIdentity(new MCvScalar(processNoiseFactor));
  62. kalman.ProcessNoiseCovariance = processNoiseCovarianceMatrix;
  63. // error covariance post matrix (initial value)
  64. Matrix<float> errorCovariancePostMatrix = new Matrix<float>(6, 6);
  65. errorCovariancePostMatrix.SetIdentity(new MCvScalar(processNoiseFactor));
  66. kalman.ErrorCovariancePost = errorCovariancePostMatrix;
  67. Initialized = false;
  68. }
  69. public void setInitialPosition(Vector2D initialPosition)
  70. {
  71. // initial state (x, y, v_x, v_y)
  72. Matrix<float> initialState = new Matrix<float>(new float[] { initialPosition.X, initialPosition.Y, 0.0f, 0.0f, 0.0f, 0.0f });
  73. kalman.CorrectedState = initialState;
  74. Initialized = true;
  75. }
  76. public Vector2D getPrediction()
  77. {
  78. Matrix<float> predicton = kalman.Predict();
  79. return new Vector2D(predicton[0, 0], predicton[1, 0]);
  80. }
  81. // updates the filter and returns the corrected position
  82. public Vector2D getCorrectedPosition(Vector2D rawPosition)
  83. {
  84. Matrix<float> rawPositionMatrix = new Matrix<float>(new float[,]
  85. { {rawPosition.X},
  86. {rawPosition.Y}});
  87. // prediction according to model
  88. kalman.Predict();
  89. // corrected point
  90. Matrix<float> estimate = kalman.Correct(rawPositionMatrix);
  91. return new Vector2D(estimate[0, 0], estimate[1, 0]);
  92. }
  93. }
  94. }