您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

deepstream实践Gst-nvtracker插件

时间:2023-01-08 15:50:37  来源:今日头条  作者:程序员修行

nvtracker允许deepstream pipeline使用底层跟踪器库来跟踪检测到的具有持久(可能唯一) ID 的对象。nvtracker支持任何实现 了NVNvDsTracker API 的底层库,其自带的NvMultiObjectTracker 库实现了三种跟踪器:NvDCF、DeepSORT 和 IOU 。nvtracker查询底层库获取输入格式、内存类型和批处理支持相关的功能和要求,基于这些查询,将输入帧缓冲区转换为底层跟踪器库要求的格式。 例如,NvDCF 和 DeepSORT 跟踪器使用 NV12 或 RGBA,而 IOU 不需要视频帧缓冲区。

底层跟踪器库还支持对多个输入流进行批处理。 批处理通常比单独处理每个流更有效,尤其是当底层库基于 GPU 进行加速时。如果底层库支持批处理模式,它通常是插件的默认运行方式; 如果底层库同时支持批处理和单流模式,可以使用 enable-batch-process 配置选项覆盖默认选项。

底层功能还包括支持传递过往的帧数据,过往帧数据包括在过往的帧中生成但尚未报告的对象跟踪数据。例如由于跟踪置信度低,底层跟踪器仅在内部存储过往帧中生成的对象跟踪数据,但后来由于置信度增加而决定报告时,可能会出现这种情况。 如果底层跟踪器检索到过往的帧数据,它将被报告为用户元数据,称为 NvDsPastFrameObjBatch, 可以通过 enable-past-frame 配置选项启用。

nvtracker接受来自上游组件的 NV12 或 RGBA 格式的帧数据,根据底层库所需的格式将输入缓冲区缩放(和/或转换)为跟踪器插件中的缓冲区,并通过配置文件[tracker] 部分中的 tracker-width 和 tracker-height 指定帧分辨率。底层跟踪器库的路径将通过[tracker]部分中的 ll-lib-file 配置选项指定, 要使用的底层库也可能需要自己的配置文件,可以通过 ll-config-file 选项指定。 如果未指定 ll-config-file,则底层跟踪器库可能会继续使用其默认参数值。 NvMultiObjectTracker 库提供的参考底层跟踪器支持不同的跟踪算法:

  • NvDCF:NvDCF 跟踪器是NVIDIA® 开发的判别相干滤波(DCF) 跟踪器,它使用基于相干滤波器的在线判别学习算法来实现视觉对象跟踪功能,同时使用数据关联算法和状态估计器来实现多对象跟踪 .
  • DeepSORT:DeepSORT 跟踪器使用了深度余弦度量学习和 Re-ID 神经网络,是官方 DeepSORT 跟踪器的重新实现。此实现允许用户使用任何 Re-ID 网络,只要支持NVIDIA 的 TensorRT™ 框架即可。
  • IOU Tracker:Intersection-Over-Union (IOU) 跟踪器使用两个连续帧的检测器边界框之间的 IOU 值来计算它们之间的关联,如果未匹配则分配一个新的目标 ID。 该跟踪器会处理来自对象检测器的误报和漏报,然而这被认为是最低限度的对象跟踪器,只能作为基线功能。

tracker 架构

输入输出

输入:

  • Gst Buffer (来自可用源流的批处理帧)
  • NvDsBatchMeta

NvTracker 插件支持的输入视频帧的颜色格式是 NV12 和 RGBA。

  • Gst Buffer(可以作为下一插件输入)
  • NvDsBatchMeta(在NvDsObjectMeta 中添加了跟踪对象坐标、跟踪器置信度和对象 ID)

如果跟踪器算法不生成置信度值,则跟踪器置信度值将被设置为跟踪对象的默认值(即 1.0)。对于 IOU 和 DeepSORT 跟踪器,tracker_confidence 设置为 1.0,因为这些算法不会为跟踪对象生成置信度值;另一方面,NvDCF 跟踪器由于其视觉跟踪能力而为被跟踪对象生成置信度,其值设置在 NvDsObjectMeta结构中的 tracker_confidence 字段中。请注意,NvDsObjectMeta 中有单独的参数用于检测器的置信度和跟踪器的置信度,分别是 confidence 和 tracker_confidence。

下表总结了插件的功能。

特征

描述

release

配置跟踪器宽度/高度

nvtracker把帧缩放到追踪需要的分辨率并发送给底层库

DS 2.0

多流 CPU/GPU 跟踪器

支持跟踪由来自多个源的帧组成的批处理缓冲区

DS 2.0

NV12输入

-

DS 2.0

RGBA输入

-

DS 3.0

配置GPU设备

用户可以选择GPU进行内部缩放/颜色格式转换和跟踪

DS 2.0

运行时动态添加/删除流

支持在运行时跟踪添加的新源,在删除源时清理资源

DS 3.0

支持用户选择底层库

动态加载用户选择的底层库

DS 4.0

支持批处理

支持将帧从多个输入流批量发送到底层库(如果底层库通告拥有该处理功能)

DS 4.0

支持多种缓冲区格式作为底层库的输入

将输入缓冲区转换为底层库要求的格式,每帧最多 4 种格式

DS 4.0

支持报告过往帧数据

支持报告过往帧数据(如果底层库支持该功能)

DS 5.0

支持显示tracking-id

支持启用或禁用跟踪 ID 的显示

DS 5.0

支持基于事件的跟踪 ID 重置

支持根据事件重置跟踪 ID

DS 6.0

用于底层跟踪器库的 NvDsTracker API

可以使用
sources/includes/nvdstracker.h 中定义的 API 来实现底层跟踪器库,部分 API 参考 sources/includes/nvbufsurface.h。API 函数和数据结构的名称以 NvMOT 为前缀,它代表 NVIDIA Multi-Object Tracker。 以下是从底层库的角度来看实现 API 的一般流程:

1.第一个需要的函数是:

NvMOTStatus NvMOT_Query (
    uint16_t customConfigFilePathSize,
    char* pCustomConfigFilePath,
    NvMOTQuery *pQuery
);

插件在开始与库的任何处理会话(即上下文)之前,使用此函数查询底层库的功能和要求。 查询的属性包括输入帧的颜色格式(例如 RGBA 或 NV12)、内存类型(例如 NVIDIA® CUDA® 设备或 CPU 映射的 NVMM)以及对批处理的支持。

插件在初始化阶段执行一次此查询,其结果将应用于与底层库建立的所有上下文。 如果指定了底层库配置文件,则在查询中提供该文件以供库查阅。 查询回复结构 NvMOTQuery 包含以下字段:

  • NvMOTCompute computeConfig:报告库支持的计算目标。该插件目前仅在启动上下文时回显报告的值。
  • uint8_t numTransforms:底层库需要的颜色格式数量。该字段的有效范围是 0 到 NVMOT_MAX_TRANSFORMS。 如果库不需要任何视觉数据,请将其设置为 0。注意: 0 并不意味着将未转换的数据传递给底层库。
  • NvBufSurfaceColorFormat colorFormats[NVMOT_MAX_TRANSFORMS]:底层库需要的颜色格式列表。 只有前 numTransforms 个条目是有效的。
  • NvBufSurfaceMemType memType:转换缓冲区的内存类型。插件分配这种类型的缓冲区来存储颜色和比例转换的帧,并且发送每帧的缓冲区到底层库。目前仅支持以下类型:

dGPU:

NVBUF_MEM_CUDA_PINNED
NVBUF_MEM_CUDA_UNIFIED

Jetson:

NVBUF_MEM_SURFACE_ARRAY
  • bool supportBatchProcessing:如果底层库支持跨多个流的批处理,则为true; 否则为false。
  • bool supportPastFrame:如果底层库支持输出过往帧数据则为true; 否则为false

2. 在查询之后,任何帧到达之前,插件必须通过调用以下函数初始化底层库的上下文:

NvMOTStatus NvMOT_Init (
     NvMOTConfig *pConfigIn,
     NvMOTContextHandle *pContextHandle,
     NvMOTConfigResponse *pConfigResponse
);

上下文句柄在底层库之外是不透明的。 在批处理模式下,插件为所有输入流请求一个上下文。在按流处理模式下,插件对每个输入流进行此调用,以便每个流都有自己的上下文。 此调用包括对上下文的配置请求。底层库处理简介:

  • 仅当请求被接受时才检查配置并创建上下文。 如果配置请求的任何部分被拒绝,则不会创建上下文,并且返回状态必须设置为NvMOTStatus_Error。 pConfigResponse 字段可以选择包含特定配置项的状态。
  • 根据配置预分配资源。注意:在 NvMOTMiscConfig 结构中,目前不支持且未初始化logMsg字段;customConfigFilePath 指针仅在调用期间有效。

3. 初始化上下文后,只要插件从上游接收到数据,它就会将帧数据连同检测到的对象边界框发送到底层库。尽管在每个流处理上下文中批量帧数据可能只包含一帧,它始终把数据当成批量帧数据来处理。 请注意根据跟踪器插件的帧到达时间,批量帧的组合可以是完整批(包含来自每个流的帧)或部分批(仅包含来自部分流的帧)。在任何一种情况下,每个批处理帧都保证从每个流中最多只获取一帧数据。

此处理的函数调用是:

NvMOTStatus NvMOT_Process (
    NvMOTContextHandle contextHandle,
    NvMOTProcessParams *pParams,
    NvMOTTrackedObjBatch *pTrackedObjectsBatch
);
  • pParams 是指向要处理的输入批处理帧的指针。 该结构包含由一个或多个帧组成的列表,每个流最多有一帧,因此每帧具有不同的 streamID。 帧数据的每个条目都包含由一个或多个缓冲区组成的列表,这些缓冲区采用底层库所需的颜色格式和帧对象属性数据列表。大多数库只需要一种颜色格式。
  • pTrackedObjectsBatch 是指向对象属性数据批处理输出的指针。 它预先填充了 numFilled 的值,该值与输入参数中包含的帧数相同。
  • 如果一个帧没有输出对象属性数据,它仍然被计入 numFilled 并用一个空列表条目 (NvMOTTrackedObjList) 表示。 空列表条目具有正确的 streamID设置且numFilled 设置为 0

注意:输出对象属性数据 NvMOTTrackedObj 包含指向检测器对象(在输入中提供)的指针,该对象与被跟踪对象相关联,存储在 associatedObjectIn 中。 只有传入输入对象的那一帧,才必须将此设置为关联的输入对象。例如对于PGIE interval=1的管道:

  • 第0帧:传入NvMOTObjToTrack X,跟踪器为其分配ID 1,输出对象的associatedObjectIn指向X。
  • 第 1 帧:跳过推理,因此没有来自检测器的输入对象与之关联。 跟踪器找到对象 1,输出对象的 associatedObjectIn 指向 NULL。
  • 第2帧:传入NvMOTObjToTrack Y,跟踪器识别为对象1,输出对象1的associatedObjectIn指向Y

4. 根据底层跟踪器的能力,过往的帧可能会生成一些被跟踪的对象数据,但由于置信度低仅存储在跟踪器后台而不会被报告。 如果这些对象数据在后面的帧中置信度变高并准备好报告它们,可以使用以下函数调用从跟踪器插件中检索那些过往帧数据。可以从底层库中检索过往帧数据,并将其作为用户元数据输出到 NvDsBatchMeta 中的 batch_user_meta_list:

NvMOTStatus NvMOT_ProcessPast (
     NvMOTContextHandle contextHandle,
     NvMOTProcessParams *pParams,
     NvDsPastFrameObjBatch *pPastFrameObjBatch
);
  • pParams 是指向要处理的输入批处理帧的指针。需要此结构来检查批处理帧的流 ID 列表。
  • pPastFrameObjBatch 指针指向过往帧生成的批处理输出帧的对象属性数据。数据结构 NvDsPastFrameObjBatch 在 include/nvds_tracker_meta.h 中定义。每个输入流都可能包括一组跟踪数据,对于单个对象,可能有多个过往帧数据。

5. 如果动态删除视频流源,插件会调用以下函数,以便底层跟踪器库也可以将其删除。 请注意,此 API 是可选的并且仅在启用批处理模式时有效,即只有在底层跟踪器库实际实现此 API 时才会被执行。 如果被调用,底层跟踪器库可以释放分配给它的任意视频流源:

void NvMOT_RemoveStreams (
     NvMOTContextHandle contextHandle,
     NvMOTStreamId streamIdMask
);

6. 当所有处理完成后,插件调用此函数来清理上下文并释放其资源:

void NvMOT_DeInit (NvMOTContextHandle contextHandle);

NvMultiObjectTracker:底层跟踪器库

多目标跟踪 (MOT) 是大多数智能视频分析 (IVA) 应用程序的关键模块,在这些应用程序中需要分析对象状态随时间的变化。 给定一组来自单个或多个流上的主GIE (PGIE) 模块检测对象,并定义与跟踪器插件一起使用的 API,底层跟踪器库可以执行实际的多对象跟踪操作,随着时间的推移,仍对相同对象使用相同的的持久ID。

DeepStream SDK(从 v6.0 开始)提供了一个单一的底层跟踪器库NvMultiObjectTracker,NvMultiObjectTracker在一个统一的架构中实现了所有三种底层跟踪算法(IOU、NvDCF 和 DeepSORT),另外它在 CPU 和 GPU 上都实现了批处理模式下的多流、多目标高效跟踪处理。

可组合多目标跟踪器的统一跟踪器架构

不同的多目标跟踪器在基本功能(例如数据关联、目标管理和状态估计)方面共享通用模块,而在其他核心功能(例如,NvDCF 的视觉跟踪和 DeepSORT 的深度关联度量)方面有所不同。NvMultiObjectTracker 底层跟踪器库采用统一架构,通过仅启用特定对象跟踪器所需模块的配置方式来组合实现不同对象跟踪器。例如,IOU 跟踪器需要的模块数量最少,仅包含数据关联和目标管理模块;NvDCF 跟踪器除了需要 IOU 跟踪器中的模块外,还需要基于 DCF 的视觉跟踪模块、状态估计器模块和轨迹管理模块;DeepSORT 跟踪器不需要视觉跟踪模块,但需要一个基于 Re-ID 深度关联度量的数据关联模块。

下表总结了组成每个对象跟踪器的模块,显示了不同对象跟踪器共享的模块及其在组成上的不同之处。通过在配置文件中启用所需的模块,NvMultiObjectTracker在统一的体系结构下,可以组成不同类型的对象追踪器。

对比不同对象跟踪器

NvMultiObjectTracker 库的工作流程和核心模块

底层跟踪器库的输入包括:来自单个或多个流的批处理视频帧和每个视频帧的检测器对象列表。如果检测间隔(即主 GIE interval参数)设置为大于 0,只有对批处理视频帧进行了对象检测推理,给底层跟踪器的输入数据才会包含对象检测数据,对于跳过推理的批处理帧(即未进行推理的批处理帧),输入数据将仅包含视频帧。

注意:

  • 检测器对象是指主GIE中的检测器检测到的对象,它会作为多目标跟踪器模块的输入。
  • 目标指的是对象跟踪器正在跟踪的对象
  • 推理帧是为对象检测执行推理的视频帧。 由于推理间隔可以在主GIE 的设置中配置,并且可以大于零,因此两个连续推理帧的 frameNum 可能不连续。

为了使用给定的输入数据执行多目标跟踪,以下是要实现的基本功能。 在cpu上会部署多线程来优化性能。

  • 对来自新视频帧的检测器对象与同一视频流的现有目标之间实现数据关联
  • 基于数据关联结果的目标管理,包括目标状态更新和目标的创建和终止

根据跟踪器的类型,在数据关联之前可能需要执行一些额外处理。 例如NvDCF 跟踪器将执行基于视觉跟踪器的定位,以便新视频帧的目标定位结果可用于数据关联;DeepSORT 跟踪器将从所有检测器对象 bbox 中提取 Re-ID 特征以进行数据关联。

Data Association

对于数据关联,各种类型的相似性度量用于计算检测器对象与现有目标之间的匹配分数,包括:

  • 位置相似度
  • 边界框大小相似度
  • 视觉外观相似度(特定于 NvDCF 跟踪器)
  • Re-ID 特征相似度(特定于 DeepSORT tracker)

交并比(IOU)被广泛用于度量两个对象/目标之间的相似度,IOU取决于对象之间的大小相似度。较小bbox除以较大bbox获得的比值可以明确作为两对象间的大小相似度。

两对象/目标的关联总分为所有指标的加权和,其权重由 IOU 分数的 matchingScoreWeight4Iou、大小相似度的
matchingScoreWeight4SizeSimilarity 和视觉相似度的 matchingScoreWeight4VisualSimilarity 组成,所有这些权重都可在底层跟踪器配置文件DataAssociator 部分配置。除了这些指标的权重之外,用户还可以通过minMatchingScore4Iou、minMatchingScore4SizeSimilarity 和 minMatchingScore4VisualSimilarity分别为 IOU、大小相似度和视觉相似度配置一个最小阈值。整体匹配分数的最小阈值可以通过 minMatchingScore4Overall 设置。关于匹配算法,用户可以设置 associationMatcherTyp 来使用高效的贪心算法或类匈牙利算法进行最优二分匹配。

在匹配过程中,检测器对象默认与属于同一类的目标相关联/匹配,以最大限度地减少错误匹配。 但是可以通过设置 checkClassMatch: 0 来禁用此默认规则,即关联两对象时不管它们的对象类 ID。 这在使用像 YOLO 这样的检测器时很有用,YOLO可以检测许多类别的对象,随着时间的推移,同一对象可能会出现错误分类。

数据关联模块的输出由三组对象/目标组成:

  • 未匹配检测器对象;
  • 检测器对象和已有目标的匹配对
  • 未匹配目标

未匹配的检测器对象属于主GIE 检测器检测到的对象,但不与任何现有目标相关联,未匹配的检测器对象被认为是需要跟踪的新对象,除非它们被确定为与任何现有目标重复。 如果新检测器对象对任何现有目标的最大 IOU 分数低于 minIouDiff4NewTarget即它不是任何现有目标的副本,则将创建一个新的目标跟踪器来跟踪该对象。

目标管理和错误处理

尽管检测器检测到新对象(即检测器对象),但这有可能是误报。 为了抑制检测中的此类噪声,NvMultiObjectTracker 跟踪器库采用了一种称为延迟激活的技术,在这种技术中,新检测到的对象会被检查一段时间,只有在这段时间内存活下来时才会激活进行长期跟踪。具体来说,每当检测到新对象时,都会创建一个新的跟踪器来跟踪该对象,但目标最初会进入 Tentative 模式,这是一个试用期,其长度由配置文件 TargetManagement 部分下的 probationAge 定义 。 在试用期内,跟踪器输出不会报告给下游,因为目标尚未验证;然而那些未报告的跟踪器输出数据(即过往的帧数据)存储在底层跟踪器中供之后报告使用。

注意:要使底层跟踪器库存储和报告过往帧数据,用户需要在 deepstream-App 配置文件的 [tracker] 部分下设置 enable-past-frame=1 和 enable-batch-process=1 。注意过往帧数据仅支持在批处理模式下使用。

下一帧可能会检测到相同的目标;然而检测器可能会出现假阴性(即漏检),导致与目标的数据关联不成功。 NvMultiObjectTracker 库采用了一种称为阴影跟踪的技术,即使目标未与检测器对象相关联,目标仍会在一段时间内在后台被跟踪。 每当目标在给定时间范围内未与检测器对象相关联时,目标的内部变量 shadowTrackingAge 就会递增。 一旦目标与检测器对象相关联,shadowTrackingAge 将重置为零。

如果目标处于 Tentative 模式并且 shadowTrackingAge 达到配置文件中指定的 earlyTerminationAge,目标追踪将提前终止(称为Early Termination)。如果目标在Tentative模式期间未终止并成功与检测器对象关联,则目标将被激活并进入Active模式,开始向下游报告跟踪器输出,如果启用了过往帧数据,则在Tentative模式期间跟踪的数据也将被报告,因为这些数据在激活前没有报告过。一旦目标被激活(即处于Active模式),如果目标在给定时间范围内未关联(或跟踪器置信度低于阈值),它将进入Inactive模式,其 shadowTrackingAge 将递增,但仍会在后台进行跟踪。但如果 shadowTrackingAge 超过maxShadowTrackingAge,目标追踪将被终止。

下图总结了目标跟踪器的状态转换:

目标追踪状态转换

NvMultiObjectTracker 库可以在一定程度上生成唯一ID。 设置 useUniqueID: 1,将为每个视频流在初始化阶段分配一个 32 位长的随机数,该32位随机数是所有从同一视频流创建的目标ID(uint64_t 类型) 的高 32 位,目标ID的低32位从0开始。随机生成的高32 位数字允许来自特定视频流的目标 ID从可能的 ID 空间中的随机位置递增。 如果禁用(即 useUniqueID: 0,这是默认值),高 32 位和低 32 位将从 0 开始,导致每次运行时目标 ID 从 0 递增。

请注意,目标 ID 的低 32 位的递增是在同一NvMultiObjectTracker 库处理整个视频流过程中完成的。 因此即使禁用唯一 ID 生成,跟踪器 ID 对于同一视频处理工作流也是唯一的。 禁用唯一 ID 生成时,若Stream 1 有三个对象,Stream 2 有两个对象,且这两个流由同一个库实例处理,则目标 ID 将分配为 0 到 4(而不是 Stream 1 的 0 到 2 和Stream 2的0到1)。

preserveStreamUpdateOrder 控制使用单线程还是多线程来更新目标。 如果启用则使用单个线程在每个批处理帧中按照输入流 ID 顺序依次生成新 ID,即流 1 和 2 的对象将分别具有从 0 到 2 和 3 到 4 的 ID。 默认情况下,此选项被禁用,因此目标管理是通过多线程完成的,以实现更好的性能,但不会保留 ID 顺序。

NvMultiObjectTracker 库在初始化期间基于以下条件预分配所有 GPU 内存:

  • 要处理的流数
  • 每个流要跟踪的最大对象数(表示为 maxTargetsPerStream)

因此,除了依赖库(如 cuFFT™、TensorRT™ 等)使用的暂存内存空间,NvMultiObjectTracker 库的 CPU/GPU 内存使用几乎与被跟踪的对象总数成线性比例即(视频流的数量)×(maxTargetsPerStream)。由于预先分配了所有必要的内存,即使对象数量随时间增加,NvMultiObjectTracker 库在长期运行期间也不会出现内存增长。

一旦被跟踪的对象数量达到配置的最大值(即 maxTargetsPerStream),任何新对象都将被丢弃,直到一些现有目标停止追踪。 请注意,被跟踪的对象数量包括在shadow跟踪模式下被跟踪的目标。 因此,NVIDIA 建议用户将 maxTargetsPerStream 设置得足够大,以容纳一帧中可能出现的感兴趣对象的最大数量,以及shadow跟踪模式下可能从过往帧中跟踪到的对象。

底层跟踪器配置文件中 BaseConfig 部分下的 minDetectorConfidence 属性设置了检测器对象被过滤掉的置信度级别。

状态估计

NvMultiObjectTracker 库采用两种类型的状态估计器,它们都基于卡尔曼滤波器 (KF):简单 KF 和常规 KF。 简单KF 定义了 6 个状态,分别是 {x, y, w, h, dx, dy},其中 x 和 y 表示目标 bbox 左上角的坐标,而 w 和 h 分别表示bbox的宽度和高度。 dx 和 dy 表示 x 和 y 状态的速度。常规KF 定义了 8 个状态,它们是 {x, y, w, h, dx, dy, dw, dh},其中 dw 和 dh 是 w 和 h 状态的速度,其余是 与简单KF 相同。两种类型的卡尔曼滤波器一般都采用恒速模型,测量向量定义为 {x, y, w, h}。 此外,当启用DeepSORT 专门使用的useAspectRatio选项时,可以使用 bbox 纵横比 a 及其速度 da 而不是 w 和 dw。如果状态估计器用于一般用例(如在 NvDCF 跟踪器中),{x, y}、{w, h} 和 {dx, dy, dw, dh} 的过程噪声方差由 processNoiseVar4Loc、processNoiseVar4Size 和 processNoiseVar4Vel 分别配置。

启用视觉跟踪器模块时(如在 NvDCF 跟踪器中),从状态估计器的角度来看有两种不同的测量:(1)来自 主GIE 检测器的 bbox 和(2)来自跟踪器定位的 bbox,这是因为 NvDCF 跟踪器模块能够使用自己学习的过滤器来定位目标。这两种不同类型测量的测量噪声方差可以通过
measurementNoiseVar4Detector 和 measurementNoiseVar4Tracker 配置,这些参数可根据检测器和跟踪器的特性进行调整或优化,以实现更好的测量精度。

DeepSORT 跟踪器中状态估计器的使用与上述通用用例略有不同,因为它基本上是一个常规 KF,但依据原始论文后的各个实现都有一些差异:

  • 使用纵横比 a 和高度 h(而不是 w 和 h)来估计 bbox 大小
  • 过程和测量噪声与边界框高度成正比(而不是常数值)

为了允许这些差异,NvMultiObjectTracker 库中的状态估计器模块有一组额外的配置参数:

  • useAspectRatio 启用 a(而不是 w)
  • noiseWeightVar4Loc 和 noiseWeightVar4Vel 分别作为测量和速度噪声的比例系数

请注意,如果设置了这两个参数,则通用用例的固定过程噪声和测量噪声参数将被忽略。

基于运动的目标重关联

在 DeepStream SDK 6.0 中,引入了一个实验性的特性,称为基于运动的目标重关联,这是为了解决对象以渐进式经历部分遮挡到完全遮挡的情况下发生的常见问题。在运行过程中,主GIE 模块中的检测器可能仅捕获部分对象(由于部分可见性),从而导致追踪目标的 bbox 大小不正确、居中不正确。这可能会导致目标状态估计出现较大误差,进而导致目标状态预测出现重大错误。 如果发生这种情况,当对象从部分或完全遮挡中恢复时,很可能由于大小和位置预测错误导致跟踪器无法与再次出现的对象相关联,从而导致跟踪失败和 ID 切换。 这种重新关联问题通常可以作为后处理来处理,然而对于实时分析应用程序,通常期望将其作为实时多对象跟踪的一部分进行无缝处理。

这种新引入的目标重新关联技术利用 NvMultiObjectTracker 库中的延迟激活和阴影跟踪功能,通过以下步骤实现无缝实时目标重关联:

轨迹预测:每当一个已有的目标长时间(同probationAge)没有与检测bbox匹配(关联),就认为目标丢失了。 当视觉跟踪器模块在shadow跟踪模式下跟踪目标时,使用一些最近匹配的轨迹点(其长度由
prepLength4TrajectoryProjection 设置)生成一段预测轨迹(长度由 trajectoryProjectionLength 配置)并一直存储在内部 DB,直到它再次与检测 bbox 匹配或与另一个目标重关联。

目标 ID 获取:当一个新目标被实例化时,它将在多帧(即 probationAge)检查中验证是否有效并且只有在经过验证(即后期激活)时才分配目标 ID,之后开始报告目标状态。 在获取目标 ID 期间,检查新目标是否与存储上述轨迹预测的内部 DB 中现有目标的预测轨迹相匹配。 如果匹配,则意味着新目标实际上是过去消失的现有目标的重新出现。 然后将新目标与现有目标相关联,并将其 轨迹也融合到其中。 否则将分配一个新的目标 ID。

轨迹匹配:在上一步的轨迹匹配过程中,根据可行的时间窗口从DB中查询出有效的候选轨迹。 之后使用类似动态时间规整 (DTW) 的算法计算轨迹相似度,该算法基于轨迹平均 IOU 以及各种标准,包括最小平均 IOU 分数(minTrackletMatchingScore)、最大运动角度差 (maxAngle4TrackletMatching)、最小速度相似度(
minSpeedSimilarity4TrackletMatching)和最小 bbox 大小相似度(minBboxSizeSimilarity4TrackletMatching)。 为了及时限制搜索空间,可以通过 maxTrackletMatchingTimeSearchRange 配置帧中的最大时间间隔。

轨迹融合:一旦两个轨迹关联起来,它们就会根据与检测器的匹配状态和每个点的置信度融合生成一个平滑的轨迹。

下面是添加到轨迹管理模块并启用此功能的示例配置:

TrajectoryManagement:
  useUniqueID: 1   # Use 64-bit long Unique ID when assignining tracker ID. Default is [true]
  enableReAssoc: 1    # Enable Re-Assoc

  # [Re-Assoc: Motion-based]
  minTrajectoryLength4Projection: 20  # min trajectory length required to make projected trajectory
  prepLength4TrajectoryProjection: 10 # the length of the trajectory during which the state estimator is updated to make projections
  trajectoryProjectionLength: 90      # the length of the projected trajectory

  # [Re-Assoc: Trajectory Similarity]
  minTrackletMatchingScore: 0.5       # min tracklet similarity score for matching in terms of average IOU between tracklets
  maxAngle4TrackletMatching: 30       # max angle difference for tracklet matching [degree]
  minSpeedSimilarity4TrackletMatching: 0.2    # min speed similarity for tracklet matching
  minBboxSizeSimilarity4TrackletMatching: 0.6 # min bbox size similarity for tracklet matching
  maxTrackletMatchingTimeSearchRange: 20      # the search space in time for max tracklet similarity

请注意,基于运动的目标重关联只有在启用状态估计器时才能有效,否则将无法进行正确的轨迹预测。

边界框裁剪

另一个小的实验性特征是边界框裁剪。 如果目标在相机的视野 (FOV) 内完全可见,但开始超出 FOV,则目标将部分可见,边界框(即 bbox)可能仅捕获目标的一部分 (即被 FOV 裁剪)直到它完全退出场景。 如果预计 bbox 的大小在视频帧的边界周围变化不大,则可以使用目标完全可见时估计的 bbox 大小来估计超出 FOV 限制的完整 bbox。 可以在底层配置文件中的 TargetManagement 模块下设置 enableBboxUnClipping: 1 来启用此功能。

配置文件举例详解

在deepstream-app配置文件中调用Gst-nvtracker

[tracker]
## 是否启动此追踪器
enable=1
## 对于NvDCF, 追踪器长度和宽度必须是32的倍数
## 追踪器处理的图像宽度
tracker-width=640
## 追踪器处理的图像长度
tracker-height=384
## 底层库动态库路径
ll-lib-file=/opt/nvidia/deepstream/deepstream-5.1/lib/libnvds_nvdcf.so
## 底层库配置文件,nvtracker 自带的底层库NvDCF和IOU需要设置配置文件
ll-config-file=tracker_config.yml
# ll-config-file=iou_config.txt
## gpu id
gpu-id=0
#enable-batch-process and enable-past-frame applicable to NvDCF only
## 启用/禁用批处理,只有底层库支持批处理此配置才生效。
## nvtracker 自带的底层库NvDCF支持批处理
enable-batch-process=1
## 启用/禁用过往帧数据,只有底层库支持报告过往帧数据此配置才生效。
## nvtracker 自带的底层库NvDCF支持报告过往帧数据
enable-past-frame=0
## 显示追踪id
display-tracking-id=1

本文介绍了如何配置deepstream Gst-nvtracker插件,相信了解这些后,可以轻松配置deepstream-app,调用Gst-nvtracker进行对象追踪。

参考:
https://docs.nvidia.com/metropolis/deepstream/dev-guide/text/DS_plugin_gst-nvtracker.html



Tags:deepstream   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
nvtracker允许deepstream pipeline使用底层跟踪器库来跟踪检测到的具有持久(可能唯一) ID 的对象。nvtracker支持任何实现 了NVNvDsTracker API 的底层库,其自带的NvMultiObjec...【详细内容】
2023-01-08  Tags: deepstream  点击:(0)  评论:(0)  加入收藏
▌简易百科推荐
介绍本文主要介绍一种通过windbg分析内存泄漏的方法,方法也适用linux。这个内存泄漏问题比较经典,我个人认为是自己这么多年bug定位中一个非常好的bug,并且在分析的过程中,也有...【详细内容】
2023-01-09  睡在床板下    Tags:内存泄漏   点击:(1)  评论:(0)  加入收藏
让我们深入探讨 DevOps 和 DevSecOps 管道中密码密钥管理的各个方面。 当今的数字业务有望以闪电般的速度创新、执行和发布产品。自动化工具的广泛采用,加上 DevOps 和DevSec...【详细内容】
2023-01-09  qaseven     Tags:软件开发   点击:(1)  评论:(0)  加入收藏
nvtracker允许deepstream pipeline使用底层跟踪器库来跟踪检测到的具有持久(可能唯一) ID 的对象。nvtracker支持任何实现 了NVNvDsTracker API 的底层库,其自带的NvMultiObjec...【详细内容】
2023-01-08  程序员修行  今日头条  Tags:deepstream   点击:(0)  评论:(0)  加入收藏
WebAssembly (WASM) 在过去几年一直是一个流行词。 这是一项引起广泛关注但在实践中应用较少的技术。 我一直很好奇它的现状,所以我调查并总结了我的发现。 其中一些可能会让...【详细内容】
2023-01-07  启辰8  今日头条  Tags: WebAssembly   点击:(2)  评论:(0)  加入收藏
前言项目是基于swoole开发,框架也是公司内自己开发的框架,并没有用外界热门的swoole框架,swoole是4.0.0版本。项目需要执行大量的自动任务,框架是通过swoole的sendMessage方法将...【详细内容】
2022-12-29  博读代码  51CTO  Tags:后端   点击:(10)  评论:(0)  加入收藏
现在的各种开源项目中使用 Vue 的越来越多了,作为一个后端程序员不会点 Vue 也都玩不转了。所以抽空学习了一下 Vue 的简单用法,整理成笔记,方便有需要的同学一起学习。Vue 是...【详细内容】
2022-12-28  猿来猿往  今日头条  Tags:VUE   点击:(15)  评论:(0)  加入收藏
C语言几乎唯一的缺点就是,需要手动管理内存。抛开这点之外,我觉得其他语言都不如C语言[呲牙]所以,虽然自动内存管理比较复杂,但我还是给scf编译器框架加了静态的GC算法。在编程...【详细内容】
2022-12-27  底层技术栈  今日头条  Tags:编译器   点击:(14)  评论:(0)  加入收藏
编译器在经过词法分析、语法分析之后,就把源代码变成了抽象语法树(AST)。接下来,编译器的任务就是把AST变成机器码。AST,是一个表示代码逻辑的树形结构,它是不能直接顺序遍历的,而...【详细内容】
2022-12-26  底层技术栈  今日头条  Tags:编译   点击:(13)  评论:(0)  加入收藏
大家在平时的开发过程中估计不会经常碰到需要主动取消一个 Fetch 请求的需求,所以一部分同学可能对这一块知识不是很了解。没有关系,看完这篇文章你就能够掌握关于如何终止一...【详细内容】
2022-12-25  嘻呱互联   网易号  Tags: Promise   点击:(12)  评论:(0)  加入收藏
很早前就想写一篇关于 eBPF 的文章,但是迟迟没有动手,这两天有点时间,所以就来写一篇。这文章主要还是简单的介绍 eBPF 是用来干什么的,并通过几个示例来介绍是怎么玩的。这个技...【详细内容】
2022-12-24   IT架构师联盟     Tags:eBPF   点击:(4)  评论:(0)  加入收藏
相关文章
    无相关信息
站内最新
站内热门
站内头条