首页
/ 卡尔曼滤波器在二维空间中的应用与实现

卡尔曼滤波器在二维空间中的应用与实现

2025-07-10 07:56:51作者:裴锟轩Denise

前言

卡尔曼滤波器是一种强大的状态估计算法,广泛应用于信号处理、导航系统、机器人技术等领域。本文将深入探讨二维卡尔曼滤波器的数学原理和实现方法,并通过眼动追踪实验数据展示其平滑效果。

线性动态系统(LDS)基础

线性动态系统(LDS)是卡尔曼滤波器的理论基础,它描述了系统状态随时间演化的过程。在二维空间中,LDS可以表示为:

状态方程

s_t = D * s_{t-1} + w_t

其中:

  • s_t 是t时刻的状态向量(2维)
  • D 是状态转移矩阵(2×2)
  • w_t 是过程噪声,服从N(0,Q)分布

观测方程

m_t = H * s_t + η_t

其中:

  • m_t 是t时刻的观测向量(2维)
  • H 是观测矩阵(2×2)
  • η_t 是观测噪声,服从N(0,R)分布

系统采样实现

我们可以通过以下步骤生成LDS的样本数据:

  1. 初始化系统参数
  2. 生成过程噪声和观测噪声样本
  3. 按照状态方程和观测方程递推计算状态和观测值
def sample_lds(n_timesteps, params, seed=0):
    # 设置随机种子
    np.random.seed(seed)
    
    # 生成噪声样本
    mi = stats.multivariate_normal(cov=params['Q']).rvs(n_timesteps)
    eta = stats.multivariate_normal(cov=params['R']).rvs(n_timesteps)
    
    # 初始化状态和观测数组
    state = np.zeros((n_timesteps, params['D'].shape[0]))
    obs = np.zeros((n_timesteps, params['H'].shape[0]))
    
    # 递推计算状态和观测
    for t in range(n_timesteps):
        if t == 0:
            # 初始状态
            state[t] = stats.multivariate_normal(
                mean=params['mu_0'], 
                cov=params['sigma_0']).rvs()
        else:
            # 根据状态方程计算当前状态
            state[t] = params['D'] @ state[t-1] + mi[t]
        
        # 根据观测方程计算当前观测
        obs[t] = params['H'] @ state[t] + eta[t]
    
    return state, obs

卡尔曼滤波算法实现

卡尔曼滤波分为预测和更新两个步骤:

预测步骤

ŝ_t|t-1 = D * ŝ_t-1|t-1
Σ̂_t|t-1 = D * Σ_t-1|t-1 * D^T + Q

更新步骤

K_t = Σ̂_t|t-1 * H^T * (H * Σ̂_t|t-1 * H^T + R)^-1
ŝ_t|t = ŝ_t|t-1 + K_t * (m_t - H * ŝ_t|t-1)
Σ_t|t = (I - K_t * H) * Σ̂_t|t-1

Python实现如下:

def kalman_filter(observations, params):
    n_timesteps = observations.shape[0]
    n_dim_state = params['D'].shape[0]
    
    # 初始化
    mu = np.zeros((n_timesteps, n_dim_state))
    sigma = np.zeros((n_timesteps, n_dim_state, n_dim_state))
    
    # 初始状态
    mu[0] = params['mu_0']
    sigma[0] = params['sigma_0']
    
    for t in range(1, n_timesteps):
        # 预测步骤
        mu_pred = params['D'] @ mu[t-1]
        sigma_pred = params['D'] @ sigma[t-1] @ params['D'].T + params['Q']
        
        # 更新步骤
        K = sigma_pred @ params['H'].T @ np.linalg.inv(
            params['H'] @ sigma_pred @ params['H'].T + params['R'])
        
        mu[t] = mu_pred + K @ (observations[t] - params['H'] @ mu_pred)
        sigma[t] = (np.eye(n_dim_state) - K @ params['H']) @ sigma_pred
    
    return mu, sigma

眼动追踪数据平滑应用

卡尔曼滤波器特别适合处理眼动追踪数据,可以有效去除测量噪声,得到平滑的眼球运动轨迹。我们使用真实眼动数据进行演示:

# 加载眼动数据
subjects, images = load_eyetracking_data()

# 选择一组数据
data = subjects[0]['fixations'][0]

# 创建卡尔曼滤波器
kf = pykalman.KalmanFilter(
    transition_matrices=np.eye(2),
    observation_matrices=np.eye(2),
    transition_covariance=0.1*np.eye(2),
    observation_covariance=0.1*np.eye(2))

# 应用卡尔曼滤波
mu, _ = kf.smooth(data)

# 可视化结果
fig, ax = plt.subplots(figsize=(10, 6))
ax.scatter(data[:,0], data[:,1], c='m', s=100, alpha=0.7, label='原始数据')
ax.plot(mu[:,0], mu[:,1], 'limegreen', linewidth=3, label='滤波后轨迹')
ax.legend()
plt.show()

总结

本文详细介绍了二维卡尔曼滤波器的原理和实现方法,包括:

  1. 线性动态系统的数学描述
  2. 系统采样方法
  3. 卡尔曼滤波算法的预测和更新步骤
  4. 在眼动追踪数据平滑中的应用

卡尔曼滤波器通过结合系统动力学模型和观测数据,能够有效地估计隐藏状态,在噪声环境下表现出色。理解其数学原理和实现细节,有助于我们在各种实际应用中更好地利用这一强大工具。