# 将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集合,每个检测框的标识为dfor d,det in enumerate(detections):# 遍历跟踪框(卡尔曼滤波器预测)bbox集合,每个跟踪框标识为tfor 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_trackersif 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))