// Set up the initial values for the Kalman filter
    void InitializeKalmanFilter()
    {
        // Create the Kalman Filter
        _kalman = Cv.CreateKalman(4, 2, 0);

        // Set the Kalman filter initial state
        _kalman.StatePre.Set2D(0, 0, _rectToTrack.X); // Initial X position
        _kalman.StatePre.Set2D(1, 0, _rectToTrack.Y); // Initial Y position
        _kalman.StatePre.Set2D(2, 0, 0);              // Initial X velocity
        _kalman.StatePre.Set2D(3, 0, 0);              // Initial Y velocity

        // Prediction Equations

        // X position is a function of previous X positions and previous X velocities
        _kalman.TransitionMatrix.Set2D(0, 0, 1);
        _kalman.TransitionMatrix.Set2D(1, 0, 0);
        _kalman.TransitionMatrix.Set2D(2, 0, 1);
        _kalman.TransitionMatrix.Set2D(3, 0, 0);

        // Y position is a function of previous Y positions and previous Y velocities
        _kalman.TransitionMatrix.Set2D(0, 1, 0);
        _kalman.TransitionMatrix.Set2D(1, 1, 1);
        _kalman.TransitionMatrix.Set2D(2, 1, 0);
        _kalman.TransitionMatrix.Set2D(3, 1, 1);

        // X velocity is a function of previous X velocities
        _kalman.TransitionMatrix.Set2D(0, 2, 0);
        _kalman.TransitionMatrix.Set2D(1, 2, 0);
        _kalman.TransitionMatrix.Set2D(2, 2, 1);
        _kalman.TransitionMatrix.Set2D(3, 2, 0);

        // Y velocity is a function of previous Y velocities
        _kalman.TransitionMatrix.Set2D(0, 3, 0);
        _kalman.TransitionMatrix.Set2D(1, 3, 0);
        _kalman.TransitionMatrix.Set2D(2, 3, 0);
        _kalman.TransitionMatrix.Set2D(3, 3, 1);

        // set Kalman Filter
        Cv.SetIdentity(_kalman.MeasurementMatrix, 1.0f);
        Cv.SetIdentity(_kalman.ProcessNoiseCov, 0.4f);   //0.4
        Cv.SetIdentity(_kalman.MeasurementNoiseCov, 3f); //3
        Cv.SetIdentity(_kalman.ErrorCovPost, 1.0f);
    }
Example #2
0
        /// <summary>
        /// kalman 初期化ルーチン
        /// </summary>
        /// <param name="elem">読み出した要素</param>
        public void kalman_init()
        {
            CvKalman kalman = kv_kalman;

            // 初期化(kalman)
            kalman_id = 0;
            Cv.SetIdentity(kalman.MeasurementMatrix, Cv.RealScalar(1.0));
            Cv.SetIdentity(kalman.ProcessNoiseCov, Cv.RealScalar(1e-4));
            Cv.SetIdentity(kalman.MeasurementNoiseCov, Cv.RealScalar(0.001));
            Cv.SetIdentity(kalman.ErrorCovPost, Cv.RealScalar(1.0));

            measurement.Zero();

            // 等速直線運動モデル(kalman)

            /* unsafe
             * {
             *  kalman.DynamMatr[0] = 1.0f; kalman.DynamMatr[1] = 0.0f; kalman.DynamMatr[2] = 1.0f; kalman.DynamMatr[3] = 0.0f;
             *  kalman.DynamMatr[4] = 0.0f; kalman.DynamMatr[5] = 1.0f; kalman.DynamMatr[6] = 0.0f; kalman.DynamMatr[7] = 1.0f;
             *  kalman.DynamMatr[8] = 0.0f; kalman.DynamMatr[9] = 0.0f; kalman.DynamMatr[10] = 1.0f; kalman.DynamMatr[11] = 0.0f;
             *  kalman.DynamMatr[12] = 0.0f; kalman.DynamMatr[13] = 0.0f; kalman.DynamMatr[14] = 0.0f; kalman.DynamMatr[15] = 1.0f;
             * }*/
            kalman.TransitionMatrix.Set2D(0, 0, 1.0f);
            kalman.TransitionMatrix.Set2D(0, 1, 0.0f);
            kalman.TransitionMatrix.Set2D(0, 2, 1.0f);
            kalman.TransitionMatrix.Set2D(0, 3, 0.0f);

            kalman.TransitionMatrix.Set2D(1, 0, 0.0f);
            kalman.TransitionMatrix.Set2D(1, 1, 1.0f);
            kalman.TransitionMatrix.Set2D(1, 2, 0.0f);
            kalman.TransitionMatrix.Set2D(1, 3, 1.0f);

            kalman.TransitionMatrix.Set2D(2, 0, 0.0f);
            kalman.TransitionMatrix.Set2D(2, 1, 0.0f);
            kalman.TransitionMatrix.Set2D(2, 2, 1.0f);
            kalman.TransitionMatrix.Set2D(2, 3, 0.0f);

            kalman.TransitionMatrix.Set2D(3, 0, 0.0f);
            kalman.TransitionMatrix.Set2D(3, 1, 0.0f);
            kalman.TransitionMatrix.Set2D(3, 2, 0.0f);
            kalman.TransitionMatrix.Set2D(3, 3, 1.0f);
        }
Example #3
0
        public unsafe Kalman()
        {
            // cvKalmanPredict, cvKalmanCorrect
            // カルマンフィルタを用いて回転する点を追跡する

            // A matrix data
            float[] A = new float[] { 1, 1, 0, 1 };

            using (IplImage img = new IplImage(500, 500, BitDepth.U8, 3))
                using (CvKalman kalman = new CvKalman(2, 1, 0))
                    using (CvWindow window = new CvWindow("Kalman", WindowMode.AutoSize))
                    {
                        // state is (phi, delta_phi) - angle and angle increment
                        CvMat state         = new CvMat(2, 1, MatrixType.F32C1);
                        CvMat process_noise = new CvMat(2, 1, MatrixType.F32C1);
                        // only phi (angle) is measured
                        CvMat measurement = new CvMat(1, 1, MatrixType.F32C1);

                        measurement.SetZero();
                        CvRandState rng  = new CvRandState(0, 1, -1, DistributionType.Uniform);
                        int         code = -1;

                        for (; ;)
                        {
                            Cv.RandSetRange(rng, 0, 0.1, 0);
                            rng.DistType = DistributionType.Normal;

                            Marshal.Copy(A, 0, kalman.TransitionMatrix.Data, A.Length);
                            kalman.MeasurementMatrix.SetIdentity(1);
                            kalman.ProcessNoiseCov.SetIdentity(1e-5);
                            kalman.MeasurementNoiseCov.SetIdentity(1e-1);
                            kalman.ErrorCovPost.SetIdentity(1);
                            // choose random initial state
                            Cv.Rand(rng, kalman.StatePost);
                            rng.DistType = DistributionType.Normal;

                            for (; ;)
                            {
                                float   state_angle = state.DataSingle[0];
                                CvPoint state_pt    = CalcPoint(img, state_angle);

                                // predict point position
                                CvMat   prediction    = kalman.Predict(null);
                                float   predict_angle = prediction.DataSingle[0];
                                CvPoint predict_pt    = CalcPoint(img, predict_angle);

                                Cv.RandSetRange(rng, 0, Math.Sqrt(kalman.MeasurementNoiseCov.DataSingle[0]), 0);
                                Cv.Rand(rng, measurement);

                                // generate measurement
                                Cv.MatMulAdd(kalman.MeasurementMatrix, state, measurement, measurement);

                                float   measurement_angle = measurement.DataArraySingle[0];
                                CvPoint measurement_pt    = CalcPoint(img, measurement_angle);

                                img.SetZero();
                                DrawCross(img, state_pt, CvColor.White, 3);
                                DrawCross(img, measurement_pt, CvColor.Red, 3);
                                DrawCross(img, predict_pt, CvColor.Green, 3);
                                img.Line(state_pt, measurement_pt, new CvColor(255, 0, 0), 3, LineType.AntiAlias, 0);
                                img.Line(state_pt, predict_pt, new CvColor(255, 255, 0), 3, LineType.AntiAlias, 0);

                                // adjust Kalman filter state
                                kalman.Correct(measurement);

                                Cv.RandSetRange(rng, 0, Math.Sqrt(kalman.ProcessNoiseCov.DataSingle[0]), 0);
                                Cv.Rand(rng, process_noise);
                                Cv.MatMulAdd(kalman.TransitionMatrix, state, process_noise, state);

                                window.ShowImage(img);
                                // break current simulation by pressing a key
                                code = CvWindow.WaitKey(100);
                                if (code > 0)
                                {
                                    break;
                                }
                            }
                            // exit by ESCAPE
                            if (code == 27)
                            {
                                break;
                            }
                        }
                    }
        }