Ddddd4431 2023-05-19 12:41 采纳率: 90%
浏览 10
已结题

卡尔曼滤波预测的跟踪框过大或过小的问题

使用deepsort做目标跟踪,有时会出现这样的情况:

img

当目标活动较大或者由垂直变为平行式,
卡尔曼滤波所预测的跟踪框会比检测框大,或者小。虽然能做到跟踪同一目标,但是跟踪框内会包含出跟踪目标外的对于信息,或者跟踪框内只包含跟踪目标的部分信息。
请问需要怎么解决这个问题?是否需要修改代码中的卡尔曼滤波的相关参数?
这是源码:请教需要改哪些地方

# vim: expandtab:ts=4:sw=4
import numpy as np
import scipy.linalg


chi2inv95 = {
    1: 3.8415,
    2: 5.9915,
    3: 7.8147,
    4: 9.4877,
    5: 11.070,
    6: 12.592,
    7: 14.067,
    8: 15.507,
    9: 16.919}


class KalmanFilter(object):
    """
    一个简单的卡尔曼滤波器,用于跟踪图像空间中的边界框。
     8维状态空间
        x, y, a, h, vx, vy, va, vh
    包含边界框中心位置(x,y),纵横比a,高度h,以及它们各自的速度。
    物体运动遵循恒定速度模型。 边界框位置(x, y, a, h) 作为对状态空间的直接观察(线性观察模型)。
    """

    def __init__(self):
        ndim, dt = 4, 1.

        # 创建卡尔曼滤波器模型矩阵.
        self._motion_mat = np.eye(2 * ndim, 2 * ndim)  # 创建8*8的单位矩阵
        for i in range(ndim):
            self._motion_mat[i, ndim + i] = dt

        self._update_mat = np.eye(ndim, 2 * ndim)   # 4*8
        self._std_weight_position = 1. / 20
        self._std_weight_velocity = 1. / 160

    def initiate(self, measurement):
        mean_pos = measurement
        mean_vel = np.zeros_like(mean_pos)
        mean = np.r_[mean_pos, mean_vel]

        std = [
            2 * self._std_weight_position * measurement[3],
            2 * self._std_weight_position * measurement[3],
            1e-2,
            2 * self._std_weight_position * measurement[3],
            10 * self._std_weight_velocity * measurement[3],
            10 * self._std_weight_velocity * measurement[3],
            1e-5,
            10 * self._std_weight_velocity * measurement[3]]
        covariance = np.diag(np.square(std))
        return mean, covariance

    def predict(self, mean, covariance):
        std_pos = [
            self._std_weight_position * mean[3],
            self._std_weight_position * mean[3],
            1e-2,
            self._std_weight_position * mean[3]]
        std_vel = [
            self._std_weight_velocity * mean[3],
            self._std_weight_velocity * mean[3],
            1e-5,
            self._std_weight_velocity * mean[3]]
        motion_cov = np.diag(np.square(np.r_[std_pos, std_vel]))

        #mean = np.dot(self._motion_mat, mean)
        mean = np.dot(mean, self._motion_mat.T)
        covariance = np.linalg.multi_dot((
            self._motion_mat, covariance, self._motion_mat.T)) + motion_cov

        return mean, covariance

    def project(self, mean, covariance):
        std = [
            self._std_weight_position * mean[3],
            self._std_weight_position * mean[3],
            1e-1,
            self._std_weight_position * mean[3]]
        innovation_cov = np.diag(np.square(std))

        mean = np.dot(self._update_mat, mean)
        covariance = np.linalg.multi_dot((
            self._update_mat, covariance, self._update_mat.T))
        return mean, covariance + innovation_cov

    def multi_predict(self, mean, covariance):
        std_pos = [
            self._std_weight_position * mean[:, 3],
            self._std_weight_position * mean[:, 3],
            1e-2 * np.ones_like(mean[:, 3]),
            self._std_weight_position * mean[:, 3]]
        std_vel = [
            self._std_weight_velocity * mean[:, 3],
            self._std_weight_velocity * mean[:, 3],
            1e-5 * np.ones_like(mean[:, 3]),
            self._std_weight_velocity * mean[:, 3]]
        sqr = np.square(np.r_[std_pos, std_vel]).T

        motion_cov = []
        for i in range(len(mean)):
            motion_cov.append(np.diag(sqr[i]))
        motion_cov = np.asarray(motion_cov)
        mean = np.dot(mean, self._motion_mat.T)
        left = np.dot(self._motion_mat, covariance).transpose((1, 0, 2))
        covariance = np.dot(left, self._motion_mat.T) + motion_cov

        return mean, covariance

    def update(self, mean, covariance, measurement):
        projected_mean, projected_cov = self.project(mean, covariance)

        chol_factor, lower = scipy.linalg.cho_factor(
            projected_cov, lower=True, check_finite=False)

        kalman_gain = scipy.linalg.cho_solve(
            (chol_factor, lower), np.dot(covariance, self._update_mat.T).T,
            check_finite=False).T
        innovation = measurement - projected_mean

        new_mean = mean + np.dot(innovation, kalman_gain.T)
        new_covariance = covariance - np.linalg.multi_dot((
            kalman_gain, projected_cov, kalman_gain.T))
        return new_mean, new_covariance

    def gating_distance(self, mean, covariance, measurements,
                        only_position=False, metric='maha'):
        mean, covariance = self.project(mean, covariance)
        if only_position:
            mean, covariance = mean[:2], covariance[:2, :2]
            measurements = measurements[:, :2]

        d = measurements - mean
        if metric == 'gaussian':
            return np.sum(d * d, axis=1)
        elif metric == 'maha':
            cholesky_factor = np.linalg.cholesky(covariance)
            z = scipy.linalg.solve_triangular(
                cholesky_factor, d.T, lower=True, check_finite=False,
                overwrite_b=True)
            squared_maha = np.sum(z * z, axis=0)
            return squared_maha
        else:
            raise ValueError('invalid distance metric')

  • 写回答

1条回答 默认 最新

  • 技术宅program 2023-05-19 13:55
    关注

    以下答案由GPT-4.0Plus大模型与博主A努力中.......共同编写:

    1. 过程噪声参数设置过大或过小。过程噪声参数决定了跟踪框的扩散程度,过大会导致跟踪框过度扩散,过小时跟踪框变化不够敏感。我建议适当减小self._std_weight_velocity参数,限制跟踪框运动过快的情况。
    2. 观测噪声参数设置过大或过小。观测噪声决定了跟踪框对观测数据的聚合程度。过大会导致跟踪框无法及时根据观测数据调整,过小时跟踪框会过度聚集在观测数据附近。我建议适当增加self._std_weight_position参数,给跟踪框更大的调整空间。
    3. 预测迭代次数过多或过少。迭代次数过多会导致跟踪框过度扩散,过少时跟踪框无法完全fit观测数据。一般3-5次迭代可以获得较好效果。我建议将多目标跟踪的迭代次数self.multi_predict()适当减小,限制跟踪框过度扩散的趋势。
    4. kalman gain过大或过小。kalman gain决定观测数据对跟踪框修正的程度。过大会导致跟踪框无法及时调整,过小时跟踪框无法充分利用观测信息。我建议在update()方法中,适当增大或减小kalman_gain,找到可以令跟踪框既利用观测数据又不致过度聚集的合适值。
    5. 相机内参设置是否正确。如果相机内参设置不准确,跟踪框的大小也会受到影响。我建议检查相机的焦距、像素等参数是否设置正确。

    总之,导致卡尔曼滤波跟踪框过大或过小的原因主要在于过程噪声、观测噪声、预测迭代次数、kalman gain以及相机内参等参数设置不当。我提出的建议可以逐步实验,选取合适的参数组合来解决这个问题。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 6月3日
  • 已采纳回答 5月26日
  • 创建了问题 5月19日

悬赏问题

  • ¥30 STM32 INMP441无法读取数据
  • ¥100 求汇川机器人IRCB300控制器和示教器同版本升级固件文件升级包
  • ¥15 用visualstudio2022创建vue项目后无法启动
  • ¥15 x趋于0时tanx-sinx极限可以拆开算吗
  • ¥500 把面具戴到人脸上,请大家贡献智慧
  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。
  • ¥15 各位 帮我看看如何写代码,打出来的图形要和如下图呈现的一样,急
  • ¥30 c#打开word开启修订并实时显示批注
  • ¥15 如何解决ldsc的这条报错/index error
  • ¥15 VS2022+WDK驱动开发环境