def voc_eval(detpath, annopath, test_imgid_list, cls_name, ovthresh=0.5, use_07_metric=False, use_diff=False): ''' :param detpath: :param annopath: :param test_imgid_list: it 's a list that contains the img_name of test_imgs :param cls_name: :param ovthresh: :param use_07_metric: :param use_diff: :return: ''' # 1. parse xml to get gtboxes # read list of images imagenames = test_imgid_list recs = {} for i, imagename in enumerate(imagenames): recs[imagename] = parse_rec(os.path.join(annopath, imagename+'.xml')) # if i % 100 == 0: # print('Reading annotation for {:d}/{:d}'.format( # i + 1, len(imagenames))) # 2. get gtboxes for this class. class_recs = {} num_pos = 0 # if cls_name == 'person': # print ("aaa") det_boxes = [] for imagename in imagenames: R = [obj for obj in recs[imagename] if obj['name'] == cls_name] bbox = np.array([x['bbox'] for x in R]) if use_diff: difficult = np.array([False for x in R]).astype(np.bool) else: difficult = np.array([x['difficult'] for x in R]).astype(np.bool) det = [False] * len(R) num_pos = num_pos + sum(~difficult) # ignored the diffcult boxes class_recs[imagename] = {'bbox': bbox, 'difficult': difficult, 'det': det} # det means that gtboxes has already been detected # 3. read the detection file detfile = os.path.join(detpath, "det_"+cls_name+".txt") with open(detfile, 'r') as f: lines = f.readlines() # for a line. that is [img_name, confidence, xmin, ymin, xmax, ymax] splitlines = [x.strip().split(' ') for x in lines if x.strip().split(' ')[0] in imagenames] # a list that include a list image_ids = [x[0] for x in splitlines] # img_id is img_name confidence = np.array([float(x[1]) for x in splitlines]) BB = np.array([[float(z) for z in x[2:]] for x in splitlines]) nd = len(image_ids) # num of detections. That, a line is a det_box. tp = np.zeros(nd) fp = np.zeros(nd) tp_angle_offsets = [] if BB.shape[0] > 0: # sort by confidence sorted_ind = np.argsort(-confidence) sorted_scores = np.sort(-confidence) BB = BB[sorted_ind, :] image_ids = [image_ids[x] for x in sorted_ind] #reorder the img_name # go down dets and mark TPs and FPs for d in range(nd): R = class_recs[image_ids[d]] # img_id is img_name bb = BB[d, :].astype(float) ovmax = -np.inf BBGT = R['bbox'].astype(float) if BBGT.size > 0: # compute overlaps # intersection # ixmin = np.maximum(BBGT[:, 0], bb[0]) # iymin = np.maximum(BBGT[:, 1], bb[1]) # ixmax = np.minimum(BBGT[:, 2], bb[2]) # iymax = np.minimum(BBGT[:, 3], bb[3]) # iw = np.maximum(ixmax - ixmin + 1., 0.) # ih = np.maximum(iymax - iymin + 1., 0.) # inters = iw * ih # # # union # uni = ((bb[2] - bb[0] + 1.) * (bb[3] - bb[1] + 1.) + # (BBGT[:, 2] - BBGT[:, 0] + 1.) * # (BBGT[:, 3] - BBGT[:, 1] + 1.) - inters) # # overlaps = inters / uni overlaps = [] angle_offsets = [] for i in range(len(BBGT)): # print('bb', bb) # print('BBGT', BBGT[i]) overlap = iou_rotate.iou_rotate_calculate1(np.array([bb]), BBGT[i], use_gpu=False)[0] overlaps.append(overlap) angle_offset = abs(bb[-1] - BBGT[i][0][-1]) angle_offsets.append(angle_offset) ovmax = np.max(overlaps) jmax = np.argmax(overlaps) if ovmax > ovthresh: if not R['difficult'][jmax]: if not R['det'][jmax]: # print('angle offset', angle_offsets[jmax]) if angle_offsets[jmax] < ANGLE_TRESHOLD: tp[d] = 1. R['det'][jmax] = 1 tp_angle_offsets.append(angle_offsets[jmax]) else: fp[d] = 1. # print(ovmax, angle_offsets[jmax]) else: fp[d] = 1. # print(ovmax, angle_offsets[jmax]) # 4. get recall, precison and AP fp = np.cumsum(fp) tp = np.cumsum(tp) rec = tp / float(num_pos) # avoid divide by zero in case the first detection matches a difficult # ground truth prec = tp / np.maximum(tp + fp, np.finfo(np.float64).eps) ap = voc_ap(rec, prec, use_07_metric) gt_cls_num = num_pos tp_angle_offsets = np.array(tp_angle_offsets) angle_offsets_mse = np.mean(tp_angle_offsets**2) angle_offsets_rmse = np.sqrt(angle_offsets_mse) print('angle_offsets_mse:', angle_offsets_mse) print('angle_offsets_rmse:', angle_offsets_rmse) return rec, prec, ap, gt_cls_num, tp, fp
def voc_eval(detpath, gtboxes_horizontal_dict, gtboxes_rotate_dict, cls_name, mode, ovthresh=0.5, use_07_metric=False): ''' :param detpath: :param annopath: :param test_imgid_list: it 's a list that contains the img_name of test_imgs :param cls_name: :param ovthresh: :param use_07_metric: :param use_diff: :return: ''' # get gtboxes for this class. # ************************************** class_recs = {} num_pos = 0 for imagename in gtboxes_horizontal_dict.keys(): if mode == 0: R = [ obj for obj in gtboxes_horizontal_dict[imagename] if obj['name'] == cls_name ] else: R = [ obj for obj in gtboxes_rotate_dict[imagename] if obj['name'] == cls_name ] bbox = np.array([x['bbox'] for x in R]) det = [False] * len(R) num_pos = num_pos + len(R) class_recs[imagename] = { 'bbox': bbox, 'det': det } # det means that gtboxes has already been detected # read the detection file if mode == 0: detfile = os.path.join(detpath, "det_h_" + cls_name + ".txt") else: detfile = os.path.join(detpath, "det_r_" + cls_name + ".txt") with open(detfile, 'r') as f: lines = f.readlines() # for a line. that is [img_name, confidence, xmin, ymin, xmax, ymax] splitlines = [x.strip().split(' ') for x in lines] # a list that include a list image_ids = [x[0] for x in splitlines] # img_id is img_name confidence = np.array([float(x[1]) for x in splitlines]) BB = np.array([[float(z) for z in x[2:]] for x in splitlines]) nd = len(image_ids) # num of detections. That, a line is a det_box. tp = np.zeros(nd) fp = np.zeros(nd) if BB.shape[0] > 0: # sort by confidence sorted_ind = np.argsort(-confidence) sorted_scores = np.sort(-confidence) BB = BB[sorted_ind, :] image_ids = [image_ids[x] for x in sorted_ind] #reorder the img_name # go down dets and mark TPs and FPs for d in range(nd): R = class_recs[image_ids[d]] # img_id is img_name bb = BB[d, :].astype(float) ovmax = -np.inf BBGT = R['bbox'].astype(float) if BBGT.size > 0: # compute overlaps # intersection if mode == 0: ixmin = np.maximum(BBGT[:, 0], bb[0]) iymin = np.maximum(BBGT[:, 1], bb[1]) ixmax = np.minimum(BBGT[:, 2], bb[2]) iymax = np.minimum(BBGT[:, 3], bb[3]) iw = np.maximum(ixmax - ixmin + 1., 0.) ih = np.maximum(iymax - iymin + 1., 0.) inters = iw * ih # union uni = ((bb[2] - bb[0] + 1.) * (bb[3] - bb[1] + 1.) + (BBGT[:, 2] - BBGT[:, 0] + 1.) * (BBGT[:, 3] - BBGT[:, 1] + 1.) - inters) overlaps = inters / uni else: overlaps = [] for i in range(len(BBGT)): overlap = iou_rotate.iou_rotate_calculate1( np.array([bb]), np.array([BBGT[i]]), # BBGT[i].reshape(1,-1), use_gpu=False)[0] overlaps.append(overlap) ovmax = np.max(overlaps) jmax = np.argmax(overlaps) if ovmax > ovthresh: if not R['det'][jmax]: tp[d] = 1. R['det'][jmax] = 1 else: fp[d] = 1. else: fp[d] = 1. # 4. get recall, precison and AP fp = np.cumsum(fp) tp = np.cumsum(tp) rec = tp / float(num_pos) # avoid divide by zero in case the first detection matches a difficult # ground truth prec = tp / np.maximum(tp + fp, np.finfo(np.float64).eps) ap = voc_ap(rec, prec, use_07_metric) if len(tp) > 0 and len(fp) > 0: return rec, prec, ap else: return np.array([0], np.float64), np.array([0], np.float64), ap
def eval(rboxes, gboxes, iou_th, use_07_metric, mode): rbox_images = rboxes.keys() fp = np.zeros(len(rbox_images)) tp = np.zeros(len(rbox_images)) box_num = 0 for i in range(len(rbox_images)): rbox_image = rbox_images[i] if len(rboxes[rbox_image][0]['bbox']) > 0: rbox_lists = np.array(rboxes[rbox_image][0]['bbox']) if len(gboxes[rbox_image]) > 0: gbox_list = np.array( [obj['bbox'] for obj in gboxes[rbox_image]]) box_num = box_num + len(gbox_list) gbox_list = np.concatenate( (gbox_list, np.zeros((np.shape(gbox_list)[0], 1))), axis=1) confidence = rbox_lists[:, -1] box_index = np.argsort(-confidence) rbox_lists = rbox_lists[box_index, :] for rbox_list in rbox_lists: if mode == 0: ixmin = np.maximum(gbox_list[:, 0], rbox_list[0]) iymin = np.maximum(gbox_list[:, 1], rbox_list[1]) ixmax = np.minimum(gbox_list[:, 2], rbox_list[2]) iymax = np.minimum(gbox_list[:, 3], rbox_list[3]) iw = np.maximum(ixmax - ixmin + 1., 0.) ih = np.maximum(iymax - iymin + 1., 0.) inters = iw * ih # union uni = ((rbox_list[2] - rbox_list[0] + 1.) * (rbox_list[3] - rbox_list[1] + 1.) + (gbox_list[:, 2] - gbox_list[:, 0] + 1.) * (gbox_list[:, 3] - gbox_list[:, 1] + 1.) - inters) overlaps = inters / uni else: overlaps = iou_rotate.iou_rotate_calculate1( np.array([rbox_list[:-1]]), gbox_list, use_gpu=False)[0] ovmax = np.max(overlaps) jmax = np.argmax(overlaps) if ovmax > iou_th: if gbox_list[jmax, -1] == 0: tp[i] += 1 gbox_list[jmax, -1] = 1 else: fp[i] += 1 else: fp[i] += 1 else: fp[i] += len(rboxes[rbox_image][0]['bbox']) else: continue rec = np.zeros(len(rbox_images)) prec = np.zeros(len(rbox_images)) if box_num == 0: for i in range(len(fp)): if fp[i] != 0: prec[i] = 0 else: prec[i] = 1 else: fp = np.cumsum(fp) tp = np.cumsum(tp) prec = tp / np.maximum(tp + fp, np.finfo(np.float64).eps) rec = tp / box_num ap = voc_ap(rec, prec, use_07_metric) return rec, prec, ap, box_num
def eval(rboxes, gboxes, iou_th, use_07_metric, mode): rbox_images = rboxes.keys() fp = np.zeros(len(rbox_images)) tp = np.zeros(len(rbox_images)) box_num = 0 for i in range(len(rbox_images)): rbox_image = rbox_images[i] if len(rboxes[rbox_image]) > 0: rbox_lists = np.array(rboxes[rbox_image][0]['bbox']) if len(gboxes[rbox_image]) > 0: gbox_list = np.array( [obj['bbox'] for obj in gboxes[rbox_image]]) box_num = box_num + len(gbox_list) gbox_list = np.concatenate( (gbox_list, np.zeros((np.shape(gbox_list)[0], 1))), axis=1) confidence = rbox_lists[:, -1] box_index = np.argsort(-confidence) rbox_lists = rbox_lists[box_index, :] for rbox_list in rbox_lists: if mode == 0: ixmin = np.maximum(gbox_list[:, 0], rbox_list[0]) iymin = np.maximum(gbox_list[:, 1], rbox_list[1]) ixmax = np.minimum(gbox_list[:, 2], rbox_list[2]) iymax = np.minimum(gbox_list[:, 3], rbox_list[3]) iw = np.maximum(ixmax - ixmin + 1., 0.) ih = np.maximum(iymax - iymin + 1., 0.) inters = iw * ih # 重合的面积 # print(inters) # union uni = ( (rbox_list[2] - rbox_list[0] + 1.) * (rbox_list[3] - rbox_list[1] + 1.) + (gbox_list[:, 2] - gbox_list[:, 0] + 1.) * (gbox_list[:, 3] - gbox_list[:, 1] + 1.) - inters ) # 并的面积 overlaps = inters / uni else: overlaps = iou_rotate.iou_rotate_calculate1( np.array([rbox_list[:-1]]), gbox_list, use_gpu=False)[0] ovmax = np.max(overlaps) # 取最大重合的面积 # print(ovmax) jmax = np.argmax(overlaps) # 取最大重合面积的索引 if ovmax > iou_th: # 比阈值大 if gbox_list[jmax, -1] == 0: tp[i] = tp[i] + 1 gbox_list[jmax, -1] = 1 else: fp[i] = fp[i] + 1 else: fp[i] = fp[i] + 1 else: fp[i] = fp[i] + len(rboxes[rbox_image]) else: continue rec = np.zeros(len(rbox_images)) prec = np.zeros(len(rbox_images)) if box_num == 0: for i in range(len(fp)): if fp[i] != 0: prec[i] = 0 else: prec[i] = 1 else: # print(fp) # print(tp) fp = np.cumsum(fp) # 累计求和 tp = np.cumsum(tp) prec = tp / np.maximum(tp + fp, np.finfo(np.float64).eps) # print(box_num) rec = tp / box_num # 标出来的对的占应该标出来的百分比 # avoid division by zero in case first detection matches a difficult ground ruth # 标出来的对的占所有标出来的百分比 ap = voc_ap(rec, prec, use_07_metric) # ap=voc_ap(rec, prec, use_07_metric) # print(ap) return rec, prec, ap
def eval(rboxes, gboxes, iou_th, use_07_metric, mode): rbox_images = rboxes.keys() fp = np.zeros(len(rbox_images)) tp = np.zeros(len(rbox_images)) box_num = 0 for i in range(len(rbox_images)): rbox_image = rbox_images[i] if len(rboxes[rbox_image]) > 0: rbox_lists = np.array(rboxes[rbox_image][0]['bbox']) if len(gboxes[rbox_image]) > 0: gbox_list = np.array([obj['bbox'] for obj in gboxes[rbox_image]]) box_num = box_num + len(gbox_list) gbox_list = np.concatenate((gbox_list, np.zeros((np.shape(gbox_list)[0], 1))), axis=1) confidence = rbox_lists[:, -1] box_index = np.argsort(-confidence) rbox_lists = rbox_lists[box_index, :] for rbox_list in rbox_lists: if mode == 0: ixmin = np.maximum(gbox_list[:, 0], rbox_list[0]) iymin = np.maximum(gbox_list[:, 1], rbox_list[1]) ixmax = np.minimum(gbox_list[:, 2], rbox_list[2]) iymax = np.minimum(gbox_list[:, 3], rbox_list[3]) iw = np.maximum(ixmax - ixmin + 1., 0.) ih = np.maximum(iymax - iymin + 1., 0.) inters = iw * ih # 重合的面积 # print(inters) # union uni = ((rbox_list[2] - rbox_list[0] + 1.) * (rbox_list[3] - rbox_list[1] + 1.) + (gbox_list[:, 2] - gbox_list[:, 0] + 1.) * (gbox_list[:, 3] - gbox_list[:, 1] + 1.) - inters) # 并的面积 overlaps = inters / uni else: overlaps = iou_rotate.iou_rotate_calculate1(np.array([rbox_list[:-1]]), gbox_list, use_gpu=False)[0] ovmax = np.max(overlaps) # 取最大重合的面积 # print(ovmax) jmax = np.argmax(overlaps) # 取最大重合面积的索引 if ovmax > iou_th: # 比阈值大 if gbox_list[jmax, -1] == 0: tp[i] = tp[i] + 1 gbox_list[jmax, -1] = 1 else: fp[i] = fp[i] + 1 else: fp[i] = fp[i] + 1 else: fp[i] = fp[i] + len(rboxes[rbox_image]) else: continue rec = np.zeros(len(rbox_images)) prec = np.zeros(len(rbox_images)) if box_num == 0: for i in range(len(fp)): if fp[i] != 0: prec[i] = 0 else: prec[i] = 1 else: # print(fp) # print(tp) fp = np.cumsum(fp) # 累计求和 tp = np.cumsum(tp) prec = tp / np.maximum(tp + fp, np.finfo(np.float64).eps) # print(box_num) rec = tp / box_num # 标出来的对的占应该标出来的百分比 # avoid division by zero in case first detection matches a difficult ground ruth # 标出来的对的占所有标出来的百分比 ap = voc_ap(rec, prec, use_07_metric) # ap=voc_ap(rec, prec, use_07_metric) # print(ap) return rec, prec, ap
def voc_eval(detpath, annopath, test_imgid_list, cls_name, ovthresh=0.5, use_07_metric=False, use_diff=False): ''' :param detpath: :param annopath: :param test_imgid_list: it 's a list that contains the img_name of test_imgs :param cls_name: :param ovthresh: :param use_07_metric: :param use_diff: :return: ''' # 1. parse xml to get gtboxes # read list of images # read list of images imagenames = test_imgid_list recs = {} class_recs = {} npos = 0 for imagename in imagenames: try: recs[imagename] = parse_rec( os.path.join(annopath, imagename + '.xml')) except FileNotFoundError: # 이미지는 있지만 이미지에 해당하는 annotation 파일이 없는 경우 pass continue R = [obj for obj in recs[imagename] if obj['name'] == cls_name] if len( R ) == 0: # 같은 xml 파일이라도 읽어오지 못하는 문제가 있어 그럴경우, 일단 continue, 원인 찾는중 continue bbox = np.array([x['bbox'] for x in R]) difficult = np.array([x['difficult'] for x in R]).astype(np.bool) det = [False] * len(R) npos = npos + sum(~difficult) class_recs[imagename] = { 'bbox': bbox, 'difficult': difficult, 'det': det } # 3. read the detection file detfile = os.path.join(detpath, "det_" + cls_name + ".txt") with open(detfile, 'r') as f: lines = f.readlines() if len(lines) == 0: return 0, 0, 0 else: # for a line. that is [img_name, confidence, xmin, ymin, xmax, ymax] splitlines = [x.strip().split('__') for x in lines] # a list that include a list image_ids = [x[0] for x in splitlines] # img_id is img_name confidence = np.array([float(x[1]) for x in splitlines]) BB = np.array([[float(z) for z in x[2:]] for x in splitlines]) # sort by confidence sorted_ind = np.argsort(-confidence) sorted_scores = np.sort(-confidence) BB = BB[sorted_ind, :] image_ids = [image_ids[x] for x in sorted_ind] # reorder the img_name nd = len(image_ids) # num of detections. That, a line is a det_box. tp = np.zeros(nd) fp = np.zeros(nd) # go down dets and mark TPs and FPs for d in range(nd): try: # 위에서 특정 xml 을 못읽는 문제 때문에 Key Error 발생, 일단 exception 처리함 R = class_recs[image_ids[d]] except KeyError: continue bb = BB[d, :].astype(float) ovmax = -np.inf BBGT = R['bbox'].astype(float) if BBGT.size > 0: # compute overlaps # intersection overlaps = [] for i in range(len(BBGT)): overlap = iou_rotate.iou_rotate_calculate1( np.array([bb]), BBGT[i], use_gpu=False)[0] overlaps.append(overlap) ovmax = np.max(overlaps) jmax = np.argmax(overlaps) if ovmax > ovthresh: if not R['difficult'][jmax]: if not R['det'][jmax]: tp[d] = 1. R['det'][jmax] = 1 else: fp[d] = 1. else: fp[d] = 1. # 4. get recall, precison and AP fp = np.cumsum(fp) tp = np.cumsum(tp) rec = tp / float(npos) # avoid divide by zero in case the first detection matches a difficult # ground truth prec = tp / np.maximum(tp + fp, np.finfo(np.float64).eps) ap = voc_ap(rec, prec, use_07_metric) return rec, prec, ap