簡體   English   中英

網格數據上的有效卡爾曼濾波器實現

[英]Efficient Kalman filter implementation on gridded data

我編寫了一個非常簡單的卡爾曼濾波器,該濾波器可以按時間序列運行(包括數據間隔)。 它工作得很好,但是我碰巧有一個數據數據立方體 (形狀為Nt, Ny, Nx的數組),並且我想對數據立方體中的每個像素應用我的時間Kalman濾波器。 我已經做了很明顯的事情(在最后兩個維度上循環),但這花費了相當長的時間。

最終,我總是總是不得不從各個“像素”中提取數據,並構造相關的矩陣/向量,因此該過程相當緩慢(請注意,每個各個時間序列中的間隔是不同的,通常,H將狀態鏈接到觀察值的矩陣)。 我不熟悉cython,它可能會有所幫助(只是我不熟悉它)。

我只是想知道,對問題進行巧妙的措辭,或者巧妙的數據結構,是否可以使時間過濾效率更高。 我寧願只使用numpy / scipy,而不要使用OpenCV,否則,根據額外的軟件包,這將是一個麻煩。

我制作了一個像這樣的簡單矢量化卡爾曼濾波器來處理電影幀。 它非常快速,但目前僅限於一維輸入和輸出,並且不對任何濾波器參數進行EM優化。

import numpy as np

def runkalman(y, RQratio=10., meanwindow=10):
    """
    A simple vectorised 1D Kalman smoother

    y       Input array. Smoothing is always applied over the first 
            dimension

    RQratio     An estimate of the ratio of the variance of the output 
            to the variance of the state. A higher RQ ratio will 
            result in more smoothing.

    meanwindow  The initial mean and variance of the output are 
            estimated over this number of timepoints from the start 
            of the array

    References:
        Ghahramani, Z., & Hinton, G. E. (1996). Parameter Estimation for
        Linear Dynamical Systems.
        http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.55.5997

        Yu, B., Shenoy, K., & Sahani, M. (2004). Derivation of Extented
        Kalman Filtering and Smoothing Equations.
        http://www-npl.stanford.edu/~byronyu/papers/derive_eks.pdf
    """

    x,vpre,vpost = forwardfilter(y, RQratio=RQratio, meanwindow=meanwindow)
    x,v = backpass(x, vpre, vpost)
    x[np.isnan(x)] = 0.
    return x

def forwardfilter(y, RQratio=10., meanwindow=10):
    """
    the Kalman forward (filter) pass:

        xpost,Vpre,Vpost = forwardfilter(y)
    """

    y = np.array(y,copy=False,subok=True,dtype=np.float32)

    xpre = np.empty_like(y)
    xpost = np.empty_like(y)
    Vpre = np.empty_like(y)
    Vpost = np.empty_like(y)
    K = np.empty_like(y)

    # initial conditions
    pi0 = y[:meanwindow].mean(0)
    ystd = np.std(y,0)
    R = ystd * ystd
    Q = R / RQratio
    V0 = Q

    xpre[0] = xpost[0] = pi0
    Vpre[0] = Vpost[0] = V0
    K[0] = 0

    # loop forwards through time
    for tt in xrange(1, y.shape[0]):

        xpre[tt] = xpost[tt-1]
        Vpre[tt] = Vpost[tt-1] + Q

        K[tt] = Vpre[tt] / (Vpre[tt] + R)
        xpost[tt] = xpre[tt] + K[tt] * (y[tt] - xpre[tt])
        Vpost[tt] = Vpre[tt] - K[tt] * (Vpre[tt])

    return xpost,Vpre,Vpost

def backpass(x, Vpre, V):
    """ 
    the Kalman backward (smoothing) pass:

        xpost,Vpost = backpass(x,Vpre,V)
    """

    xpost = np.empty_like(x)
    Vpost = np.empty_like(x)
    J = np.empty_like(x)

    xpost[-1] = x[-1]
    Vpost[-1] = V[-1]

    # loop backwards through time
    for tt in xrange(x.shape[0]-1, 0, -1):
        J[tt-1] = V[tt-1] / Vpre[tt]
        xpost[tt-1] = x[tt-1] + J[tt-1] * (xpost[tt] - x[tt-1])
        Vpost[tt-1] = V[tt-1] + J[tt-1] * (Vpost[tt] - Vpre[tt]) * J[tt-1]

    return xpost,Vpost 

如果有人知道Python中支持多維輸入/輸出和EM參數優化的矢量化Kalman平滑器實現,我很想聽聽它! 我向PyKalman維護人員提出了功能要求,但他們說,清晰度是重中之重,而不是速度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM