计算机视觉中的目标跟踪算法详解
立即解锁
发布时间: 2025-08-21 01:23:51 阅读量: 1 订阅数: 7 


OpenCV 3计算机视觉实战指南
### 计算机视觉中的目标跟踪算法详解
#### 1. cv::calcOpticalFlowSF()参数设置
在计算机视觉中,`cv::calcOpticalFlowSF()`函数的长参数形式允许设置多个用于能量最小化的双边滤波器参数、速度场交叉双边滤波器的窗口大小和参数、遮挡检测阈值、上采样联合双边滤波器的窗口大小和参数,以及不规则性图决定何时在更精细金字塔级别重新计算流的阈值。详细调整这些参数是专家的话题,下面是默认的标称值:
| 参数 | 标称值 |
| --- | --- |
| sigma_dist | 4.1 |
| sigma_color | 25.5 |
| postprocess_window | 18 |
| sigma_dist_fix | 55.0 |
| sigma_color_fix | 25.5 |
| occ_thr | 0.35 |
| upscale_averaging_radius | 18 |
| upscale_sigma_dist | 55.0 |
| upscale_sigma_color | 25.5 |
| speed_up_thr | 10 |
#### 2. Mean-Shift和Camshift跟踪算法
##### 2.1 Mean-Shift算法
Mean-Shift算法是一种在数据集密度分布中寻找局部极值的鲁棒方法。对于连续分布,它本质上是对数据密度直方图应用爬山算法;对于离散数据集,问题则相对复杂。该算法具有统计鲁棒性,会忽略远离数据峰值的离群点,只处理局部窗口内的点并移动窗口。其运行步骤如下:
1. 选择搜索窗口:
- 初始位置
- 类型(均匀、多项式、指数或高斯)
- 形状(对称或偏斜,可能旋转、圆形或矩形)
- 大小(衰减或截止的范围)
2. 计算窗口的(可能加权的)质心。
3. 将窗口中心置于质心处。
4. 重复步骤2,直到窗口停止移动。
Mean-Shift算法与核密度估计相关,但它只寻求估计数据分布的梯度。当梯度为0时,达到分布的稳定(可能是局部)峰值。不同的窗口大小会找到不同的峰值,因为“峰值”本质上是一个与尺度相关的概念。
在OpenCV中,`cv::meanShift()`函数用于实现Mean-Shift算法,其输入是表示待分析密度分布的图像。该函数的原型如下:
```cpp
int cv::meanShift( // Return number of iterations to converge
cv::InputArray probImage, // density of locations (CV_8U or CV_32F)
cv::Rect& window, // initial location (and size) of kernel window
cv::TermCriteria criteria // limits location update iterations
);
```
在这个函数中,`probImage`表示可能位置的密度,`window`是核窗口的初始位置和大小,`criteria`设置了Mean-Shift位置更新迭代的最大次数和最小移动量。返回值是收敛前的迭代次数。
Mean-Shift算法可用于跟踪,通过选择特征分布表示对象,在对象生成的特征分布上启动Mean-Shift窗口,并在后续视频帧中计算所选特征分布,从而实现对象的逐帧跟踪。
##### 2.2 Camshift算法
Camshift算法是基于Mean-Shift算法的改进,主要区别在于搜索窗口可以自动调整大小。例如,在跟踪人脸时,当人靠近或远离相机,算法能自动调整窗口大小以适应人脸的变化。实现Camshift算法的函数原型如下:
```cpp
RotatedRect cv::CamShift( // Return final window size and rotation
cv::InputArray probImage, // Density of locations (CV_8U or CV_32F)
cv::Rect& window, // Initial location (and size) of kernel window
cv::TermCriteria criteria // Limits location update iterations
);
```
该函数的三个参数与`cv::meanShift()`函数的参数含义相同。返回值包含新调整大小的矩形框,还包括通过二阶矩计算得到的对象方向。在跟踪应用中,可将上一帧的调整后矩形框作为下一帧的窗口。
需要注意的是,很多人认为Mean-Shift和Camshift算法仅用于基于颜色特征的跟踪,实际上它们可以跟踪`probImage`中表达的任何特征分布,是轻量级、鲁棒且高效的跟踪器。
#### 3. Motion Templates算法
Motion Templates算法由MIT媒体实验室的Bobick和Davis发明,并由相关人员进一步开发,是OpenCV实现的基础。该算法是跟踪一般运动的有效方法,特别适用于手势识别。使用Motion Templates需要对象的轮廓,获取对象轮廓的方法有多种:
- 使用相对静止的相机进行帧间差分,得到对象的移动边缘。
- 采用色度键控,例如以亮绿色为背景,将非亮绿色的部分作为前景。
- 学习背景模型,从中分离出新的前景对象或人物作为轮廓。
- 使用主动轮廓技术,如创建近红外光墙,用近红外敏感相机观察,遮挡物会显示为轮廓。
- 使用热成像仪,将热对象(如人脸)作为前景。
- 使用分割技术(如金字塔分割或Mean-Shift分割)生成轮廓。
假设已经得到良好分割的对象轮廓,随着对象移动,新的轮廓会被捕获并覆盖上当前时间戳,旧的运动轮廓会逐渐变暗,形成运动历史图像(Motion History Image,MHI)。当轮廓的时间戳比当前系统时间戳早超过指定时长时,这些轮廓会被置为0。
OpenCV中实现Motion Templates算法的相关函数如下:
##### 3.1 cv::motempl::updateMotionHistory()
该函数用于构建运动模板,其原型如下:
```cpp
void cv::motempl::updateMotionHistory(
cv::InputArray silhouette, // Nonzero pixels where motion occurs
cv::InputeOutputArray mhi, // Motion history image
double timestamp, // Current time (usually milliseconds)
double duration // Max track duration ('timestamp' units)
);
```
在这个函数中,`silhouette`是表示运动发生位置的单通道字节图像,`mhi`是表示运动模板的单通道浮点图像,`timestamp`是当前系统时间(通常为毫秒计数),`duration`设置了运动历史像素在`mhi`中保留的最长时间。
##### 3.2 cv::motempl::calcMotionGradient()
通过对MHI取梯度可以得到整体运动的指示,但部分梯度可能无效。该函数用于计算有效梯度,其原型如下:
```cpp
void cv::motempl::calcMotionGradient(
cv::InputArray mhi, // Motion history image
cv::OutputArray mask, // Nonzero where valid gradients were found
cv::OutputArray orientation, // Orientation of found gradients
double delta1, // Minimal gradient allowed
double delta2, // Maximal gradient allowed
int apertureSize
```
0
0
复制全文
相关推荐










