改变 OpenCV 卡尔曼滤波器的增益以使其响应更快

Changing the Gain in OpenCV's Kalman Filter to make it more responsive

对于跟踪图像中边界框的位置和速度,其中测量值不是很嘈杂,但边界框移动非常快

state_size = 6; // x,y,w,h,vx,vy of BB
meas_size = 4; // x,y,w,h of BB
contr_size = 0;
int type = CV_32F;

使用

初始化转换、过程噪声和测量噪声
cv::KalmanFilter kf;
kf.init(state_size, meas_size, contr_size, type);

setIdentity(kf.transitionMatrix);
kf.transitionMatrix.at<float>(2) = params.dt;
kf.transitionMatrix.at<float>(9) = params.dt;

kf.processNoiseCov.at<float>(0) = params.proc_noise_cov_p0;
kf.processNoiseCov.at<float>(7) = params.proc_noise_cov_p0;
kf.processNoiseCov.at<float>(14) = params.proc_noise_cov_p1;
kf.processNoiseCov.at<float>(21) = params.proc_noise_cov_p1;
kf.processNoiseCov.at<float>(28) = params.proc_noise_cov_p0;
kf.processNoiseCov.at<float>(35) = params.proc_noise_cov_p0;

setIdentity(kf.measurementNoiseCov, cv::Scalar(params.meas_noise_cov_p0));

1.如何让过滤器响应更快?

2。转移矩阵的初始值有什么影响?

为了使滤波器响应更快,OpenCV 的卡尔曼滤波器似乎有一个增益矩阵 https://docs.opencv.org/trunk/dd/d6a/classcv_1_1KalmanFilter.html#a077d73eb075b00779dc009a9057c27c3 (Kalman gain matrix (K(k)): K(k)=P'(k)*Ht*inv(H*P'(k)*Ht+R))

但不清楚if/how我们应该直接增加它。它似乎不受过程噪声协方差矩阵 (Q) 的影响,但根据 processNoiseCov 正是我应该增加的,以使其响应更快。

卡尔曼滤波器是一种线性滤波器,最适合具有高斯噪声的线性系统。 假设没有噪音并且您的系统是完全线性的。因此,转换矩阵描述了状态如何变化并且不被卡尔曼滤波器更新。如果转换矩阵只是恒等式,则意味着状态永远不会改变。您的案例的转换矩阵应该是在 (0,4) 和 (1,5) 中具有 dt 条目的标识(因为给定矩形的最后状态,下一个状态是当前位置 (x,y) + dt *(vx,vy)。这取决于应用程序是否有更多关于状态变化的信息(宽度和高度发生了什么)。

现实受到噪音的影响。卡尔曼滤波器考虑了两种不同的类型。结构/过程噪声和测量噪声。 两者都会影响增益矩阵。增益矩阵不是由用户给出的,而是通过历史、测量协方差和过程协方差计算的。 如果测量没有噪声,您可能会降低测量协方差(至少检查您的方差在哪个范围内可能是值得的),通过“增加”测量矩阵来减少当前估计中观察的影响。另一部分是过程噪声协方差。这部分影响 P'(k)。这是给定最后状态(及其协方差)的当前状态的协方差。如果您完全了解系统的行为方式(这意味着您知道转换矩阵),则可以假设过程噪声为零。如果你增加你所说的过程噪声协方差,那么两个时间戳之间的传播存在错误,这不是由转换矩阵解释的并且是随机的。 (也许你知道宽度或高度平均变化多少。这个方差可以用在对角线元素中,对应于 w 和 h(2 和 3))。 因此,为了使过滤器响应更快,您必须告诉他,您不确定实际变化,因此您必须增加过程噪声。对于参数调整,我建议您仔细查看您的数据。 因此,您必须增加过程噪声并降低测量噪声以使滤波器响应更快。