def ga_loc_targets(self, gt_bboxes_list, featmap_sizes): """Compute location targets for guided anchoring. Each feature map is divided into positive, negative and ignore regions. - positive regions: target 1, weight 1 - ignore regions: target 0, weight 0 - negative regions: target 0, weight 0.1 Args: gt_bboxes_list (list[Tensor]): Gt bboxes of each image. featmap_sizes (list[tuple]): Multi level sizes of each feature maps. Returns: tuple """ anchor_scale = self.approx_anchor_generator.octave_base_scale anchor_strides = self.approx_anchor_generator.strides # Currently only supports same stride in x and y direction. for stride in anchor_strides: assert (stride[0] == stride[1]) anchor_strides = [stride[0] for stride in anchor_strides] center_ratio = self.train_cfg.center_ratio ignore_ratio = self.train_cfg.ignore_ratio img_per_gpu = len(gt_bboxes_list) num_lvls = len(featmap_sizes) r1 = (1 - center_ratio) / 2 r2 = (1 - ignore_ratio) / 2 all_loc_targets = [] all_loc_weights = [] all_ignore_map = [] for lvl_id in range(num_lvls): h, w = featmap_sizes[lvl_id] loc_targets = torch.zeros( img_per_gpu, 1, h, w, device=gt_bboxes_list[0].device, dtype=torch.float32) loc_weights = torch.full_like(loc_targets, -1) ignore_map = torch.zeros_like(loc_targets) all_loc_targets.append(loc_targets) all_loc_weights.append(loc_weights) all_ignore_map.append(ignore_map) for img_id in range(img_per_gpu): gt_bboxes = gt_bboxes_list[img_id] scale = torch.sqrt((gt_bboxes[:, 2] - gt_bboxes[:, 0]) * (gt_bboxes[:, 3] - gt_bboxes[:, 1])) min_anchor_size = scale.new_full( (1, ), float(anchor_scale * anchor_strides[0])) # assign gt bboxes to different feature levels w.r.t. their scales target_lvls = torch.floor( torch.log2(scale) - torch.log2(min_anchor_size) + 0.5) target_lvls = target_lvls.clamp(min=0, max=num_lvls - 1).long() for gt_id in range(gt_bboxes.size(0)): lvl = target_lvls[gt_id].item() # rescaled to corresponding feature map gt_ = gt_bboxes[gt_id, :4] / anchor_strides[lvl] # calculate ignore regions ignore_x1, ignore_y1, ignore_x2, ignore_y2 = calc_region( gt_, r2, featmap_sizes[lvl]) # calculate positive (center) regions ctr_x1, ctr_y1, ctr_x2, ctr_y2 = calc_region( gt_, r1, featmap_sizes[lvl]) all_loc_targets[lvl][img_id, 0, ctr_y1:ctr_y2 + 1, ctr_x1:ctr_x2 + 1] = 1 all_loc_weights[lvl][img_id, 0, ignore_y1:ignore_y2 + 1, ignore_x1:ignore_x2 + 1] = 0 all_loc_weights[lvl][img_id, 0, ctr_y1:ctr_y2 + 1, ctr_x1:ctr_x2 + 1] = 1 # calculate ignore map on nearby low level feature if lvl > 0: d_lvl = lvl - 1 # rescaled to corresponding feature map gt_ = gt_bboxes[gt_id, :4] / anchor_strides[d_lvl] ignore_x1, ignore_y1, ignore_x2, ignore_y2 = calc_region( gt_, r2, featmap_sizes[d_lvl]) all_ignore_map[d_lvl][img_id, 0, ignore_y1:ignore_y2 + 1, ignore_x1:ignore_x2 + 1] = 1 # calculate ignore map on nearby high level feature if lvl < num_lvls - 1: u_lvl = lvl + 1 # rescaled to corresponding feature map gt_ = gt_bboxes[gt_id, :4] / anchor_strides[u_lvl] ignore_x1, ignore_y1, ignore_x2, ignore_y2 = calc_region( gt_, r2, featmap_sizes[u_lvl]) all_ignore_map[u_lvl][img_id, 0, ignore_y1:ignore_y2 + 1, ignore_x1:ignore_x2 + 1] = 1 for lvl_id in range(num_lvls): # ignore negative regions w.r.t. ignore map all_loc_weights[lvl_id][(all_loc_weights[lvl_id] < 0) & (all_ignore_map[lvl_id] > 0)] = 0 # set negative regions with weight 0.1 all_loc_weights[lvl_id][all_loc_weights[lvl_id] < 0] = 0.1 # loc average factor to balance loss loc_avg_factor = sum( [t.size(0) * t.size(-1) * t.size(-2) for t in all_loc_targets]) / 200 return all_loc_targets, all_loc_weights, loc_avg_factor
def target_single_image(self, gt_boxes, gt_labels, feat_shape): """ Args: gt_boxes: tensor, tensor <=> img, (num_gt, 4). gt_labels: tensor, tensor <=> img, (num_gt,). feat_shape: tuple. Returns: heatmap: tensor, tensor <=> img, (80, h, w). box_target: tensor, tensor <=> img, (4, h, w) or (80 * 4, h, w). reg_weight: tensor, same as box_target """ output_h, output_w = feat_shape heatmap_channel = self.num_fg # gt_boxes, gt_labels= self.FilerBbox(gt_boxes, gt_labels, output_h*output_w) # if gt_boxes: # gt_boxes = torch.stack(gt_boxes, dim=0) # # if gt_labels: # gt_labels = torch.stack(gt_labels, dim=0) heatmap = torch.zeros((heatmap_channel, output_h, output_w)).cuda() fake_heatmap = torch.zeros((output_h, output_w)).cuda() box_target = torch.ones((self.wh_planes, output_h, output_w)).cuda() * -1 reg_weight = torch.zeros((self.wh_planes // 4, output_h, output_w)).cuda() try: if self.wh_area_process == 'log': boxes_areas_log = self.bbox_areas(gt_boxes).log() elif self.wh_area_process == 'sqrt': boxes_areas_log = self.bbox_areas(gt_boxes).sqrt() else: boxes_areas_log = self.bbox_areas(gt_boxes) boxes_area_topk_log, boxes_ind = torch.topk(boxes_areas_log, boxes_areas_log.size(0)) if self.wh_area_process == 'norm': boxes_area_topk_log[:] = 1. gt_boxes = gt_boxes[boxes_ind] gt_labels = gt_labels[boxes_ind] feat_gt_boxes = gt_boxes / self.down_ratio feat_gt_boxes[:, [0, 2]] = torch.clamp(feat_gt_boxes[:, [0, 2]], min=0, max=output_w - 1) feat_gt_boxes[:, [1, 3]] = torch.clamp(feat_gt_boxes[:, [1, 3]], min=0, max=output_h - 1) feat_hs, feat_ws = (feat_gt_boxes[:, 3] - feat_gt_boxes[:, 1], feat_gt_boxes[:, 2] - feat_gt_boxes[:, 0]) # we calc the center and ignore area based on the gt-boxes of the origin scale # no peak will fall between pixels ct_ints = (torch.stack([(gt_boxes[:, 0] + gt_boxes[:, 2]) / 2, (gt_boxes[:, 1] + gt_boxes[:, 3]) / 2], dim=1) / self.down_ratio).to(torch.int) h_radiuses_alpha = (feat_hs / 2. * self.alpha).int() w_radiuses_alpha = (feat_ws / 2. * self.alpha).int() if self.wh_gaussian and self.alpha != self.beta: h_radiuses_beta = (feat_hs / 2. * self.beta).int() w_radiuses_beta = (feat_ws / 2. * self.beta).int() if not self.wh_gaussian: # calculate positive (center) regions r1 = (1 - self.beta) / 2 ctr_x1s, ctr_y1s, ctr_x2s, ctr_y2s = calc_region(gt_boxes.transpose(0, 1), r1) ctr_x1s, ctr_y1s, ctr_x2s, ctr_y2s = [torch.round(x.float() / self.down_ratio).int() for x in [ctr_x1s, ctr_y1s, ctr_x2s, ctr_y2s]] ctr_x1s, ctr_x2s = [torch.clamp(x, max=output_w - 1) for x in [ctr_x1s, ctr_x2s]] ctr_y1s, ctr_y2s = [torch.clamp(y, max=output_h - 1) for y in [ctr_y1s, ctr_y2s]] # larger boxes have lower priority than small boxes. for k in range(boxes_ind.shape[0]): cls_id = gt_labels[k] - 1 fake_heatmap = fake_heatmap.zero_() self.draw_truncate_gaussian(fake_heatmap, ct_ints[k], h_radiuses_alpha[k].item(), w_radiuses_alpha[k].item()) heatmap[cls_id] = torch.max(heatmap[cls_id], fake_heatmap) if self.wh_gaussian: if self.alpha != self.beta: fake_heatmap = fake_heatmap.zero_() self.draw_truncate_gaussian(fake_heatmap, ct_ints[k], h_radiuses_beta[k].item(), w_radiuses_beta[k].item()) box_target_inds = fake_heatmap > 0 else: ctr_x1, ctr_y1, ctr_x2, ctr_y2 = ctr_x1s[k], ctr_y1s[k], ctr_x2s[k], ctr_y2s[k] box_target_inds = torch.zeros_like(fake_heatmap, dtype=torch.uint8) box_target_inds[ctr_y1:ctr_y2 + 1, ctr_x1:ctr_x2 + 1] = 1 if self.wh_agnostic: box_target[:, box_target_inds] = gt_boxes[k][:, None] cls_id = 0 else: box_target[(cls_id * 4):((cls_id + 1) * 4), box_target_inds] = gt_boxes[k][:, None] if self.wh_gaussian: local_heatmap = fake_heatmap[box_target_inds] ct_div = local_heatmap.sum() local_heatmap *= boxes_area_topk_log[k] reg_weight[cls_id, box_target_inds] = local_heatmap / ct_div else: reg_weight[cls_id, box_target_inds] = \ boxes_area_topk_log[k] / box_target_inds.sum().float() except: # print("There is no big target") pass return heatmap, box_target, reg_weight