视觉跟踪技术:从原理到OpenVX实现
立即解锁
发布时间: 2025-09-01 02:02:12 阅读量: 5 订阅数: 25 AIGC 

### 视觉跟踪技术:从原理到OpenVX实现
#### 1. 光流方程与基本假设
在光流计算中,有一个重要的方程:$I_xV_x + I_yV_y = -I_t$ ,用向量表示为 $\nabla I^T \cdot \vec{V} = -I_t$ 。其中,$V_x$ 和 $V_y$ 是速度(即 $I(x,y,t)$ 的光流)的 $x$ 和 $y$ 分量,$I_x$、$I_y$ 和 $I_t$ 分别是强度关于空间和时间坐标的导数。这个方程表明,经过时间 $t$ 后,强度的变化取决于运动方向和该方向上的强度梯度。然而,此方程由于只有一个方程却有两个未知数,无法直接求解。
这里有两个假设,目前只使用了其中一个,另一个假设是相邻像素会一起移动,也就是说,需要多个像素才能构成一个可跟踪的对象。但具体选择哪些像素是个难题,这与光流中的孔径问题类似。
#### 2. 孔径问题
孔径问题可以通过一个例子来说明。在对栏杆的特写图像中,从一个小孔观察,两张相邻图像中栏杆有位移,但位移的角度有多种可能,像素的运动方向是模糊的,因为基于视觉输入无法推断出与线条平行的运动分量。孔径问题是一个比单个像素运动检测更高级的问题,它提醒我们,基于特写的像素化视图计算结果需要谨慎对待,仅根据给定信息可能无法确定真实的运动情况。
#### 3. 用于稀疏特征集的Lucas - Kanade算法
光流可以针对图像的所有像素位置进行计算,但大多数情况下,我们只关注少数感兴趣的点,即稀疏特征集。计算的点越少,所需资源可能越少,或者可以利用这些资源获得更准确的结果。不过,对于具有大规模并行计算能力的实现,减少计算点数量可能不会带来明显收益。
Lucas - Kanade算法专为稀疏特征集设计,它利用了相邻像素具有相同运动的假设。对于所选点的紧邻像素,在大多数情况下可以认为这些像素属于同一对象。以最小的邻域窗口(3×3)为例,会得到九个方程、两个未知数和一些误差。使用最小二乘法线性回归来估计未知数,得到方程:
$\vec{V} =
\begin{bmatrix}
\sum_{i} I_{xi}^2 & \sum_{i} I_{xi}I_{yi} \\
\sum_{i} I_{xi}I_{yi} & \sum_{i} I_{yi}^2
\end{bmatrix}^{-1}
\begin{bmatrix}
-\sum_{i} I_{xi}I_{ti} \\
-\sum_{i} I_{yi}I_{ti}
\end{bmatrix}$
实际上,这个方程可以扩展到任意大小的窗口,但3×3窗口通常就足够了,且计算量远小于更大的窗口(如5×5,包含25个像素)。最小二乘法解对窗口内的所有像素赋予相同的权重,更好的做法是对窗口中心赋予更多权重,常用高斯加权。上述方程看似可以通过简单的求和、矩阵求逆和乘法一步解决,但实际并非如此,通常会使用高斯消元法、Givens变换、主元法等方法来求解线性回归,而不直接对矩阵求逆,因为矩阵不一定可逆。当图像存在均匀区域(变化很可能是噪声)时,线性方法可能无法得到合理结果,因此通常使用迭代方法,并且在设计迭代时要包含对不合理解的防护和处理非线性情况的鲁棒性。不过,Lucas - Kanade方法一次只考虑很小的像素区域,如果这些像素都是均匀的或者有较大的位移到图像的不同区域,该方法就会失效,但它是其他方法的基础。
#### 4. 使用图像金字塔的Bouguet实现
OpenVX中使用的Lucas - Kanade方法基于Bouguet的论文,该方法使用图像金字塔,即同时处理图像的多个不同尺度的副本。在这个实现中,强度的偏导数 $I_x$ 和 $I_y$ 通过对输入图像使用Scharr梯度获得,而不是具有简单高斯加权的Sobel滤波器。时间变化 $I_t$ 则通过减去相邻帧中对应的像素得到。
仅9个像素的窗口(OpenVX规定实现必须支持此窗口大小)可能不足以适应位置的大变化,这就是金字塔发挥作用的地方。在最小尺度下,9像素窗口足以检测较大的位移,但小运动可能会被隐藏;在最大尺度下,可以检测到小运动,但无法测量大位移。这种金字塔方法在一定程度上有助于解决孔径问题,特别是当在所有尺度上都能检测到运动时。
算法的一般步骤如下:
1. 使用基于牛顿 - 拉夫逊技术的迭代Lucas - Kanade方法,以位移向量的初始猜测为零,在最低分辨率下求解感兴趣点的光流。
2. 将该计算结果作为下一个更高分辨率金字塔迭代的初始猜测,依次进行,直到达到金字塔的第0级,即原始图像。
这样,在最高分辨率下可以处理大运动,克服孔径问题,但需要在金字塔深度和可可靠检测的最大位移之间进行权衡。要注意非常深的金字塔可能会导致图像出现混叠,从而使运动估计过大。
#### 5. OpenVX光流API
OpenVX提供了用于光流计算的API,节点函数的声明如下:
```c
vx_node vxOpticalFlowPyrLKNode(
vx_graph graph,
vx_pyramid old_images,
vx_pyramid new_images,
vx_array old_points,
vx_array new_points_estimates,
vx_array new_points,
vx_enum termination,
vx_scalar epsilon,
vx_scalar num_iterations,
vx_scalar use_initial_estimate,
vx_size window_dimension);
```
这个函数有很多参数,下面对主要参数进行解释:
| 参数 | 说明 |
| ---- | ---- |
| `old_images` 和 `new_images` | 指灰度金字塔(`VX_DF_IMAGE_U8`) |
| `old_points` | 输入的旧点 |
| `new_points` | 输出的新点 |
| `new_points_estimates` | 可提供的新点估计值,如果已知相机平移或能根据物体动量预测运动,可提供该参数,是否使用取决于 `use_initial_estimate` 参数的值,该参数是一个布尔值,可在运行时更改 |
| `termination`、`epsilon` 和 `num_iterations` | 决定Lucas - Kanade迭代操作的停止条件。在图创建时,`termination` 可以选择 `VX_TERM_CRITERIA_ITERATIONS`、`VX_TERM_CRITERIA_EPSILON` 或 `VX_TERM_CRITERIA_BOTH`,实际值可在运行时通过标量提供。建议使用 `VX_TERM_
0
0
复制全文
相关推荐









