超全!2D单目标跟踪常用评价指标及完整代码
作者:大森林 | 来源:3D视觉工坊
在公众号「3DCV」后台,回复「原论文」即可获取pdf和代码链接。
添加微信:dddvisiona,备注:目标检测,拉你入群。文末附行业细分群。
2D单目标跟踪评价指标:
APE(Average Pixel Error):平均像素误差,一般指预测框与真实框中心位置的像素距离取帧平均。用来判断两个矩形框的靠近程度。该值越小,说明误差越小。
AOR(Average Overlap Rate):平均重叠率,即两个矩形框交集的面积与并集的面积之比取帧平均。用来判断两个矩形框的重叠程度。值越高则重叠程度越高,即两个框越靠近,跟踪精度越高。
Pixel Error threshold:需要人为设定的像素误差的阈值,Pixel Error低于该阈值的矩形框被认为是命中目标,反之则被认为未命中。用来作为区分矩形框是否命中目标的指标,阈值越小则要求矩形框与真值像素误差越小。
Overlap Rate threshold:需要人为设定的重叠率的阈值,重叠率高于该阈值的矩形框被认为是命中目标,反之则被认为未命中。用来作为区分矩形框是否命中目标的指标,阈值越高则要求矩形框与真值重叠程度越高。
Success plot:序列中跟踪成功的帧数占总帧数的比例定义为跟踪成功率,选取不同的阈值,则可以得到各阈值下的成功率,连接各点形成success曲线。根据曲线下的面积来衡量tracker的跟踪精确度。
TRE(Temporal Robustness Evaluation):时间鲁棒性评估。从整个序列中截取若干段(可以重复),每段的初始帧利用ground truth进行初始化,在每一段上分别运行跟踪算法,对每一段分别进行评估,最后对总体信息进行统计。
SRE(Spatial Robustness Evaluation):空间鲁棒性评估。对起始帧的ground truth进行shift或scale操作形成若干段测试序列,在每一段上分别运行跟踪算法,对每一段分别进行评估,最后对总体信息进行统计。
EAO(Expect Average Overlaprate)图:以AOR作为精度的衡量标准,以跟踪算法跟丢目标的次数作为鲁棒性的衡量标准。在一张图中同时反映精度和鲁棒性。越靠近坐标轴右上角,即AOR趋于1,SF趋于0,说明该算法精度和鲁棒性越好。
这里分别展示了APE、AOR、Pixel Error threshold、Overlap Rate threshold、Success plot、TRE、SRE和EAO八种指标的计算代码。
# APE(Average Pixel Error):平均像素误差,一般指预测框与真实框中心位置的像素距离取帧平均。# 假设preds和gts是两个列表,分别存储预测框和真实框的中心坐标,如[(x1, y1), (x2, y2), ...]# 假设n是帧数def APE(preds, gts, n): # 初始化总误差为0 total_error = 0 # 遍历每一帧 for i in range(n): # 计算预测框和真实框中心坐标的欧式距离 error = ((preds[i][0] - gts[i][0]) ** 2 + (preds[i][1] - gts[i][1]) ** 2) ** 0.5 # 累加误差 total_error += error # 返回平均误差 return total_error / n# AOR(Average Overlap Rate):平均重叠率,即两个矩形框交集的面积与并集的面积之比取帧平均。# 假设preds和gts是两个列表,分别存储预测框和真实框的左上角和右下角坐标,如[(x1, y1, x2, y2), ...]# 假设n是帧数def AOR(preds, gts, n): # 初始化总重叠率为0 total_overlap = 0 # 遍历每一帧 for i in range(n): # 计算预测框和真实框的交集面积 inter_area = max(0, min(preds[i][2], gts[i][2]) - max(preds[i][0], gts[i][0])) * max(0, min(preds[i][3], gts[i][3]) - max(preds[i][1], gts[i][1])) # 计算预测框和真实框的并集面积 union_area = (preds[i][2] - preds[i][0]) * (preds[i][3] - preds[i][1]) + (gts[i][2] - gts[i][0]) * (gts[i][3] - gts[i][1]) - inter_area # 计算重叠率 overlap = inter_area / union_area # 累加重叠率 total_overlap += overlap # 返回平均重叠率 return total_overlap / n# Pixel Error threshold:需要人为设定的像素误差的阈值,Pixel Error低于该阈值的矩形框被认为是命中目标,反之则被认为未命中。# 假设preds和gts是两个列表,分别存储预测框和真实框的中心坐标,如[(x1, y1), (x2, y2), ...]# 假设n是帧数,t是阈值def Pixel_Error_threshold(preds, gts, n, t): # 初始化命中数为0 hit_count = 0 # 遍历每一帧 for i in range(n): # 计算预测框和真实框中心坐标的欧式距离 error = ((preds[i][0] - gts[i][0]) ** 2 + (preds[i][1] - gts[i][1]) ** 2) ** 0.5 # 如果误差小于阈值,认为命中目标 if error < t: hit_count += 1 # 返回命中率 return hit_count / n# Overlap Rate threshold:需要人为设定的重叠率的阈值,重叠率高于该阈值的矩形框被认为是命中目标,反之则被认为未命中。# 假设preds和gts是两个列表,分别存储预测框和真实框的左上角和右下角坐标,如[(x1, y1, x2, y2), ...]# 假设n是帧数,t是阈值def Overlap_Rate_threshold(preds, gts, n, t): # 初始化命中数为0 hit_count = 0 # 遍历每一帧 for i in range(n): # 计算预测框和真实框的交集面积 inter_area = max(0, min(preds[i][2], gts[i][2]) - max(preds[i][0], gts[i][0])) * max(0, min(preds[i][3], gts[i][3]) - max(preds[i][1], gts[i][1])) # 计算预测框和真实框的并集面积 union_area = (preds[i][2] - preds[i][0]) * (preds[i][3] - preds[i][1]) + (gts[i][2] - gts[i][0]) * (gts[i][3] - gts[i][1]) - inter_area # 计算重叠率 overlap = inter_area / union_area # 如果重叠率大于阈值,认为命中目标 if overlap > t: hit_count += 1 # 返回命中率 return hit_count / n# Success plot:序列中跟踪成功的帧数占总帧数的比例定义为跟踪成功率,选取不同的阈值,则可以得到各阈值下的成功率,连接各点形成success曲线。# 假设preds和gts是两个列表,分别存储预测框和真实框的左上角和右下角坐标,如[(x1, y1, x2, y2), ...]# 假设n是帧数,m是阈值个数,thresholds是一个列表,存储m个阈值def Success_plot(preds, gts, n, m, thresholds): # 初始化一个列表,存储各阈值下的成功率 success_rates = [] # 遍历每个阈值 for t in thresholds: # 初始化命中数为0 hit_count = 0 # 遍历每一帧 for i in range(n): # 计算预测框和真实框的交集面积 inter_area = max(0, min(preds[i][2], gts[i][2]) - max(preds[i][0], gts[i][0])) * max(0, min(preds[i][3], gts[i][3]) - max(preds[i][1], gts[i][1])) # 计算预测框和真实框的并集面积 union_area = (preds[i][2] - preds[i][0]) * (preds[i][3] - preds[i][1]) + (gts[i][2] - gts[i][0]) * (gts[i][3] - gts[i][1]) - inter_area # 计算重叠率 overlap = inter_area / union_area # 如果重叠率大于阈值,认为命中目标 if overlap > t: hit_count += 1 # 计算并存储当前阈值下的成功率 success_rate = hit_count / n success_rates.append(success_rate) # 返回一个列表,表示success曲线上的点坐标(thresholds, success_rates) return list(zip(thresholds, success_rates))# TRE(Temporal Robustness Evaluation):时间鲁棒性评估。从整个序列中截取若干段(可以重复),每段的初始帧利用ground truth进行初始化,在每一段上分别运行跟踪算法,对每一段分别进行评估,最后对总体信息进行统计。# 假设preds和gts是两个列表,分别存储预测框和真实框的左上角和右下角坐标,如[(x1, y1, x2, y2), ...]# 假设n是帧数,m是截取段数,segments是一个列表,存储m个截取段的起始帧和结束帧,如[(s1, e1), (s2, e2), ...]def TRE(preds, gts, n, m, segments): # 初始化一个列表,存储各段的平均重叠率 overlap_rates = [] # 遍历每个截取段 for s, e in segments: # 初始化该段的总重叠率为0 total_overlap = 0 # 遍历该段的每一帧 for i in range(s, e + 1): # 计算预测框和真实框的交集面积 inter_area = max(0, min(preds[i][2], gts[i][2]) - max(preds[i][0], gts[i][0])) * max(0, min(preds[i][3], gts[i][3]) - max(preds[i][1], gts[i][1])) # 计算预测框和真实框的并集面积 union_area = (preds[i][2] - preds[i][0]) * (preds[i][3] - preds[i][1]) + (gts[i][2] - gts[i][0]) * (gts[i][3] - gts[i][1]) - inter_area # 计算重叠率 overlap = inter_area / union_area # 累加重叠率 total_overlap += overlap # 计算并存储该段的平均重叠率 overlap_rate = total_overlap / (e - s + 1) overlap_rates.append(overlap_rate) # 返回一个列表,表示TRE曲线上的点坐标(segments, overlap_rates) return list(zip(segments, overlap_rates))# SRE(Spatial Robustness Evaluation):空间鲁棒性评估。对起始帧的ground truth进行shift或scale操作形成若干段测试序列,在每一段上分别运行跟踪算法,对每一段分别进行评估,最后对总体信息进行统计。# 假设preds和gts是两个列表,分别存储预测框和真实框的左上角和右下角坐标,如[(x1, y1, x2, y2), ...]# 假设n是帧数,m是测试序列数,sequences是一个列表,存储m个测试序列的起始帧ground truth变化情况,如[("shift", dx1, dy1), ("scale", r1), ...]def SRE(preds, gts, n, m, sequences): # 初始化一个列表,存储各序列的平均重叠率 overlap_rates = [] # 遍历每个测试序列 for seq in sequences: # 初始化该序列的总重叠率为0 total_overlap = 0 # 判断该序列是shift还是scale操作 if seq[0] == "shift": # 获取平移量dx和dy dx, dy = seq[1], seq[2] # 对起始帧的ground truth进行平移操作 gts[0] = (gts[0][0] + dx, gts[0][1] + dy, gts[0][2] + dx, gts[0][3] + dy) elif seq[0] == "scale": # 获取缩放比例r r = seq[1] # 对起始帧的ground truth进行缩放操作 gts[0] = (gts[0][0] * r, gts[0][1] * r, gts[0][2] * r, gts[0][3] * r) # 遍历该序列的每一帧 for i in range(n): # 计算预测框和真实框的交集面积 inter_area = max(0, min(preds[i][2], gts[i][2]) - max(preds[i][0], gts[i][0])) * max(0, min(preds[i][3], gts[i][3]) - max(preds[i][1], gts[i][1])) # 计算预测框和真实框的并集面积 union_area = (preds[i][2] - preds[i][0]) * (preds[i][3] - preds[i][1]) + (gts[i][2] - gts[i][0]) * (gts[i][3] - gts[i][1]) - inter_area # 计算重叠率 overlap = inter_area / union_area # 累加重叠率 total_overlap += overlap # 计算并存储该序列的平均重叠率 overlap_rate = total_overlap / n overlap_rates.append(overlap_rate) # 返回一个列表,表示SRE曲线上的点坐标(sequences, overlap_rates) return list(zip(sequences, overlap_rates))# EAO(Expect Average Overlaprate):期望平均重叠率,综合考虑跟踪精度和鲁棒性,通过一种方式,在一张图中同时反映精度和鲁棒性。# 假设preds和gts是两个列表,分别存储预测框和真实框的左上角和右下角坐标,如[(x1, y1, x2, y2), ...]# 假设n是帧数,SF是跟踪算法跟丢目标的次数def EAO(preds, gts, n, SF): # 初始化总重叠率为0 total_overlap = 0 # 初始化总帧数为0 total_frames = 0 # 遍历每一帧 for i in range(n): # 如果该帧没有跟丢目标,计算重叠率并累加 if i not in SF: # 计算预测框和真实框的交集面积 inter_area = max(0, min(preds[i][2], gts[i][2]) - max(preds[i][0], gts[i][0])) * max(0, min(preds[i][3], gts[i][3]) - max(preds[i][1], gts[i][1])) # 计算预测框和真实框的并集面积 union_area = (preds[i][2] - preds[i][0]) * (preds[i][3] - preds[i][1]) + (gts[i][2] - gts[i][0]) * (gts[i][3] - gts[i][1]) - inter_area # 计算重叠率 overlap = inter_area / union_area # 累加重叠率 total_overlap += overlap # 累加帧数 total_frames += 1 # 返回期望平均重叠率,即总重叠率除以总帧数乘以(n-SF)/n,其中(n-SF)/n是没有跟丢目标的概率 return total_overlap / total_frames * (n - len(SF)) / n