def gen_loss_target(self, output_maps, coordinate_target, delta_ratio=0.2): """ :param output_maps: net output size(B, H, W, C) have transform to real coordinate (0-512) NOTICE !!!!! :param coordinate_target: from fun: detection_target, size(B, H, W, 8) :param delta_ratio: trans w / h to delta in 2D-gauss :return: """ # device = output_maps.device gauss_out = output_maps[..., :4] coordinate_out = output_maps[..., 4:] """ # gaussian score gaussian_score = torch.zeros((B, H, W, 4)).float() # distance target maps, ratio of distance distance_target = torch.zeros((B, H, W)).float() # size target maps, ratio of w / h, arctan size_target = torch.zeros((B, H, W)).float() # Discrete degree target maps, Mean square error discrete_target = torch.zeros((B, H, W)).float() """ # ====================【1】Gaussian Score ====================== target_bbox = gtP.corner2bboxHW(coordinate_target) target_size_w = (target_bbox[..., 2] - target_bbox[..., 0]).unsqueeze( -1) # size(B, H, W, 1) target_size_h = (target_bbox[..., 3] - target_bbox[..., 1]).unsqueeze( -1) # size(B, H, W, 1) target_size_w = torch.clamp(target_size_w, min=1e-6) target_size_h = torch.clamp(target_size_h, min=1e-6) gaussian_score_target = self.gauss_2d(coordinate_out[..., 0::2], coordinate_out[..., 1::2], coordinate_target[..., 0::2], coordinate_target[..., 1::2], delta_ratio * target_size_w, delta_ratio * target_size_h) # =====================【2】discrete loss ======================= score_means = ( gaussian_score_target[..., 0] + gaussian_score_target[..., 1] + gaussian_score_target[..., 2] + gaussian_score_target[..., 3]) / 4 # 均方根 discrete_target = torch.sqrt(( (gaussian_score_target[..., 0] - score_means)**2 + (gaussian_score_target[..., 1] - score_means)**2 + (gaussian_score_target[..., 2] - score_means)**2 + (gaussian_score_target[..., 3] - score_means)**2) / 4 + 1e-8) # =====================【3】Distance loss ======================= out_bbox = gtP.corner2bboxHW(coordinate_out) # centers of out and target target_centers = gtP.calc_centers(coordinate_target) out_centers = gtP.calc_centers(coordinate_out) distance_target = self.gen_distance_maps(out_centers, target_centers, out_bbox, target_bbox) # =======================【4】Size loss ========================= whwh_out = self.gen_whwh_maps(coordinate_out) whwh_target = self.gen_whwh_maps(coordinate_target) size_target = (torch.atan(whwh_out[..., 0] / whwh_out[..., 1]) - torch.atan(whwh_target[..., 0] / whwh_target[..., 1])) ** 2 + \ (torch.atan(whwh_out[..., 2] / whwh_out[..., 3]) - torch.atan(whwh_target[..., 2] / whwh_target[..., 3])) ** 2 size_target = size_target * 2 / (math.pi**2) return gaussian_score_target, distance_target, size_target, discrete_target
def gen_loss_target(self, output_maps, coordinate_target, delta_ratio=0.2): """ :param output_maps: net output size(B, H, W, C) have transform to real coordinate (0-512) NOTICE !!!!! :param coordinate_target: from fun: detection_target, size(B, H, W, 8) :param delta_ratio: trans w / h to delta in 2D-gauss :return: """ # device = output_maps.device gauss_out = output_maps[..., :4] coordinate_out = output_maps[..., 4:] """ # gaussian score gaussian_score = torch.zeros((B, H, W, 4)).float() # distance target maps, ratio of distance distance_target = torch.zeros((B, H, W)).float() # size target maps, ratio of w / h, arctan size_target = torch.zeros((B, H, W)).float() # Discrete degree target maps, Mean square error discrete_target = torch.zeros((B, H, W)).float() """ # ====================【1】Gaussian Score ====================== target_bbox = gtP.corner2bboxHW(coordinate_target) target_size_w = (target_bbox[..., 2] - target_bbox[..., 0]).unsqueeze( -1) # size(B, H, W, 1) target_size_h = (target_bbox[..., 3] - target_bbox[..., 1]).unsqueeze( -1) # size(B, H, W, 1) target_size_w = torch.clamp(target_size_w, min=1e-6) target_size_h = torch.clamp(target_size_h, min=1e-6) gaussian_score_target = self.gauss_2d(coordinate_out[..., 0::2], coordinate_out[..., 1::2], coordinate_target[..., 0::2], coordinate_target[..., 1::2], delta_ratio * target_size_w, delta_ratio * target_size_h) return gaussian_score_target
def gen_distance_maps(out_centers, target_centers, out_bbox, target_bbox): """ :param out_centers: size(B, H, W, 2) :param target_centers: size(B, H, W, 2) :param out_bbox: size(B, H, W, 4) :param target_bbox: size(B, H, W, 4) :return: """ center_distance = (out_centers[..., 0] - target_centers[..., 0]) ** 2 + \ (out_centers[..., 1] - target_centers[..., 1]) ** 2 union_bbox = gtP.corner2bboxHW( torch.cat([out_bbox, target_bbox], dim=-1)) corner_distance = (union_bbox[..., 2] - union_bbox[..., 0]) ** 2 + \ (union_bbox[..., 3] - union_bbox[..., 1]) ** 2 distance_maps = center_distance / corner_distance return distance_maps
def detection_analysis(outputs, top_k=50, threshold=0.5, out_size=512.0): """ :param outputs: from detection network, size(B, H, W, C) :param top_k: select top k corners :param threshold: :param out_size: detection outputs size, to limit bound (0~512) :return: """ outputs_list = [] outputs = outputs.data B = outputs.shape[0] gauss_scores = (torch.sum(outputs[..., :4], dim=-1) / 4).reshape( B, -1) # size(B, H*W) coord_outputs = outputs[..., 4:].reshape(B, -1, 8) # size(B, H*W, 8) for i in range(B): _, order = gauss_scores[i].sort(dim=0, descending=True) # order size(B, H*W) gauss_score = gauss_scores[i, order[:top_k]] # size(top_k) coord_output = coord_outputs[i, order[:top_k]] # size(top_k, 8) # 下面保证所得的四边形外接矩形长宽不为0 bbox_output = gtP.corner2bboxHW(coord_output) # size(top_k, 4) w_output = bbox_output[..., 2] - bbox_output[..., 0] # size(top_k) h_output = bbox_output[..., 3] - bbox_output[..., 1] # size(top_k) match_w = (w_output > 0) match_h = (h_output > 0) nonzero_match = (match_w * match_h).nonzero().squeeze() gauss_score = gauss_score[nonzero_match] coord_output = coord_output[nonzero_match] idx = (gauss_score >= threshold).nonzero().squeeze() gauss_score = gauss_score[idx] coord_output = coord_output[idx] coord_output = coord_output.clamp(min=0.0, max=out_size) if len(coord_output.shape) != 2: gauss_score = gauss_score.unsqueeze(0) coord_output = coord_output.unsqueeze(0) outputs_list.append({ 'score': gauss_score, # tensor size(obj) 'coord': coord_output # tensor size(obj, 8) }) return outputs_list