You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于YOLOv4与DeepSORT的两段视频目标跟踪结果融合问询

基于YOLOv4+DeepSORT实现跨视频跟踪连续性方案

一、先解决track.feature为空的问题

DeepSORT的目标特征由ReID模型提取,仅当轨迹被确认(track.is_confirmed()返回True)且有新检测结果匹配时,才会更新track.feature。若该字段为空,大概率是以下原因:

  • 检查tracker.update()调用时,是否正确传入了YOLO检测后经ReID模型提取的特征数据
  • 确认ReID模型是否正常加载(原仓库默认使用MobileNet架构的ReID模型,需保证模型路径配置正确)

二、需保存的核心跟踪数据

要实现跨视频跟踪连续性,必须保留每条确认轨迹的唯一标识、状态与特征信息,具体包括:

  • track_id:目标的唯一跟踪ID(核心字段,保证跨视频ID一致)
  • bbox:轨迹最后一帧的边界框(作为第二段视频初始匹配的位置参考)
  • feature:轨迹最后N帧的ReID特征(取最新帧或平均特征,用于跨视频ReID匹配)
  • class_id:目标类别(避免跨类别错误匹配,需在原仓库的Track类中添加该属性)
  • last_frame:轨迹结束的帧号(可选,用于判断目标在第二段视频中出现的可能性)

三、跨视频跟踪融合步骤

  1. 第一段视频结束时保存轨迹
    遍历所有已确认的轨迹,提取上述核心数据,用pickle格式保存(numpy数组用pickle比json更方便)

  2. 第二段视频初始化时加载轨迹
    加载预存轨迹数据,将其作为DeepSORT跟踪器的初始轨迹,而非让跟踪器从头创建空轨迹列表

  3. 修改跟踪器初始化逻辑
    扩展原跟踪器的__init__方法,支持加载预存轨迹,确保新视频的检测结果优先与预存轨迹匹配

四、代码示例(基于原仓库代码修改)

1. 保存第一段视频的轨迹

在第一段视频处理完成后添加以下逻辑:

import pickle
import numpy as np

# 遍历所有已确认且刚更新的轨迹
saved_tracks = []
for track in tracker.tracks:
    if track.is_confirmed() and track.time_since_update == 0:
        track_data = {
            'track_id': track.track_id,
            'bbox': track.to_tlbr().tolist(),
            'feature': track.feature.tolist() if track.feature is not None else None,
            'class_id': track.class_id,  # 需提前在Track类中添加该属性
            'last_frame': current_frame_num  # 当前处理的最后一帧编号
        }
        saved_tracks.append(track_data)

# 保存到本地文件
with open('saved_tracks.pkl', 'wb') as f:
    pickle.dump(saved_tracks, f)

2. 修改跟踪器支持加载预存轨迹

找到deepsort/tracker.py中的Tracker类,修改初始化方法:

from deepsort.track import Track, TrackState

class Tracker:
    def __init__(self, metric, max_iou_distance=0.7, max_age=30, n_init=3, saved_tracks=None):
        self.metric = metric
        self.max_iou_distance = max_iou_distance
        self.max_age = max_age
        self.n_init = n_init

        self.tracks = []
        self._next_id = 1
        # 加载预存轨迹
        if saved_tracks is not None:
            self._load_saved_tracks(saved_tracks)

    def _load_saved_tracks(self, saved_tracks):
        for track_data in saved_tracks:
            # 创建Track对象并初始化参数
            track = Track(
                np.array(track_data['bbox']),
                track_data['track_id'],
                track_data['class_id'],
                self.n_init,
                self.max_age
            )
            # 恢复特征数据
            if track_data['feature'] is not None:
                track.feature = np.array(track_data['feature'])
            # 标记为已确认状态
            track._state = TrackState.CONFIRMED
            self.tracks.append(track)
            # 更新下一个可用ID,避免ID冲突
            if track_data['track_id'] >= self._next_id:
                self._next_id = track_data['track_id'] + 1

3. 第二段视频初始化跟踪器

import pickle

# 加载预存轨迹
with open('saved_tracks.pkl', 'rb') as f:
    saved_tracks = pickle.load(f)

# 初始化跟踪器时传入预存轨迹
tracker = Tracker(metric, saved_tracks=saved_tracks)

五、额外优化建议

  • 若两段视频场景差异大(如光照、视角变化),可增加轨迹匹配的阈值限制,避免错误关联
  • 若track.feature仍为空,可在第一段视频中对确认轨迹保存最近3-5帧的特征,取平均值作为最终保存的特征
  • 可添加目标位置判断:若第一段视频最后一帧的目标bbox在画面边缘,优先保留轨迹用于第二段视频匹配;若目标在画面中间消失,可直接丢弃轨迹

内容的提问来源于stack exchange,提问作者Kush Khamesra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 08:50:22