经典相关滤波跟踪器(上):MOSSE原理、CSK与KCF、HOG特征融合

各位同学,今天我们来聊聊相关滤波跟踪。说实话,这个方向我研究了很久。记得2015年我刚入行时,公司接了个无人机跟踪项目,目标动不动就丢。后来我把KCF调参调了一周,终于稳住了。嗯,从那以后我就对相关滤波有了感情。

相关滤波的核心思想其实很简单:在图像里找一个滤波器,让它对目标区域的响应最大,对背景的响应最小。你想想看,这不就是我们要的跟踪吗?

核心公式:相关滤波跟踪 = 频域快速计算 + 在线更新模板

2.1 MOSSE:一切的开端

MOSSE(Minimum Output Sum of Squared Error)是2010年CVPR上的工作。说实话,它真的很朴素,但效果在当时是惊艳的。

MOSSE的核心思想:

  • 在频域中学习一个滤波器,使得目标区域的响应是高斯形状
  • 使用最小二乘法求解,闭式解一步到位
  • 在线更新:每帧用学习率融合新模板

我给大家看下MOSSE的求解过程。假设我们有一组训练样本 \( f_i \) 和期望输出 \( g_i \),我们要找的滤波器 \( h \) 满足:

# MOSSE的频域求解(伪代码)
# 初始化
H = np.zeros_like(F)  # 滤波器频域表示

# 对每一帧
F = fft2(image_patch)  # 目标区域做FFT
G = fft2(gaussian_label)  # 高斯标签做FFT

# 更新分子和分母
A_i = conj(G) * F        # 分子
B_i = conj(F) * F        # 分母

# 在线更新(学习率eta=0.125)
A = eta * A_i + (1-eta) * A
B = eta * B_i + (1-eta) * B

# 当前帧的滤波器
H = A / (B + epsilon)

# 检测:相关响应图
response = ifft2(H * conj(fft2(search_patch)))

这里有个坑,我当年踩过:epsilon一定要加。不加的话,分母为0直接崩掉。我建议epsilon取1e-5到1e-8之间。

个人经验:MOSSE的更新率eta很关键。eta太大(>0.2)容易漂移,太小(<0.05)跟不上目标变化。我一般用0.125,这是论文推荐值,实际效果也确实不错。

2.2 CSK:引入核技巧

MOSSE有个问题:它只用了原始像素特征,表达能力有限。CSK(Circulant Structure of Tracking-by-detection with Kernels)在2012年解决了这个问题。

CSK的贡献主要有两点:

  • 循环矩阵:利用循环移位生成大量训练样本,不用手动标注
  • 核技巧:把特征映射到高维空间,提升判别能力

为什么循环矩阵这么重要?说白了,循环矩阵在频域可以对角化。这意味着原本O(n³)的矩阵求逆,变成了O(n log n)的FFT操作。你想想看,这速度提升有多大!

CSK的求解公式变成了:

# CSK的核相关滤波求解
# 核矩阵K是循环矩阵
# 在频域中求解对偶系数alpha

# 训练
k = kernel_correlation(x, x)  # 自相关
alpha = fft2(y) / (fft2(k) + lambda_reg)

# 检测
k_z = kernel_correlation(z, x)  # 互相关
response = ifft2(fft2(k_z) * alpha)

注意:CSK用的核是线性核或高斯核。高斯核有个超参数sigma,我建议设为目标尺寸的0.1倍左右。太小了过拟合,太大了欠拟合。

2.3 KCF:把HOG加进来

CSK虽然引入了核技巧,但特征还是原始像素。KCF(Kernelized Correlation Filters)在2014年做了两件大事:

  • 多通道特征融合:把HOG特征引入相关滤波框架
  • 核相关滤波的完整推导:给出了多通道情况下的闭式解

KCF的HOG特征融合,说白了就是把每个cell的梯度直方图当成一个通道。假设HOG是31维的,那我们就有了31个通道的特征图。

多通道的核相关计算:

# KCF多通道高斯核计算
def gaussian_correlation(x1, x2, sigma):
    # x1, x2: 多通道特征 [C, H, W]
    # 计算所有通道的平方和
    x1_sq = np.sum(x1**2, axis=0)
    x2_sq = np.sum(x2**2, axis=0)
    
    # 互相关(频域计算)
    x1_f = fft2(x1)  # [C, H, W/2+1]
    x2_f = fft2(x2)
    
    # 逐通道相乘后求和
    cross = np.real(ifft2(np.sum(x1_f * np.conj(x2_f), axis=0)))
    
    # 高斯核
    c = x1_sq + x2_sq - 2 * cross
    k = np.exp(-1 / sigma**2 * np.clip(c, 0, None))
    return k

我个人觉得,KCF是相关滤波跟踪的里程碑。为什么?因为它把特征工程和频域优化完美结合了。HOG特征对光照变化和形变有很好的鲁棒性,而频域计算保证了实时性。

KCF vs MOSSE vs CSK 对比

方法 特征 核技巧 速度(FPS) 精度(OTB-50)
MOSSE 原始像素 无 ~600 ~0.40
CSK 原始像素 高斯核 ~300 ~0.52
KCF HOG(31维) 高斯核 ~170 ~0.73

看到没?KCF虽然速度比MOSSE慢了点,但精度提升了近一倍。这就是特征工程的威力。

2.4 HOG特征融合的细节

HOG特征怎么跟相关滤波结合?这里有几个关键点:

  • 特征提取:对目标区域提取HOG,得到31维特征图
  • 余弦窗:对特征图加余弦窗,抑制边界效应
  • 频域计算:所有操作都在频域完成,保持实时性
  • 尺度处理:KCF本身不支持尺度变化,需要额外处理

我曾经在项目中遇到一个问题:HOG的cell size怎么选?太小了特征维数爆炸,太大了空间信息丢失。我建议cell size取4×4或8×8,具体看目标大小。目标小就用小cell,目标大就用大cell。

避坑指南:HOG特征提取后,一定要做归一化。我见过有人直接拿原始HOG值做相关滤波,结果响应图全是噪声。归一化方法我推荐L2范数归一化,简单有效。

2.5 本章知识体系

下面我用一张图来总结本章的核心逻辑:

相关滤波跟踪器演进路线 MOSSE (2010) 原始像素特征 最小二乘求解 频域快速计算 +核技巧 CSK (2012) 循环矩阵采样 高斯核映射 对偶空间求解 +HOG特征 KCF (2014) 多通道HOG(31维) 多通道核相关 实时性+高精度 核心差异对比 特性 MOSSE CSK KCF 特征维度 1通道 1通道 31通道 样本生成 仿射变换 循环移位 循环移位 更新方式 分子分母 对偶系数 对偶系数 边界效应 无处理 余弦窗 余弦窗

从这张图可以看得很清楚:MOSSE是地基,CSK加了核技巧这层楼,KCF又加了HOG特征这层楼。每一层都在前一层的基础上做了改进。

好了,本章的内容就到这里。相关滤波跟踪器的核心思想其实不复杂,但细节很多。我建议大家动手实现一遍MOSSE和KCF,代码量不大,但能帮你真正理解频域跟踪的精髓。