# FeatureTracker

FeatureTracker节点检测帧上的关键点（特征），并在下一帧上跟踪它们。有效的特征通过Harris分数或Shi-Tomasi获得。 默认目标特征数为320，默认最大特征数为480。

## 如何放置

#### Python

```python
with dai.Pipeline() as pipeline:
    featureTracker = pipeline.create(dai.node.FeatureTracker)
```

#### C++

```cpp
dai::Pipeline pipeline;
auto featureTracker = pipeline.create<dai::node::FeatureTracker>();
```

## 输入和输出

## 使用

#### Python

```python
with dai.Pipeline() as pipeline:
    featureTracker = pipeline.create(dai.node.FeatureTracker)

    # 将shaves数量和memory slices数量设置为最大值
    featureTracker.setHardwareResources(2, 2)
    # 指定等待配置消息到达inputConfig输入
    featureTracker.setWaitForConfigInput(True)

    # 你必须将特征跟踪器与图像帧源（单色/彩色相机或xlinkIn节点）结合使用
```

#### C++

```cpp
dai::Pipeline pipeline;
auto featureTracker = pipeline.create<dai::node::FeatureTracker>();

// 将shaves数量和memory slices数量设置为最大值
featureTracker->setHardwareResources(2, 2);
// 指定等待配置消息到达inputConfig输入
featureTracker->setWaitForConfigInput(true);

// 你必须将特征跟踪器与图像帧源（单色/彩色相机或xlinkIn节点）结合使用
```

## 功能示例

 * [特征跟踪器](https://docs.luxonis.com/software-v3/depthai/examples/feature_tracker/feature_tracker.md)

## 工作原理

### 图像单元格

为使特征均匀分布在图像上，图像被划分为多个单元格，并分别进行处理。每个单元格的目标特征数 = 帧目标特征数 / 单元格数量。 单元格的数量可以在水平和垂直方向上配置。默认单元格数为4（水平）×4（垂直）。这意味着每个单元格的默认目标特征数为： 320 / (4
* 4) = 20。注意，如果已跟踪的点的新坐标位于已满的单元格中，该点不会被移除，因此特征数可能超过此限制。

### 初始Harris阈值

此阈值控制检测到特征的最小强度。将该值设为0可启用自动阈值，用于适应不同场景。如果纹理较多，需要增加此值以限制检测到的点的数量。每个单元格有自己的阈值。

### 新特征的进入条件

新特征的进入条件为：

 * 特征之间不能太近（最小距离标准——默认值为50，测量单位为像素的平方欧几里得距离），
 * 特征的Harris分数足够高，
 * 单元格中有足够的空间容纳该特征（未达到目标特征数）。

### 已跟踪特征的Harris阈值

一旦检测到特征并开始跟踪，我们需要在每帧上更新其Harris分数。 此阈值定义了需要移除此类特征的点。 目标是尽可能长时间地跟踪点，因此进入点的条件高于已跟踪点的条件。这就是为什么此值通常小于检测阈值。

### 特征维护

算法需要决定在后续帧中移除哪些特征、保留哪些特征。注意，已跟踪特征优先于新特征。 它会移除具有以下特点的特征：

 * 跟踪误差过大（未被正确跟踪），
 * Harris分数过小（可配置阈值）。

### 新位置计算

前一帧特征在当前帧上的位置可以通过两种方式计算：

 1. 使用金字塔Lucas-Kanade光流方法。
 2. 使用密集运动估计硬件块（块匹配器）。

## 参考

### dai::node::FeatureTracker

Kind: class

FeatureTracker node. Performs feature tracking and reidentification using motion estimation between 2 consecutive frames.

#### std::shared_ptr< FeatureTrackerConfig > initialConfig

Kind: variable

Initial config to use for feature tracking.

#### Input inputConfig

Kind: variable

Input FeatureTrackerConfig message with ability to modify parameters in runtime. Default queue is non-blocking with size 4.

#### Input inputImage

Kind: variable

Input message with frame data on which feature tracking is performed. Default queue is non-blocking with size 4.

#### Output outputFeatures

Kind: variable

Outputs TrackedFeatures message that carries tracked features results.

#### Output passthroughInputImage

Kind: variable

Passthrough message on which the calculation was performed. Suitable for when input queue is set to non-blocking behavior.

#### FeatureTracker()

Kind: function

#### FeatureTracker(std::unique_ptr< Properties > props)

Kind: function

#### void setHardwareResources(int numShaves, int numMemorySlices)

Kind: function

Specify allocated hardware resources for feature tracking. 2 shaves/memory slices are required for optical flow, 1 for corner
detection only. parameters: numShaves: Number of shaves. Maximum 2.; numMemorySlices: Number of memory slices. Maximum 2.

#### DeviceNodeCRTP()

Kind: function

#### DeviceNodeCRTP(const std::shared_ptr< Device > & device)

Kind: function

#### DeviceNodeCRTP(std::unique_ptr< Properties > props)

Kind: function

#### DeviceNodeCRTP(std::unique_ptr< Properties > props, bool confMode)

Kind: function

#### DeviceNodeCRTP(const std::shared_ptr< Device > & device, std::unique_ptr< Properties > props, bool confMode)

Kind: function

### 需要帮助？

请前往 [OAKChina 官网](https://www.oakchina.cn/) 获取技术支持或解答您的任何疑问。
