2014-02-26 22 views
4

在實施了卡爾曼濾波器之後,該卡爾曼濾波器在用Haar級聯先前檢測到人臉後接收來自camshift頭部追蹤的真實測量值。我用來自Haar Cascade的頭部位置初始化來自卡爾曼濾波器的狀態前置和後置變量,並且在進行camshift時調用kalman預測和校正以獲得一些平滑。問題在於預測值和校正值始終是haar級聯的起始值。我應該在做camshift時更新state pre或state post變量嗎?卡爾曼預測和校正與起始值相同

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在做haar級聯時被調用一次,並且跟蹤窗口是初始頭部位置。

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; 

} 

這不是工作,始終只返回從this出色的初始頭position.The傢伙在調用預測函數之前,博客正在用實際測量值來更改狀態帖子,但唯一改變的是,預測值和校正值現在與每幀的camshift頭部位置相同。

+0

向我們展示您的卡爾曼預測和修正代碼。這很可能出現在你錯誤的地方...... – MoonKnight

+0

我使用opencvsharp庫中的標準方法。但就像我說的那樣,我認爲在狀態變量前和變量初始化的時候有些事情是不正確的。也可能是標準方法的內部問題,因爲我沒有看到任何人,除了我提到的使用opencvsharp包裝的博客。如果是這樣,我想我需要按照你的建議制定我自己的方法。 –

+1

也許,但在上面我看不到數據的數組,只有一個點。如果你運行一個過濾器,當然你會得到起始狀態向量。卡爾曼濾波器的整體思想是它是遞歸的,並以某種方式'訓練'自己在謹慎的時間內找到與觀測矢量相關的狀態向量。如果這是來自一個衆所周知的庫,它可能會做正確的事情,你需要有一個時間序列的觀察向量(可能是1D)y_ {n} [nPoints]並運行該過濾器。我會回去閱讀更多關於實施... – MoonKnight

回答

3

我不會寫這樣的過濾器。我會爲所有卡爾曼型濾波器使用以下合約。

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

我知道這不是使用你的代碼,但我希望它有一些幫助。如果您決定要沿着這條路線走下去,我會用實際卡爾曼濾波器代碼來幫助您...