基于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:轨迹结束的帧号(可选,用于判断目标在第二段视频中出现的可能性)
三、跨视频跟踪融合步骤
第一段视频结束时保存轨迹
遍历所有已确认的轨迹,提取上述核心数据,用pickle格式保存(numpy数组用pickle比json更方便)第二段视频初始化时加载轨迹
加载预存轨迹数据,将其作为DeepSORT跟踪器的初始轨迹,而非让跟踪器从头创建空轨迹列表修改跟踪器初始化逻辑
扩展原跟踪器的__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
相关产品推荐
相关产品推荐

