def check_output(self, place): paddle.disable_static() pd_rbox1 = paddle.to_tensor(self.rbox1, place=place) pd_rbox2 = paddle.to_tensor(self.rbox2, place=place) actual_t = rbox_iou(pd_rbox1, pd_rbox2).numpy() poly_rbox1 = self.rbox1 poly_rbox2 = self.rbox2 poly_rbox1[:, 0:4] = self.rbox1[:, 0:4] * 1024 poly_rbox2[:, 0:4] = self.rbox2[:, 0:4] * 1024 expect_t = rbox_overlaps(poly_rbox1, poly_rbox2, use_cv2=False) self.assertAllClose( actual_t, expect_t, msg="rbox_iou has diff at {} \nExpect {}\nBut got {}".format( str(place), str(expect_t), str(actual_t)))
def calc_rbox_iou(pred, gt_rbox): """ calc iou between rotated bbox """ # calc iou of bounding box for speedup pred = np.array(pred, np.float32).reshape(-1, 8) pred = pred.reshape(-1, 2) gt_poly = rbox2poly_np(np.array(gt_rbox).reshape(-1, 5))[0] gt_poly = gt_poly.reshape(-1, 2) pred_rect = [ np.min(pred[:, 0]), np.min(pred[:, 1]), np.max(pred[:, 0]), np.max(pred[:, 1]) ] gt_rect = [ np.min(gt_poly[:, 0]), np.min(gt_poly[:, 1]), np.max(gt_poly[:, 0]), np.max(gt_poly[:, 1]) ] iou = jaccard_overlap(pred_rect, gt_rect, False) if iou <= 0: return iou # calc rbox iou pred = pred.reshape(-1, 8) pred = np.array(pred, np.float32).reshape(-1, 8) pred_rbox = poly2rbox(pred) pred_rbox = pred_rbox.reshape(-1, 5) pred_rbox = pred_rbox.reshape(-1, 5) try: from rbox_iou_ops import rbox_iou except Exception as e: print("import custom_ops error, try install rbox_iou_ops " \ "following ppdet/ext_op/README.md", e) sys.stdout.flush() sys.exit(-1) gt_rbox = np.array(gt_rbox, np.float32).reshape(-1, 5) pd_gt_rbox = paddle.to_tensor(gt_rbox, dtype='float32') pd_pred_rbox = paddle.to_tensor(pred_rbox, dtype='float32') iou = rbox_iou(pd_gt_rbox, pd_pred_rbox) iou = iou.numpy() return iou[0][0]
def assign_anchor(self, anchors, gt_bboxes, gt_lables, pos_iou_thr, neg_iou_thr, min_iou_thr=0.0, ignore_iof_thr=-2): """ Args: anchors: gt_bboxes:[M, 5] rc,yc,w,h,angle gt_lables: Returns: """ assert anchors.shape[1] == 4 or anchors.shape[1] == 5 assert gt_bboxes.shape[1] == 4 or gt_bboxes.shape[1] == 5 anchors_xc_yc = anchors gt_bboxes_xc_yc = gt_bboxes # calc rbox iou anchors_xc_yc = anchors_xc_yc.astype(np.float32) gt_bboxes_xc_yc = gt_bboxes_xc_yc.astype(np.float32) anchors_xc_yc = paddle.to_tensor(anchors_xc_yc) gt_bboxes_xc_yc = paddle.to_tensor(gt_bboxes_xc_yc) try: from rbox_iou_ops import rbox_iou except Exception as e: print("import custom_ops error, try install rbox_iou_ops " \ "following ppdet/ext_op/README.md", e) sys.stdout.flush() sys.exit(-1) iou = rbox_iou(gt_bboxes_xc_yc, anchors_xc_yc) iou = iou.numpy() iou = iou.T # every gt's anchor's index gt_bbox_anchor_inds = iou.argmax(axis=0) gt_bbox_anchor_iou = iou[gt_bbox_anchor_inds, np.arange(iou.shape[1])] gt_bbox_anchor_iou_inds = np.where(iou == gt_bbox_anchor_iou)[0] # every anchor's gt bbox's index anchor_gt_bbox_inds = iou.argmax(axis=1) anchor_gt_bbox_iou = iou[np.arange(iou.shape[0]), anchor_gt_bbox_inds] # (1) set labels=-2 as default labels = np.ones((iou.shape[0], ), dtype=np.int32) * ignore_iof_thr # (2) assign ignore labels[anchor_gt_bbox_iou < min_iou_thr] = ignore_iof_thr # (3) assign neg_ids -1 assign_neg_ids1 = anchor_gt_bbox_iou >= min_iou_thr assign_neg_ids2 = anchor_gt_bbox_iou < neg_iou_thr assign_neg_ids = np.logical_and(assign_neg_ids1, assign_neg_ids2) labels[assign_neg_ids] = -1 # anchor_gt_bbox_iou_inds # (4) assign max_iou as pos_ids >=0 anchor_gt_bbox_iou_inds = anchor_gt_bbox_inds[gt_bbox_anchor_iou_inds] # gt_bbox_anchor_iou_inds = np.logical_and(gt_bbox_anchor_iou_inds, anchor_gt_bbox_iou >= min_iou_thr) labels[gt_bbox_anchor_iou_inds] = gt_lables[anchor_gt_bbox_iou_inds] # (5) assign >= pos_iou_thr as pos_ids iou_pos_iou_thr_ids = anchor_gt_bbox_iou >= pos_iou_thr iou_pos_iou_thr_ids_box_inds = anchor_gt_bbox_inds[iou_pos_iou_thr_ids] labels[iou_pos_iou_thr_ids] = gt_lables[iou_pos_iou_thr_ids_box_inds] return anchor_gt_bbox_inds, anchor_gt_bbox_iou, labels
def get_odm_loss(self, odm_target, s2anet_head_out, reg_loss_type='gwd'): (labels, label_weights, bbox_targets, bbox_weights, bbox_gt_bboxes, pos_inds, neg_inds) = odm_target fam_cls_branch_list, fam_reg_branch_list, odm_cls_branch_list, odm_reg_branch_list = s2anet_head_out odm_cls_losses = [] odm_bbox_losses = [] st_idx = 0 num_total_samples = len(pos_inds) + len( neg_inds) if self.sampling else len(pos_inds) num_total_samples = max(1, num_total_samples) for idx, feat_size in enumerate(self.featmap_sizes_list): feat_anchor_num = feat_size[0] * feat_size[1] # step1: get data feat_labels = labels[st_idx:st_idx + feat_anchor_num] feat_label_weights = label_weights[st_idx:st_idx + feat_anchor_num] feat_bbox_targets = bbox_targets[st_idx:st_idx + feat_anchor_num, :] feat_bbox_weights = bbox_weights[st_idx:st_idx + feat_anchor_num, :] # step2: calc cls loss feat_labels = feat_labels.reshape(-1) feat_label_weights = feat_label_weights.reshape(-1) odm_cls_score = odm_cls_branch_list[idx] odm_cls_score = paddle.squeeze(odm_cls_score, axis=0) odm_cls_score1 = odm_cls_score feat_labels = paddle.to_tensor(feat_labels) feat_labels_one_hot = paddle.nn.functional.one_hot( feat_labels, self.cls_out_channels + 1) feat_labels_one_hot = feat_labels_one_hot[:, 1:] feat_labels_one_hot.stop_gradient = True num_total_samples = paddle.to_tensor( num_total_samples, dtype='float32', stop_gradient=True) odm_cls = F.sigmoid_focal_loss( odm_cls_score1, feat_labels_one_hot, normalizer=num_total_samples, reduction='none') feat_label_weights = feat_label_weights.reshape( feat_label_weights.shape[0], 1) feat_label_weights = np.repeat( feat_label_weights, self.cls_out_channels, axis=1) feat_label_weights = paddle.to_tensor(feat_label_weights) feat_label_weights.stop_gradient = True odm_cls = odm_cls * feat_label_weights odm_cls_total = paddle.sum(odm_cls) odm_cls_losses.append(odm_cls_total) # # step3: regression loss feat_bbox_targets = paddle.to_tensor( feat_bbox_targets, dtype='float32') feat_bbox_targets = paddle.reshape(feat_bbox_targets, [-1, 5]) feat_bbox_targets.stop_gradient = True odm_bbox_pred = odm_reg_branch_list[idx] odm_bbox_pred = paddle.squeeze(odm_bbox_pred, axis=0) odm_bbox_pred = paddle.reshape(odm_bbox_pred, [-1, 5]) odm_bbox = self.smooth_l1_loss(odm_bbox_pred, feat_bbox_targets) loss_weight = paddle.to_tensor( self.reg_loss_weight, dtype='float32', stop_gradient=True) odm_bbox = paddle.multiply(odm_bbox, loss_weight) feat_bbox_weights = paddle.to_tensor( feat_bbox_weights, stop_gradient=True) if reg_loss_type == 'l1': odm_bbox = odm_bbox * feat_bbox_weights odm_bbox_total = paddle.sum(odm_bbox) / num_total_samples elif reg_loss_type == 'iou' or reg_loss_type == 'gwd': odm_bbox = paddle.sum(odm_bbox, axis=-1) feat_bbox_weights = paddle.sum(feat_bbox_weights, axis=-1) try: from rbox_iou_ops import rbox_iou except Exception as e: print("import custom_ops error, try install rbox_iou_ops " \ "following ppdet/ext_op/README.md", e) sys.stdout.flush() sys.exit(-1) # calc iou odm_bbox_decode = self.delta2rbox(self.refine_anchor_list[idx], odm_bbox_pred) bbox_gt_bboxes = paddle.to_tensor( bbox_gt_bboxes, dtype=odm_bbox_decode.dtype, place=odm_bbox_decode.place) bbox_gt_bboxes.stop_gradient = True iou = rbox_iou(odm_bbox_decode, bbox_gt_bboxes) iou = paddle.diag(iou) if reg_loss_type == 'gwd': bbox_gt_bboxes_level = bbox_gt_bboxes[st_idx:st_idx + feat_anchor_num, :] odm_bbox_total = self.gwd_loss(odm_bbox_decode, bbox_gt_bboxes_level) odm_bbox_total = odm_bbox_total * feat_bbox_weights odm_bbox_total = paddle.sum(odm_bbox_total) / num_total_samples odm_bbox_losses.append(odm_bbox_total) st_idx += feat_anchor_num odm_cls_loss = paddle.add_n(odm_cls_losses) odm_cls_loss_weight = paddle.to_tensor( self.cls_loss_weight[1], dtype='float32', stop_gradient=True) odm_cls_loss = odm_cls_loss * odm_cls_loss_weight odm_reg_loss = paddle.add_n(odm_bbox_losses) return odm_cls_loss, odm_reg_loss
# x1 y1 w h [0, 0.5] rbox1[:, 0:4] = rbox1[:, 0:4] * 0.45 + 0.001 rbox2[:, 0:4] = rbox2[:, 0:4] * 0.45 + 0.001 # generate rbox rbox1[:, 4] = rbox1[:, 4] - 0.5 rbox2[:, 4] = rbox2[:, 4] - 0.5 print('rbox1', rbox1.shape, 'rbox2', rbox2.shape) # to paddle tensor pd_rbox1 = paddle.to_tensor(rbox1) pd_rbox2 = paddle.to_tensor(rbox2) iou = rbox_iou(pd_rbox1, pd_rbox2) start_time = time.time() print('paddle time:', time.time() - start_time) print('iou is', iou.cpu().shape) # get gt def rbox2poly_single(rrect, get_best_begin_point=False): """ rrect:[x_ctr,y_ctr,w,h,angle] to poly:[x0,y0,x1,y1,x2,y2,x3,y3] """ x_ctr, y_ctr, width, height, angle = rrect[:5] tl_x, tl_y, br_x, br_y = -width / 2, -height / 2, width / 2, height / 2 # rect 2x4