# 将YOLO模型的检测框和卡尔曼滤波的跟踪框进行匹配 def associate_detection_to_tracker(detections,trackers,iou_threshold=0.3): """ 将检测框bbox与卡尔曼滤波器的跟踪框进行关联匹配 :param detections:检测框 :param trackers:跟踪框,即跟踪目标 :param iou_threshold:IOU阈值 :return:跟踪成功目标的矩阵:matchs 新增目标的矩阵:unmatched_detections 跟踪失败即离开画面的目标矩阵:unmatched_trackers """ #跟踪/检测为0时:直接构造返回结果 if len(trackers) == 0 or (len(detections)==0): return np.empty((0,2),dtype=int),np.arange(len(detections)),np.empty((0,5),dtype=int) # 跟踪/检测不为0时: # iou 不支持数组计算,故IOU 逐个进行交并比计算,构造矩阵scipy.linear_assignment进行匹配 iou_matrix = np.zeros((len(detections), len(trackers)), dtype=np.float32) # 遍历目标检测的bbox集合,每个检测框的标识为d for d,det in enumerate(detections): # 遍历跟踪框(卡尔曼滤波器预测)bbox集合,每个跟踪框标识为t for t,trk in enumerate(trackers): iou_matrix[d,t] = iou(det,trk) #通过匈牙利算法(linear_assignment)将跟踪框和检测框以[[d,t]...]的二维矩阵的形式存储在match_indices中 result = linear_sum_assignment(-iou_matrix) #将匹配结果以 [[d,t]]的形式存储匹配结果 matched_indices = np.array(list(zip(*result))) #记录未匹配的检测框及跟踪框 #未匹配的检测框放入unmatched_detections中,表示有新的目标进入画面,要新增所要跟踪的目标序列 unmatched_detecetions = [] for d,det in enumerate(detections): if d not in matched_indices[:,0]: unmatched_detecetions.append(d) #未匹配的跟踪框放入unmatched_trackers中,表示目标离开之前的画面,应删除对应的跟踪器 unmatched_tracker = [] for t,trk in enumerate(trackers): if t not in matched_indices[:,1]: unmatched_tracker.append(t) #将匹配成功的跟踪框放入matches中进行存储 matchs = [] for m in matched_indices: # 过滤掉IOU低的匹配,将其放入到unmatched_detections和unmatched_trackers if iou_matrix[m[0],m[1]]<iou_threshold: unmatched_tracker.append([m[1]]) unmatched_detecetions.append(m[0]) else: matchs.append(m.reshape(1,2)) #格式转换:初始化matchs,以np.array的形式返回 if len(matchs) == 0 : matchs = np.array((0,2),dtype=int) else: matchs = np.concatenate(matchs, axis=0) return matchs,np.array(unmatched_detecetions,np.array(unmatched_detecetions))