2014-02-26 3 views
4

Haar 캐스케이드로 얼굴을 미리 감지 한 후 캠축 헤드 추적에서 실제 측정 값을받는 칼만 필터를 구현합니다. Haar 캐스 캐 이드의 머리 위치로 칼만 필터의 주 프리 및 스테이트 포스트 변수를 초기화하고 캠 셔프트를 수행하면서 칼만이 예측하고 올바른 것을 호출하여 부드럽게 처리합니다. 문제는 예측되고 수정 된 값이 항상 하얼 폭포에서 출발 한 값이라는 것입니다. 캠 쉬프트를하는 동안 상태 프리 또는 스테이트 포스트 변수를 업데이트해야합니까?칼만 예측 및 보정 시작 값과 동일

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 캐스케이드를 수행하는 동안 initkalman이 한 번 호출되고 추적 창이 초기 머리 위치입니다.

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

나는 훌륭한 this에서 초기 헤드 position.The 사람을 반환 항상 윈도우에게이 작동하지 않는 실제 머리 위치

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; 

} 

를 추적 지금 존재하고, 각 camshift 반복에 processKalman 함수를 호출 블로그는 예측 기능을 호출하기 전에 실제 측정 값으로 주정부를 변경하지만 예측 및 보정 된 값은 이제 각 프레임의 캠 위치 머리 위치와 동일합니다.

+0

칼만 예측 및 수정 코드를 알려주십시오. 여기서 잘못 될 가능성이 있습니다 ... – MoonKnight

+0

나는 opencvsharp 라이브러리에서 표준 방법을 사용합니다. 그러나 내가 말했듯이, 나는 국가의 전후 변수와 그것들의 초기화와 관련하여 무언가가 올바르지 않다고 생각한다. opencvsharp 래퍼를 사용하는 블로그에서 언급 한 사람 외에는 아무 것도 보지 못했기 때문에 표준 메서드의 내부 문제 일 수도 있습니다. 그것이 그렇다면 나는 당신이 제안한대로 내 자신의 방법을 만들 필요가 있다고 생각합니다. –

+1

어쩌면, 그러나 위의 데이터 배열, 단일 지점을 볼 수 없습니다. 코스의 한 지점에 대해 필터를 실행하면 시작 상태 벡터가 다시 나타납니다. 칼만 필터의 전체 개념은 재귀 적이며, 신중한 시간에 관측 벡터와 관련된 상태 벡터를 찾는 '열차'자체라는 것입니다. 이것이 잘 알려진 라이브러리에서 나온 것이라면, 옳은 일을 할 가능성이 있습니다. 시계열 (1D 일 수도 있음) y_ {n} [nPoints]의 시계열이 필요하고 그에 대한 필터를 실행해야합니다. 나는 돌아가서 구현에 대해 더 많이 읽었을 것이다 ... – MoonKnight

답변

3

이렇게 필터를 작성하지 않겠습니다. 모든 Kalman 유형 필터에 대해 다음 계약을 사용합니다. 내 자신의 구현을위한

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에서들을 수 있습니다. 필자가 보았던 이유는이 구조를 사용하면 필터링 된 데이터 세트에서 스무딩 재귀를 실행하고 최대 우도 매개 변수 추정을 수행 할 수 있기 때문입니다 (필요한 경우).

위의 템플릿을 사용하여 선형 가우스 칼만 필터를 구현 한 후에는 시계열의 각 데이터 포인트에 대한 루프의 일부 데이터 세트에 대해 호출 할 수 있습니다 (루프는 필터 코드). 1 차원 상태/관측 벡터의 경우 다음과 같이 쓸 수 있습니다.

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

이 코드는 사용하지 않고 있지만 도움이되기를 바랍니다. 이 경로를 따라 가기로 결정했다면 실제 칼만 필터 코드를 사용하여 도와 드리겠습니다 ...