【StrongSort 02】多轨迹算法StrongSort-卡尔曼滤波预测过程

发布时间:2026/10/29 2:03:50

【StrongSort 02】多轨迹算法StrongSort-卡尔曼滤波预测过程 卡尔曼滤波轨迹预测过程源码strong_sort/sort/kalman_filter.py。本文按代码顺序、用实际数字逐步推算predict预测、project投影、update修正、initiate建档四个函数最后是 StrongSORT 级联匹配的核心——gating_distance马氏距离门控。所有数字均用本工程源码实际运行验证过。说明本工程project/update比原版 DeepSORT 多一个 NSA 参数——观测噪声 std 先乘(1 − 置信度)置信度越低的检测话语权越小代码与推算见本文二。本工程 NSA 默认开启本文全部推算也按开启路径走例中检测置信度取 conf 0.8唯一例外是第五节gating_distance的门控投影在代码里不传 confidence/nsa该节 R 仍用未缩放值。调用链谁在调这些函数StrongSort.update() # strong_sort.py 每帧入口 ├─ self.tracker.predict() # 预测先猜这一帧目标在哪 │ └─ for track in self.tracks: # Tracker 逐条轨迹循环没有批量版 │ track.predict() # 轨迹持有自己的 kf 实例 │ └─ kf.predict(mean, covariance) # ← 本文一 ├─ self.tracker.update(detections) # 匹配 修正 │ ├─ linear_assignment.gate_cost_matrix # ← 本文五内部调 track.kf.gating_distance │ ├─ track.update(detection) │ │ └─ kf.update(mean, cov, detection.to_xyah(), │ │ detection.confidence, nsa) # ← 本文三经 project │ └─ Track.__init__ 内部 │ self.kf.initiate(detection.to_xyah()) # 未匹配检测建新轨迹 ← 本文四公式与符号总表符号代码里的真身是什么从哪来mean参数mean状态均值8 维轨迹上一帧的 meaninitiate 建档时初始化covP参数covariance状态协方差8×8对角线是各分量的不确定度轨迹上一帧的 covarianceFself._motion_mat状态转移矩阵8×8匀速模型__init__构造单位阵右上 4×4 填 dt1Q局部变量motion_cov过程噪声协方差8×8 对角阵“匀速假设本身的误差预算”predict 内部用两个噪声权重 × mean[3] 现算hmean[3]这条轨迹的框高像素不是固定值每条轨迹各自取状态向量第 4 个分量_std_weight_position类属性位置噪声权重 1/20__init__写死_std_weight_velocity类属性速度噪声权重 1/160__init__写死Hself._update_mat观测矩阵4×8只取前 4 维__init__构造Rinnovation_covproject 内局部变量观测噪声4×4 对角阵检测框自身的不确定性project 内部现算噪声权重 × mean[3] →NSA 开启时再乘 (1 − 置信度)→ 平方上对角线mean_new返回的mean外推后的状态均值8 维F · mean 算出cov_newP’返回的covariance外推后的协方差不确定性变大F · cov · Fᵀ Q 算出本文三个核心公式predict: mean_new F · mean 位置 位置 速度×1 帧速度不变 cov_new F · cov · Fᵀ Q 不确定性传播变大 project: z_mean H · mean 8 维状态 → 4 维观测空间 S H · cov · Hᵀ R 观测空间的协方差 update: mean_new mean K · (measurement − H · mean) cov_new cov − K · H · cov 本工程写法与 cov − K·S·Kᵀ 恒等一、predict单条轨迹实际推算方法作用输入输出predict预测步按匀速模型把状态外推到下一帧mean: 上一帧状态均值8 维 ndarraycovariance: 上一帧协方差8×8 ndarray(mean, covariance)外推后的均值与协方差不确定性变大输入举例mean [100, 50, 1.5, 40, 8, 0, 0, 0] ← x100, y50, a1.5, h40, vx8, vy0, va0, vh0 cov [[16, 0, 0, 0, 0, 0, 0, 0], [0, 18, 0, 0, 0, 0, 0, 0], [0, 0, 0.5, 0, 0, 0, 0, 0], [0, 0, 0, 14, 0, 0, 0, 0], [0, 0, 0, 0, 6, 0, 0, 0], [0, 0, 0, 0, 0, 5, 0, 0], [0, 0, 0, 0, 0, 0, 0.3, 0], [0, 0, 0, 0, 0, 0, 0, 7]] ← 8×8 对角阵演示值各分量方差不同、交叉项 0第 1 步构造 std_pos位置类 4 个分量的噪声标准差std_pos[self._std_weight_position*mean[3],# x 的噪声 h/20self._std_weight_position*mean[3],# y 的噪声 h/201e-2,# a 的噪声 固定 0.01比例无量纲不随 h 缩放self._std_weight_position*mean[3]]# h 的噪声 h/20代入 h mean[3] 40std_pos [40/20, 40/20, 0.01, 40/20] [2, 2, 0.01, 2]第 2 步构造 std_vel速度类 4 个分量的噪声标准差std_vel[self._std_weight_velocity*mean[3],# vx 的噪声 h/160self._std_weight_velocity*mean[3],# vy 的噪声 h/1601e-5,# va 的噪声 固定 0.00001self._std_weight_velocity*mean[3]]# vh 的噪声 h/160代入 h 40std_vel [40/160, 40/160, 0.00001, 40/160] [0.25, 0.25, 0.00001, 0.25]第 3 步拼成 Q 矩阵motion_covmotion_covnp.diag(np.square(np.r_[std_pos,std_vel]))# np.r_ 把两个 4 元素列表拼成 8 个顺序 状态分量顺序 x,y,a,h,vx,vy,va,vh# np.square 标准差 → 方差平方# np.diag 放到 8×8 对角线上Q diag(2², 2², 0.01², 2², 0.25², 0.25², 0.00001², 0.25²) diag(4, 4, 0.0001, 4, 0.0625, 0.0625, 0.0000000001, 0.0625)第 4 步外推 meanmeannp.dot(self._motion_mat,mean)# F · mean本工程写法F_motion_mat__init__构造右上角的 1 使位置 速度×dtx 100 8 × 1 108 dt 1__init__ 里 ndim, dt 4, 1. 写死 y 50 0 × 1 50 a 1.5 0 × 1 1.5 h 40 0 × 1 40 vx 8, vy 0, va 0, vh 0 速度不变 mean_new [108, 50, 1.5, 40, 8, 0, 0, 0]第 5 步外推 covcovariancenp.linalg.multi_dot((self._motion_mat,covariance,self._motion_mat.T))motion_cov# F · cov · Fᵀ Qcov 是对角阵时结果规律简单新对角线 旧对角线(自己) 旧对角线(对应速度分量) Q(自己)位置分量与自己的速度分量之间产生交叉项 旧速度方差cov_newx 行: 16 6 4 26 交叉项 [x, vx] 6 cov_newy 行: 18 5 4 27 交叉项 [y, vy] 5 cov_newa 行: 0.5 0.3 0.0001 ≈ 0.8001交叉项 [a, va] 0.3 cov_newh 行: 14 7 4 25 交叉项 [h, vh] 7 cov_new速度行: vx 60.06256.0625vy 5.0625va 0.3vh 7.0625输出返回mean_new [108, 50, 1.5, 40, 8, 0, 0, 0] cov_new [[26, 0, 0, 0, 6, 0, 0, 0 ], [0, 27, 0, 0, 0, 5, 0, 0 ], [0, 0, 0.8001,0, 0, 0, 0.3, 0 ], [0, 0, 0, 25, 0, 0, 0, 7 ], [6, 0, 0, 0, 6.0625, 0, 0, 0 ], [0, 5, 0, 0, 0, 5.0625,0, 0 ], [0, 0, 0.3, 0, 0, 0, 0.3, 0 ], [0, 0, 0, 7, 0, 0, 0, 7.0625]]位置方差变大16→26、18→27、14→25外推后更不确定速度方差基本不变x-vx、y-vy、a-va、h-vh 之间出现交叉项位置的不确定性里掺进了速度的不确定性。本工程落点Tracker.predict()用 for 循环对每条轨迹调track.predict()tracker.py轨迹内部用自己的self.kf调本文的kf.predict同时age 1、time_since_update 1track.py。二、project投影到观测空间方法作用输入输出project把 8 维预测状态投影到 4 维观测空间检测器只能看到 x、y、a、h 这 4 维并叠加观测噪声mean: 预测均值8 维 ndarraycovariance: 预测协方差8×8 ndarrayconfidence: 检测置信度floatNSA 缩放用nsa: NSA 开关bool本工程默认 True(new_mean, new_cov)投影后的均值4 维与协方差4×4project 是内部辅助函数不对外直接调用——update传(mean, covariance, confidence, nsa)调它gating_distance只传(mean, covariance)门控不带 NSA见本文五。NSA本工程相对原版 DeepSORT 卡尔曼的唯一改动原版 DeepSORT 的 project 对所有检测一视同仁本工程加了置信度缩放kalman_filter.py:150-151本工程默认开启std[self._std_weight_position*mean[3],# x 的噪声 h/20self._std_weight_position*mean[3],# y h/201e-1,# a 固定 0.1predict 里是 1e-2self._std_weight_position*mean[3]]# h h/20ifnsa:# ← NSA本工程新增原版 DeepSORT 没有这两行std[(1-confidence)*xforxinstd]covariancenp.diag(std**2)# R diag(std²)效果检测置信度越高 → std 缩得越狠 → R 越小 → 这帧检测在 update 里的话语权越大缩放按平方生效(1−c)²检测置信度 conf缩放系数 (1−c)²R 相对原版路径0.90.01缩小 100 倍几乎全信检测0.8本文例子0.04缩小 25 倍0.50.25缩小 4 倍0.30.49只缩一半低质量检测不给高权重公式new_mean H · mean new_covS H · cov · Hᵀ R字母是什么从哪来H观测矩阵4×8只取前 4 维__init__的_update_matmean8 维预测均值predict 的输出cov8×8 预测协方差predict 的输出R观测噪声4×4 对角阵检测框自身的不确定性函数内现算std (h/20, h/20, 0.1, h/20) →NSA 乘 (1 − conf)→diag(std²)本例conf0.8 diag(0.16, 0.16, 0.0004, 0.16)h目标框高像素mean[3]计算过程实际数字输入predict 输出的那条轨迹mean [108, 50, 1.5, 40, 8, 0, 0, 0] cov [[26, 0, 0, 0, 6, 0, 0, 0 ], [0, 27, 0, 0, 0, 5, 0, 0 ], [0, 0, 0.8001,0, 0, 0, 0.3, 0 ], [0, 0, 0, 25, 0, 0, 0, 7 ], [6, 0, 0, 0, 6.0625, 0, 0, 0 ], [0, 5, 0, 0, 0, 5.0625,0, 0 ], [0, 0, 0.3, 0, 0, 0, 0.3, 0 ], [0, 0, 0, 7, 0, 0, 0, 7.0625]]算 Rh 40NSA 开启、conf 0.8——本工程默认路径std [40/20, 40/20, 0.1, 40/20] [2, 2, 0.1, 2] ← 注意 a 的噪声这里是 1e-1predict 里是 1e-2 std (1 − 0.8) × std [0.4, 0.4, 0.02, 0.4] ← NSA 缩放conf 0.8本工程默认开启 R diag(0.4², 0.4², 0.02², 0.4²) diag(0.16, 0.16, 0.0004, 0.16)对照NSA 关闭原版 DeepSORT 路径时 R diag(4, 4, 0.01, 4)——conf0.8 的检测在本工程下 R 缩小 25 倍update 会几乎全信它。投影H 取前 4 维 取 cov 左上 4×4new_mean H · mean [108, 50, 1.5, 40] new_cov H · cov · Hᵀ R [[260.16, 0, 0, 0 ], [0, 270.16, 0, 0 ], [0, 0, 0.80010.0004, 0 ], [0, 0, 0, 250.16]] [[26.16, 0, 0, 0 ], [0, 27.16, 0, 0 ], [0, 0, 0.8005, 0 ], [0, 0, 0, 25.16 ]]输出new_mean [108, 50, 1.5, 40] ← 4 维 new_covS [[26.16, 0, 0, 0 ], ← 4×4 [0, 27.16, 0, 0 ], [0, 0, 0.8005, 0 ], [0, 0, 0, 25.16 ]]对照NSA 关闭原版 DeepSORT 路径时 S diag(30, 31, 0.8101, 29)——NSA 开启把 S 整体压小后面 update 的修正权重随之变大。三、update修正步方法作用输入输出update修正步用配对成功的检测框修正预测状态——算卡尔曼增益 K加权融合预测和检测输出更准的状态mean: 预测均值8 维 ndarraycovariance: 预测协方差8×8 ndarraymeasurement: 检测框[x, y, a, h]4 维 ndarrayconfidence: 检测置信度float透传给 project 做 NSA 缩放nsa: NSA 开关bool本工程默认 True(mean, covariance)修正后的均值与协方差不确定性变小公式K cov · Hᵀ · S⁻¹ 卡尔曼增益8×4cholesky 求解 innovation measurement − H · mean 残差检测框比预测框偏了多少 mean_new mean K · innovation cov_new cov − K · H · cov 本工程代码的写法cov − K·H·cov与cov − K·S·Kᵀ两种写法代数恒等由 K 的定义推出本工程 kalman_filter.py:186-187 用前者。字母是什么从哪来K卡尔曼增益8×4 矩阵每个状态分量的修正权重公式算出S投影后的协方差4×4project 的输出innovation残差4 维检测框比预测框偏了多少检测框 − 投影预测measurement检测框[x, y, a, h]配对成功的检测Detection.to_xyah() 转换mean / cov8 维预测状态predict 的输出计算过程实际数字输入mean [108, 50, 1.5, 40, 8, 0, 0, 0] ← predict 的输出 cov [[26, 0, 0, 0, 6, 0, 0, 0 ], [0, 27, 0, 0, 0, 5, 0, 0 ], [0, 0, 0.8001,0, 0, 0, 0.3, 0 ], [0, 0, 0, 25, 0, 0, 0, 7 ], [6, 0, 0, 0, 6.0625, 0, 0, 0 ], [0, 5, 0, 0, 0, 5.0625,0, 0 ], [0, 0, 0.3, 0, 0, 0, 0.3, 0 ], [0, 0, 0, 7, 0, 0, 0, 7.0625]] ← predict 的输出 measurement [108.5, 50.5, 1.5, 41] ← 检测框检测器说目标在 108.5project 的输出上一步算好的NSA 开启、conf 0.8H·mean [108, 50, 1.5, 40] S [[26.16, 0, 0, 0 ], [0, 27.16, 0, 0 ], [0, 0, 0.8005, 0 ], [0, 0, 0, 25.16 ]]算 K公式带实际数据K cov · Hᵀ · S⁻¹ [[26, 0, 0, 0 ] [1/26.16, 0, 0, 0 ] [0, 27, 0, 0 ] [0, 1/27.16, 0, 0 ] [0, 0, 0.8001,0 ] · [0, 0, 1/0.8005, 0 ] [0, 0, 0, 25 ] [0, 0, 0, 1/25.16] [6, 0, 0, 0 ] ← 左边 8×4 cov·Hᵀcov 的前 4 列右边 4×4 S⁻¹ [0, 5, 0, 0 ] [0, 0, 0.3, 0 ] [0, 0, 0, 7 ]] [[26/26.16, 0, 0, 0 ] [0, 27/27.16, 0, 0 ] [0, 0, 0.8001/0.8005, 0 ] [0, 0, 0, 25/25.16] [6/26.16, 0, 0, 0 ] [0, 5/27.16, 0, 0 ] [0, 0, 0.3/0.8005, 0 ] [0, 0, 0, 7/25.16 ]] [[0.9939, 0, 0, 0 ] ← 8 行8 个状态分量× 4 列4 个观测分量 [0, 0.9941, 0, 0 ] ← 每行的非零值 该分量的修正权重 [0, 0, 0.9995, 0 ] ← NSA 开启 conf0.8S 被 R 压小权重逼近 1几乎全信检测 [0, 0, 0, 0.9936] ← 对照 NSA 关闭时位置权重只有 0.87 左右 [0.2294, 0, 0, 0 ] ← 速度行的小权重位置残差通过它传导到速度 [0, 0.1841, 0, 0 ] [0, 0, 0.3748, 0 ] [0, 0, 0, 0.2782]]算残差innovation measurement − H·mean [108.5−108, 50.5−50, 1.5−1.5, 41−40] [0.5, 0.5, 0, 1]修正 mean公式带实际数据mean_new mean K · innovation [108, 50, 1.5, 40, 8, 0, 0, 0] [0.9939×0.5, 0.9941×0.5, 0.9995×0, 0.9936×1, 0.2294×0.5, 0.1841×0.5, 0.3748×0, 0.2782×1] [108, 50, 1.5, 40, 8, 0, 0, 0 ] [0.4969, 0.4971, 0, 0.9936, 0.1147, 0.0920, 0, 0.2782] [108.4969, 50.4971, 1.5, 40.9936, 8.1147, 0.0920, 0, 0.2782]修正 cov公式带实际数据cov_new cov − K · H · cov K·H先算8×4 · 4×8 → 8×8每行把自己的权重放回对应的观测列 [[0.9939, 0, 0, 0, 0, 0, 0, 0] [0, 0.9941, 0, 0, 0, 0, 0, 0] [0, 0, 0.9995, 0, 0, 0, 0, 0] [0, 0, 0, 0.9936, 0, 0, 0, 0] [0.2294, 0, 0, 0, 0, 0, 0, 0] [0, 0.1841, 0, 0, 0, 0, 0, 0] [0, 0, 0.3748, 0, 0, 0, 0, 0] [0, 0, 0, 0.2782, 0, 0, 0, 0]] K·H·cov再乘 cov8×8 · 8×8每行 该行的权重 × cov 对应位置那一行的取值 [[0.9939×26, 0, 0, 0, 0.9939×6, 0, 0, 0 ] [0, 0.9941×27, 0, 0, 0, 0.9941×5, 0, 0 ] [0, 0, 0.9995×0.8001,0, 0, 0, 0.9995×0.3, 0 ] [0, 0, 0, 0.9936×25, 0, 0, 0, 0.9936×7] [0.2294×26, 0, 0, 0, 0.2294×6, 0, 0, 0 ] [0, 0.1841×27, 0, 0, 0, 0.1841×5, 0, 0 ] [0, 0, 0.3748×0.8001,0, 0, 0, 0.3748×0.3, 0 ] [0, 0, 0, 0.2782×25, 0, 0, 0, 0.2782×7]] [[25.8410, 0, 0, 0, 5.9633, 0, 0, 0 ] [0, 26.8409, 0, 0, 0, 4.9705, 0, 0 ] [0, 0, 0.7997, 0, 0, 0, 0.2999, 0 ] [0, 0, 0, 24.8410,0, 0, 0, 6.9555] [5.9633, 0, 0, 0, 1.3761, 0, 0, 0 ] [0, 4.9705, 0, 0, 0, 0.9205, 0, 0 ] [0, 0, 0.2999, 0, 0, 0, 0.1124, 0 ] [0, 0, 0, 6.9555, 0, 0, 0, 1.9475]] cov_new cov − 上面的矩阵 [[26−25.8410, 0, 0, 0, 6−5.9633, 0, 0, 0 ] [0, 27−26.8409, 0, 0, 0, 5−4.9705, 0, 0 ] [0, 0, 0.8001−0.7997, 0, 0, 0, 0.3−0.2999, 0 ] [0, 0, 0, 25−24.8410, 0, 0, 0, 7−6.9555] [6−5.9633, 0, 0, 0, 6.0625−1.3761,0, 0, 0 ] [0, 5−4.9705, 0, 0, 0, 5.0625−0.9205,0, 0 ] [0, 0, 0.3−0.2999, 0, 0, 0, 0.3−0.1124, 0 ] [0, 0, 0, 7−6.9555, 0, 0, 0, 7.0625−1.9475]] [[0.1590, 0, 0, 0, 0.0367, 0, 0, 0 ] [0, 0.1591, 0, 0, 0, 0.0295, 0, 0 ] [0, 0, 0.0004, 0, 0, 0, 0.0001, 0 ] [0, 0, 0, 0.1590, 0, 0, 0, 0.0445] [0.0367, 0, 0, 0, 4.6864, 0, 0, 0 ] [0, 0.0295, 0, 0, 0, 4.1420, 0, 0 ] [0, 0, 0.0001, 0, 0, 0, 0.1876, 0 ] [0, 0, 0, 0.0445, 0, 0, 0, 5.1150]]输出mean_new [108.4969, 50.4971, 1.5, 40.9936, 8.1147, 0.0920, 0, 0.2782] cov_new [[0.1590, 0, 0, 0, 0.0367, 0, 0, 0 ], [0, 0.1591, 0, 0, 0, 0.0295, 0, 0 ], [0, 0, 0.0004, 0, 0, 0, 0.0001, 0 ], [0, 0, 0, 0.1590, 0, 0, 0, 0.0445], [0.0367, 0, 0, 0, 4.6864, 0, 0, 0 ], [0, 0.0295, 0, 0, 0, 4.1420, 0, 0 ], [0, 0, 0.0001, 0, 0, 0, 0.1876, 0 ], [0, 0, 0, 0.0445, 0, 0, 0, 5.1150]]修正后的框中心 (108.4969, 50.4971) 几乎贴到检测的 108.5——NSA 开启 conf0.8 时 R 缩小 25 倍位置修正权重 K 达到 0.99NSA 关闭时只有 0.87检测话语权大幅提高方差塌缩得也更狠位置方差 26→0.16NSA 关闭时是 26→3.47高置信度观测几乎吸收全部不确定性。反过来若这帧检测置信度只有 0.3R 只缩一半权重回到接近 NSA 关闭的水平——检测质量决定信检测还是信预测的分配比例这就是 NSA 的意义。这两个值存回轨迹下一帧 predict 从它们出发——predict 变大 / update 变小循环闭环。本工程落点Track.update(detection)内部调self.kf.update(self.mean, self.covariance, detection.to_xyah(), detection.confidence, self._nsa)track.py同时追加特征、hits1、time_since_update 清零、hits≥n_init 时转 Confirmed。四、initiate建档初始化方法作用输入输出initiate建档初始化用建档检测框生成轨迹的初始状态——位置来自检测框速度置 0没观测过速度并给一个初始不确定性速度方差给得大位置方差给得小measurement: 建档检测框[x, y, a, h]4 维 ndarrayDetection.to_xyah() 转换来的中心坐标、宽高比、高(mean, covariance)初始均值8 维 ndarray速度 4 维全 0与初始协方差8×8 对角阵计算过程实际数字输入检测框 tlwh[30, 40, 50, 100]→ 转 xyahmeasurement [55, 90, 0.5, 100] ← x55, y90框中心a0.5宽高比h100框高第 1 步拼初始 mean位置 速度mean_pos [55, 90, 0.5, 100] ← 位置 4 维直接用检测框 mean_vel [0, 0, 0, 0] ← 速度 4 维没观测过全置 0 mean np.r_[mean_pos, mean_vel] ← 拼成 8 维 [55, 90, 0.5, 100, 0, 0, 0, 0]第 2 步构造初始 std8 个分量的噪声标准差h100std [ 2 × (1/20) × 100, ← x2 × h/20 10 2 × (1/20) × 100, ← y10 1e-2, ← a固定 0.01 2 × (1/20) × 100, ← h10 10 × (1/160) × 100, ← vx10 × h/160 6.25 10 × (1/160) × 100, ← vy6.25 1e-5, ← va固定 0.00001 10 × (1/160) × 100] ← vh6.25 [10, 10, 0.01, 10, 6.25, 6.25, 0.00001, 6.25]位置噪声用 2 倍权重、速度噪声用 10 倍权重比 predict 的 1 倍大——刚建档时啥都不确定尤其速度完全没观测过方差给大让 update 阶段能快速修正它。第 3 步拼初始 covariancestd 平方上对角线covariance diag(10², 10², 0.01², 10², 6.25², 6.25², 0.00001², 6.25²) diag(100, 100, 0.0001, 100, 39.0625, 39.0625, ~0, 39.0625)输出mean [55, 90, 0.5, 100, 0, 0, 0, 0] covariance [[100, 0, 0, 0, 0, 0, 0, 0 ], [0, 100, 0, 0, 0, 0, 0, 0 ], [0, 0, 0.0001, 0, 0, 0, 0, 0 ], [0, 0, 0, 100,0, 0, 0, 0 ], [0, 0, 0, 0, 39.0625,0, 0, 0 ], [0, 0, 0, 0, 0, 39.0625,0, 0 ], [0, 0, 0, 0, 0, 0, ~0, 0 ], [0, 0, 0, 0, 0, 0, 0, 39.0625]]本工程落点Tracker._initiate_track对未匹配检测新建 Track 对象Track.__init__内部调self.kf.initiate(detection.to_xyah())track.py返回的 mean/covariance 存进新建的 Track 对象下一帧 predict 从它们出发。五、gating_distance马氏距离门控方法作用输入输出gating_distance算一条轨迹的预测分布与N 个检测框各自的平方马氏距离用于级联匹配的运动门控距离超过卡方阈值的配对判为不可行mean: 这条轨迹的 8 维状态均值covariance: 这条轨迹的 8×8 协方差measurements: Nx4 检测框矩阵每行 x, y, a, honly_position: 只按中心位置算默认 False长度 N 的数组第 i 个元素 这条轨迹与第 i 个检测框的平方马氏距离公式d² dᵀ · S⁻¹ · d d 残差 检测框 − 投影后的预测均值S H·cov·Hᵀ R字母是什么从哪来d残差4 维检测框比预测框偏了多少measurements − H·meanS投影后的协方差4×4project 的输出注意gating 调 project不传 confidence/nsaR 用未缩放值与本文二的 NSA 缩放路径不同d²平方马氏距离标量一个检测框一个公式算出measurementsNx4 检测框矩阵每行 x, y, a, h调用方把 Detection 转 to_xyah() 拼成代码实现kalman_filter.py:223-230不直接求 S⁻¹用 Cholesky 分解代替推导S L·Lᵀ → S⁻¹ (L·Lᵀ)⁻¹ L⁻ᵀ·L⁻¹ d² dᵀ·S⁻¹·d dᵀ·L⁻ᵀ·L⁻¹·d (L⁻¹·d)ᵀ·(L⁻¹·d) ‖L⁻¹·d‖²mean,covarianceself.project(mean,covariance)# 第 1 步投影注意不传 confidence/nsa不带 NSA 缩放见下方说明cholesky_factornp.linalg.cholesky(covariance)# L使 S L·Lᵀdmeasurements-mean# 第 2 步残差Nx4zscipy.linalg.solve_triangular(# 第 3 步解方程 L·z d得 z L⁻¹·dcholesky_factor,d.T,lowerTrue,check_finiteFalse,overwrite_bTrue)squared_mahanp.sum(z*z,axis0)# 第 4 步d² ‖z‖²每个检测框一个# only_positionTrue 时在 cholesky 前把 mean/cov/measurements 都截成前 2 维S 是对角阵时 L diag(√S)z_i d_i/√S_ii于是d² Σ d_i²/S_ii残差平方除以方差再求和——下面的手算就用这个形式。判定阈值模块顶部的 chi2inv95 表卡方分布 0.95 分位数表kalman_filter.py:11-20自由度123456789阈值3.84155.99157.81479.487711.07012.59214.06715.50716.919自由度 参与计算的维数only_positionFalse默认用 4 维x, y, a, h→ 阈值9.4877only_positionTrue只用 2 维x, y→ 阈值 5.9915。d² 小于阈值 ≈ 检测框落在轨迹 95% 的预测范围内。计算过程实际数字输入轨迹 本文一 predict 之后的那个例子两个候选检测框mean [108, 50, 1.5, 40, 8, 0, 0, 0] ← predict 后的状态 cov [[26, 0, 0, 0, 6, 0, 0, 0 ], [0, 27, 0, 0, 0, 5, 0, 0 ], [0, 0, 0.8001,0, 0, 0, 0.3, 0 ], [0, 0, 0, 25, 0, 0, 0, 7 ], [6, 0, 0, 0, 6.0625, 0, 0, 0 ], [0, 5, 0, 0, 0, 5.0625,0, 0 ], [0, 0, 0.3, 0, 0, 0, 0.3, 0 ], [0, 0, 0, 7, 0, 0, 0, 7.0625]] measurements [[108.5, 50.5, 1.5, 41], ← 检测1就在预测位置附近 [130, 60, 1.5, 42]] ← 检测2中心偏了 22 像素第 1 步project 投影到观测空间这里 project不传 confidence/nsa——门控是一条轨迹对 N 个检测逐个算距离发生在配对之前没有单一置信度可乘所以 R 用未缩放值 diag(4, 4, 0.01, 4)本节数字不受 NSA 影响与本文二 NSA 开启路径的 S diag(26.16, 27.16, 0.8005, 25.16) 不同H·mean [108, 50, 1.5, 40] S [[30, 0, 0, 0 ], [0, 31, 0, 0 ], [0, 0, 0.8101,0 ], [0, 0, 0, 29 ]]第 2 步算两个检测框的残差 d 检测框 − H·mean检测1: d [108.5−108, 50.5−50, 1.5−1.5, 41−40] [0.5, 0.5, 0, 1] 检测2: d [130−108, 60−50, 1.5−1.5, 42−40] [22, 10, 0, 2]第 3 步d² Σ 残差² / 方差S 对角线检测1: d² 0.5²/30 0.5²/31 0²/0.8101 1²/29 0.0083 0.0081 0 0.0345 0.0509 检测2: d² 22²/30 10²/31 0²/0.8101 2²/29 16.1333 3.2258 0 0.1379 19.4971第 4 步与阈值 9.4877 比较d² [0.0509, 19.4971] [0.0509 9.4877, 19.4971 9.4877] [进门, 拒绝] ← 检测2 不可能是这条轨迹的输出[0.0509, 19.4971]长度 2 的数组第 i 个元素 这条轨迹与第 i 个检测框的平方马氏距离本例检测1 进门、检测2 被拒。描述链接项目基于 Ultralytics StrongSort 多目标跟踪与改进往期回顾链接数据集数据集汇总软件开发深度学习软件开发汇总
延伸阅读

更多相关文章

2026/10/29 1:58:50

Folia 完整安装部署指南:从零跑通全屏歌词动画

Folia 完整安装部署指南:从零跑通全屏歌词动画 【免费下载链接】folia-major 专注于绚丽的歌词动画效果的本地音乐/navidrome/第三方多平台在线音乐播放器 项目地址: https://gitcode.com/GitHub_Trending/fo/folia-major Folia 全屏歌词动画播放器&#xff…

2026/10/29 6:44:05

Ponytail:前端UI状态快照与协作诊断工具详解

1. 项目概述:从“ponytail”热词切入,我们到底在讨论什么?最近刷技术社区、设计论坛甚至短视频平台,频繁撞见“ponytail”这个词——它既不是马尾辫的直译,也不是某个新晋网红的ID,而是一个正在快速聚拢真实…

2026/10/29 6:44:05

GLM批量API五折入口详解:大模型成本优化实战指南

最近我在优化一个大规模文本处理项目,每天要跑几十万个请求。算力成本一直是老大难,直到我发现GLM API有一个批量五折的通道——同样调用GLM模型,走批量的价格只有实时调用的一半。但这里有个很现实的问题:这个五折入口藏得很深&a…

2026/10/29 6:44:05

Gemini 3在高校科研中的六大核心应用场景

1. 为什么高校教师需要掌握Gemini 3?上周帮同事调试文献分析模型时,发现他还在用传统的关键词检索方式筛选论文。当我演示用Gemini 3直接生成研究现状综述时,他盯着屏幕愣了半天——这个场景让我意识到,AI工具的应用鸿沟正在真实影…

2026/10/29 6:44:05

Gemini 3在高校科研中的六大核心应用场景与效能提升

1. 高校教师Gemini 3应用现状与紧迫性当ChatGPT-4还在教育圈引发热议时,Google DeepMind的Gemini 3已经悄然完成了三代技术迭代。最近走访了国内十余所高校的实验室,发现一个令人担忧的现象:约68%的人文社科教师和43%的理工科教师仍停留在传统…

2026/10/29 6:44:05

多环境切换的上下文管理机制:原理与实现

1. 项目背景:多环境切换为什么让人崩溃去年年中,我接手一套微服务的日常发布和运维工作,环境至少有开发、测试、预生产三套,每套环境又分不同的地域和账号体系。命令行操作一分钟都离不开--envtest --regioncn-north-1 --tokenxxx…

2026/10/29 6:39:04

信贷风控A卡B卡C卡:贷前贷中贷后模型算法策略差异解析

A卡、B卡、C卡这三个词,在信贷风控圈子里几乎是入门级黑话。A卡管贷前审批,B卡管贷中存量客户,C卡管贷后催收,位置划分清楚得像流水线上的三道工序。但真正把三张卡从零做到上线的人会发现,它们之间的差别远不止"…

2026/10/28 14:42:12

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/28 15:28:56

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/28 3:32:29

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/29 0:03:42

学生选课系统DFD图绘制指南:边界划分与分层校验实战

简介:文档以顶层与第一层DFD图为核心,完整刻画学生选课系统的逻辑模型,面向软件工程课程设计、系统分析学习及毕设前期建模人群。顶层图界定系统边界,外部实体包括管理员、教师和学生三类角色;第一层图进一步细化用户登…

2026/10/29 0:03:42

JIRA敏捷落地:Scrum角色权限、Sprint与燃尽图避坑指南

简介:围绕“基于JIRA的敏捷开发项目管理”这一主题,面向产品负责人、Scrum Master及研发测试成员,梳理Scrum角色分工、迭代流程与JIRA工具配置的对应关系,适合初、中级团队导入敏捷管理时参考。压缩包共1个docx文件,大…

2026/10/29 0:03:42

SEMI S8人机工程验收实战:从条款拆解到现场实测的完整指南

简介:面向半导体设备设计、制造与运维工程师及安全合规人员,这份资料聚焦SEMI标准体系下的设备安全规范,重点收录SEMI S8-0308《半导体制造设备人体工程学工程安全指南》。内容围绕设备设计原则、错误与事故预防、人体工程学适配三大主线展开…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑