gpt4 book ai didi

c# - 卡尔曼预测和校正与起始值相同

转载 作者:太空狗 更新时间:2023-10-30 01:36:31 25 4
gpt4 key购买 nike

我正在实现一个卡尔曼滤波器,该滤波器在先前使用 Haar Cascade 检测到面部后,从凸轮位移头部跟踪接收真实测量值。我使用来自 Haar 级联的头部位置初始化来自卡尔曼滤波器的状态前变量和状态后变量,并在进行凸轮移位时调用卡尔曼预测和校正以获得一些平滑。问题是预测值和校正值始终是 haar 级联的起始值。我应该在进行 camshift 时更新状态前或状态后变量吗?

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};

在做haar cascade时会调用一次initkalman,tracking window就是初始的head position。

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);
}

我在每次 camshift 迭代中调用 processKalman 函数,现在正在跟踪实际头部位置的窗口

    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;

}

这不起作用,总是只返回初始头部位置。来自 this 的人优秀的博客是在调用预测函数之前用实际测量值改变状态帖子,但这样做对我来说唯一改变的是预测值和校正值现在与每一帧的凸轮位移头位置相同。

最佳答案

我不会这样写你的过滤器。我将为所有卡尔曼型滤波器使用以下契约(Contract)。

public interface IKalmanFilter
{
/// <summary>
/// The current observation vector being used.
/// </summary>
Vector<double> Observation { get; }

/// <summary>
/// The best estimate of the current state of the system.
/// </summary>
Vector<double> State { get; }

/// <summary>
/// The covariance of the current state of the filter. Higher covariances
/// indicate a lower confidence in the state estimate.
/// </summary>
Matrix<double> StateVariance { get; }

/// <summary>
/// The one-step-ahead forecast error of y given the previous measurement.
/// </summary>
Vector<double> ForecastError { get; }

/// <summary>
/// The one-step ahead forecast error variance.
/// </summary>
Matrix<double> ForecastErrorVariance { get; }

/// <summary>
/// The Kalman Gain matrix.
/// </summary>
Matrix<double> KalmanGain { get; }

/// <summary>
/// Performs a prediction of the next state of the system.
/// </summary>
/// <param name="T">The state transition matrix.</param>
void Predict(Matrix<double> T);

/// <summary>
/// Perform a prediction of the next state of the system.
/// </summary>
/// <param name="T">The state transition matrix.</param>
/// <param name="R">The linear equations to describe the effect of the noise
/// on the system.</param>
/// <param name="Q">The covariance of the noise acting on the system.</param>
void Predict(Matrix<double> T, Matrix<double> R, Matrix<double> Q);

/// <summary>
/// Updates the state estimate and covariance of the system based on the
/// given measurement.
/// </summary>
/// <param name="y">The measurements of the system.</param>
/// <param name="T">The state transition matrix.</param>
/// <param name="Z">Linear equations to describe relationship between
/// measurements and state variables.</param>
/// <param name="H">The covariance matrix of the measurements.</param>
void Update(Vector<double> y, Matrix<double> T,
Matrix<double> Z, Matrix<double> H, Matrix<double> Q);
}

在哪里Vector<T>Matrix<T>我自己的实现是来自 MathNet.Numerics 的那些。我展示这一点的原因是,此结构将使您能够对过滤后的数据集运行平滑递归并执行最大似然参数估计(如果您需要)。

使用上述模板实现线性高斯卡尔曼滤波器后,您可以为时间序列中每个数据点的循环中的某些数据集调用它(请注意,循环不在滤波器内完成代码)。对于一维状态/观察向量,我们可以这样写:

// Set default initial state and variance.
a = Vector<double>.Build.Dense(1, 0.0d);
P = Matrix<double>.Build.Dense(1, 1, Math.Pow(10, 7));

// Run the filter.
List<double> filteredData = new List<double>();
IKalmanFilter filter = new KalmanFilter(a, P);
for (int i = 0; i < Data.Length; i++)
{
filter.Predict(T, R, Q);
Vector<double> v = DenseVector.Create(1, k => Convert.ToDouble(Data[i]));
filter.Update(v, T, Z, H, Q);

// Now to get the filtered state values, you use. (0 as it is one-dimensional data)
filteredData.Add(filter.State[0]);
}

我知道这不是在使用您的代码,但我希望它能有所帮助。如果您决定要走这条路,我会帮助您处理实际的卡尔曼滤波器代码...

关于c# - 卡尔曼预测和校正与起始值相同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22046217/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com