0%

目标检测-badcase提取

大致流程

1.所需的数据是:

模型输出,一般为pkl文件。

推理的数据对应的gt数据,一般从coco格式数据集或者VOC格式数据集读取。

原始图像,处理好后将标注框画在上面可视化

输出的是:

画有标注框的图像

2.提取流程:根据数据集生成gt数据->处理pkl输出数据,与gt数据格式匹配->取出漏检,多检,错检的bbox->根据box把前面三种框corp出来保存->将gt、错检、漏检、多检画在图上可视化

取出漏检,多检,错检的bbox

  1. 对每一个img,判断极限情况:如果det_bbox长度为0,则没有检测框->所有gt框都漏了;如果gt_bbox长度为0->所有的检测框都是多检。

  2. 根据socre_thr分别选出比阈值低和高的检测框

  3. 比阈值高的检测框里没有框也是全部漏检,如果有,计算检测框和每个真实框的IOU,

  4. 对于每个检测框,找到iou最大的gt框

    1
    2
    3
    # 对于每个检测框,找到iou最大的gt框
    gt_ious_max = ious.max(axis=1) # gt_ious_max [num_det] 一维向量,是每个det对应的IoU最大的gt框的IoU值
    gt_ious_argmax = ious.argmax(axis=1) # gt_ious_argmax [num_det]一维向量,是每个det对应的IoU最大的gt框的索引
  1. 开始判断badcase:

    a. 错检,IoU匹配上了,但是label不对

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    ####### badcase情形1 错检,IOU匹配,但label不一致  #####
    gt_ious_max_val_indexs = gt_ious_max >= iou_thr # 1.筛选出有效检测框的索引
    if not any(gt_ious_max_val_indexs):
    print("所有检测框都未能匹配到gt框,都为多检")
    else:
    # 找到所有能匹配上gt(iou满足)的det框及 det对应的gt框index
    #gt_ious_max = gt_ious_max[gt_ious_max_val_indexs]
    matchgt_det_bboxes = det_bboxes[gt_ious_max_val_indexs] # 选出有效检测框 [num_det,(4,)]
    matchgt_det_labels = det_labels[gt_ious_max_val_indexs] # 选出有效检测框的标签[num_det,1]
    matchgt_gt_ious_argmax = gt_ious_argmax[gt_ious_max_val_indexs] # 有效检测框中所负责的gt框[num_det, 1(对应本img上的gt框的索引)]
    matchgt_gt_labels = gt_labels[matchgt_gt_ious_argmax] # 取出已经匹配上的检测框对应的真实的标签[num_det,1]
    matchgt_gt_bboxes = gt_bboxes[matchgt_gt_ious_argmax, :] # 取出有效框对应真实框的bbox坐标
    matchgt_gt_bboxes_idx = gt_bboxes_idx[matchgt_gt_ious_argmax] # 取出有效款的真实bbox坐标

    # 筛选出所有错检
    all_trouble_index = matchgt_gt_labels != matchgt_det_labels

    if not any(gt_ious_max_val_indexs):
    print("no trouble det box") # label都匹配上,没有错检
    else:
    all_trouble_det_boxes = matchgt_det_bboxes[all_trouble_index] # 选出错误匹配框的bbox
    all_trouble_det_labels = matchgt_det_labels[all_trouble_index]# 选出错误的标签
    all_trouble_gt_labels = matchgt_gt_labels[all_trouble_index] # 真实的标签
    all_trouble_gt_bboxes = matchgt_gt_bboxes[all_trouble_index] # 真实的bbox
    all_trouble_gt_bboxes_indx = matchgt_gt_bboxes_idx[all_trouble_index] # 有问题bbox的索引

    # 所有错检中筛选出真实label在限定label范围内的错检
    for index in range(len(all_trouble_gt_labels)):
    if all_trouble_gt_labels[index] in save_labels:
    trouble_gtbboxes.append(
    all_trouble_gt_bboxes[index])
    trouble_gtlabels.append(
    all_trouble_gt_labels[index])
    trouble_detbboxes.append(
    all_trouble_det_boxes[index])
    trouble_detlabels.append(
    all_trouble_det_labels[index])
    trouble_gtbboxes_idx.append(
    all_trouble_gt_bboxes_indx[index])

b.多检,未匹配gt的det框

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
####### badcase情形2 多检, 未匹配gt的det框#####
gt_ious_max_val_indexs = gt_ious_max < iou_thr
if not any(gt_ious_max_val_indexs):
print("所有检测框都能匹配到gt框")
else:
# 找到所有不能匹配上gt的det框,即为多检
unmatch_det_bboxes = det_bboxes[gt_ious_max_val_indexs]
unmatch_det_labels = det_labels[gt_ious_max_val_indexs]

unlable_index = 0
# 所有多检中筛选出预测lablel在限定label范围内的多检
for index in range(len(unmatch_det_labels)):
if unmatch_det_labels[index] in save_labels:
unlabel_gtbboxes.append(unmatch_det_bboxes[index])
unlabel_gtlabels.append(unmatch_det_labels[index])
unlabel_gtbboxes_idx.append(
max_anno_idx[0] + unlable_index + 1)
unlable_index += 1

# 对于每个gt框,找到iou最大的检测框
det_ious_max = ious.max(axis=0) # gt_ious_max [num_gt]
det_ious_argmax = ious.argmax(axis=0) # gt_ious_argmax [num_gt]

c.漏检,未匹配到检测框的gt框

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
####### badcase情形3 漏检,未匹配det 的gt框 #####
det_ious_max_val_indexs = det_ious_max < iou_thr
if not any(det_ious_max_val_indexs):
print("所有gt框都能匹配到至少一个检测框")
else:
# 找到所有不能匹配上det的gt框,即为漏检
unmatch_gt_bboxes = gt_bboxes[det_ious_max_val_indexs]
unmatch_gt_labels = gt_labels[det_ious_max_val_indexs]
unmatch_gt_bboxes_idx = gt_bboxes_idx[det_ious_max_val_indexs]

# 所有漏检中筛选出真实label在限定label范围内的漏检
for index in range(len(unmatch_gt_labels)):
if unmatch_gt_labels[index] in save_labels:
undetected_gtbboxes.append(unmatch_gt_bboxes[index])
undetected_gtlabels.append(unmatch_gt_labels[index])
undetected_gtbboxes_idx.append(
unmatch_gt_bboxes_idx[index])