def compute_loss(pred, conv, label, bboxes, STRIDES, NUM_CLASS, IOU_LOSS_THRESH, i=0): conv_shape = tf.shape(conv) batch_size = conv_shape[0] output_size = conv_shape[1] input_size = STRIDES[i] * output_size conv = tf.reshape(conv, (batch_size, output_size, output_size, 3, 5 + NUM_CLASS)) conv_raw_conf = conv[:, :, :, :, 4:5] conv_raw_prob = conv[:, :, :, :, 5:] pred_xywh = pred[:, :, :, :, 0:4] pred_conf = pred[:, :, :, :, 4:5] label_xywh = label[:, :, :, :, 0:4] respond_bbox = label[:, :, :, :, 4:5] label_prob = label[:, :, :, :, 5:] giou = tf.expand_dims(utils.bbox_giou(pred_xywh, label_xywh), axis=-1) input_size = tf.cast(input_size, tf.float32) bbox_loss_scale = 2.0 - 1.0 * label_xywh[:, :, :, :, 2:3] * label_xywh[:, :, :, :, 3:4] / ( input_size** 2) giou_loss = respond_bbox * bbox_loss_scale * (1 - giou) iou = utils.bbox_iou(pred_xywh[:, :, :, :, np.newaxis, :], bboxes[:, np.newaxis, np.newaxis, np.newaxis, :, :]) max_iou = tf.expand_dims(tf.reduce_max(iou, axis=-1), axis=-1) respond_bgd = (1.0 - respond_bbox) * tf.cast(max_iou < IOU_LOSS_THRESH, tf.float32) conf_focal = tf.pow(respond_bbox - pred_conf, 2) conf_loss = conf_focal * ( respond_bbox * tf.nn.sigmoid_cross_entropy_with_logits( labels=respond_bbox, logits=conv_raw_conf) + respond_bgd * tf.nn.sigmoid_cross_entropy_with_logits( labels=respond_bbox, logits=conv_raw_conf)) prob_loss = respond_bbox * tf.nn.sigmoid_cross_entropy_with_logits( labels=label_prob, logits=conv_raw_prob) giou_loss = tf.reduce_mean(tf.reduce_sum(giou_loss, axis=[1, 2, 3, 4])) conf_loss = tf.reduce_mean(tf.reduce_sum(conf_loss, axis=[1, 2, 3, 4])) prob_loss = tf.reduce_mean(tf.reduce_sum(prob_loss, axis=[1, 2, 3, 4])) return giou_loss, conf_loss, prob_loss
def preprocess_true_boxes(self, bboxes): label = [ np.zeros(( self.train_output_sizes[i], self.train_output_sizes[i], self.anchor_per_scale, 5 + self.num_classes, )) for i in range(3) ] bboxes_xywh = [ np.zeros((self.max_bbox_per_scale, 4)) for _ in range(3) ] bbox_count = np.zeros((3, )) for bbox in bboxes: bbox_coor = bbox[:4] bbox_class_ind = bbox[4] onehot = np.zeros(self.num_classes, dtype=np.float) onehot[bbox_class_ind] = 1.0 uniform_distribution = np.full(self.num_classes, 1.0 / self.num_classes) deta = 0.01 smooth_onehot = onehot * (1 - deta) + deta * uniform_distribution bbox_xywh = np.concatenate( [ (bbox_coor[2:] + bbox_coor[:2]) * 0.5, bbox_coor[2:] - bbox_coor[:2], ], axis=-1, ) bbox_xywh_scaled = (1.0 * bbox_xywh[np.newaxis, :] / self.strides[:, np.newaxis]) iou = [] exist_positive = False for i in range(3): anchors_xywh = np.zeros((self.anchor_per_scale, 4)) anchors_xywh[:, 0:2] = ( np.floor(bbox_xywh_scaled[i, 0:2]).astype(np.int32) + 0.5) anchors_xywh[:, 2:4] = self.anchors[i] iou_scale = utils.bbox_iou(bbox_xywh_scaled[i][np.newaxis, :], anchors_xywh) iou.append(iou_scale) iou_mask = iou_scale > 0.3 if np.any(iou_mask): xind, yind = np.floor(bbox_xywh_scaled[i, 0:2]).astype( np.int32) label[i][yind, xind, iou_mask, :] = 0 label[i][yind, xind, iou_mask, 0:4] = bbox_xywh label[i][yind, xind, iou_mask, 4:5] = 1.0 label[i][yind, xind, iou_mask, 5:] = smooth_onehot bbox_ind = int(bbox_count[i] % self.max_bbox_per_scale) bboxes_xywh[i][bbox_ind, :4] = bbox_xywh bbox_count[i] += 1 exist_positive = True if not exist_positive: best_anchor_ind = np.argmax(np.array(iou).reshape(-1), axis=-1) best_detect = int(best_anchor_ind / self.anchor_per_scale) best_anchor = int(best_anchor_ind % self.anchor_per_scale) xind, yind = np.floor(bbox_xywh_scaled[best_detect, 0:2]).astype(np.int32) label[best_detect][yind, xind, best_anchor, :] = 0 label[best_detect][yind, xind, best_anchor, 0:4] = bbox_xywh label[best_detect][yind, xind, best_anchor, 4:5] = 1.0 label[best_detect][yind, xind, best_anchor, 5:] = smooth_onehot bbox_ind = int(bbox_count[best_detect] % self.max_bbox_per_scale) bboxes_xywh[best_detect][bbox_ind, :4] = bbox_xywh bbox_count[best_detect] += 1 label_sbbox, label_mbbox, label_lbbox = label sbboxes, mbboxes, lbboxes = bboxes_xywh return label_sbbox, label_mbbox, label_lbbox, sbboxes, mbboxes, lbboxes
true_positives = [] scores = [] num_annotations = 0 for i in tqdm(range(len(all_annotations)), desc="Computing AP for class %12s" % (CLASSES[idx])): pred_boxes, pred_scores, pred_labels_list = all_detections[i] true_boxes, true_labels_list = all_annotations[i] detected = [] num_annotations += true_labels_list.count(idx) for k in range(len(pred_labels_list)): if pred_labels_list[k] != idx: continue scores.append(pred_scores[k]) ious = utils.bbox_iou(pred_boxes[k:k + 1], true_boxes) m = np.argmax(ious) if ious[m] > IOU_THRESH and pred_labels_list[ k] == true_labels_list[m] and m not in detected: detected.append(m) true_positives.append(1) else: true_positives.append(0) num_predictions = len(true_positives) true_positives = np.array(true_positives) false_positives = np.ones_like(true_positives) - true_positives # sorted by score indices = np.argsort(-np.array(scores)) false_positives = false_positives[indices] true_positives = true_positives[indices]
def preprocess_true_boxes(self, bboxes): # 根据每张图片的bboxes,生成 sbbox, mbbox, lbbox对应的true label以及回归坐标 label = [ np.zeros((self.train_output_sizes[i], self.train_output_sizes[i], self.anchor_per_scale, 5 + self.num_classes)) for i in range(3) ] #[(13,13,3,85), (26,26,3,85), (52,52,3,85)] #bboxes_xywh(3, 150, 4)表示一张图片中最多可以存放(3, 150)个真实框 bboxes_xywh = [ np.zeros((self.max_bbox_per_scale, 4)) for _ in range(3) ] bbox_count = np.zeros((3, )) # 对应3种网格尺寸的bounding box数量 for bbox in bboxes: # 对图片中的每个真实框处理 bbox_coordinate = bbox[:4] #(x_min, y_min, x_max, y_max) bbox_class_index = bbox[4] smooth_onehot = self.smooth_label(bbox_class_index) # 计算中心点坐标, 计算宽高, 拼接成一个数组(x, y, w, h) bbox_xywh = np.concatenate( [(bbox_coordinate[2:] + bbox_coordinate[:2]) * 0.5, bbox_coordinate[2:] - bbox_coordinate[:2]], axis=-1) # 按8,16,32下采样比例对中心点以及宽高进行缩放,shape = (3, 4) bbox_xywh_scaled = 1.0 * bbox_xywh[ np.newaxis, :] / self.strides[:, np.newaxis] # 新建一个空列表,用来保存3个anchor框(先验框)和真实框(缩小后)的IOU值 iou = [] exist_positive = False for i in range(3): # 对于一个bbox,遍历其sbbox, mbbox, lbbox,找到对应的anchors anchors_xywh = np.zeros((self.anchor_per_scale, 4)) # (3, 4) anchors_xywh[:, 0:2] = np.floor(bbox_xywh_scaled[i, 0:2]).astype( np.int32) + 0.5 # 找到bbox在尺度i下对应的anchors的中心坐标 anchors_xywh[:, 2:4] = self.anchors[i] # 添加i尺度下3个anchor的预置宽高 # 计算当前该anchor和true label的iou值 iou_scale = utils.bbox_iou(bbox_xywh_scaled[i][np.newaxis, :], anchors_xywh) iou.append(iou_scale) iou_mask = iou_scale > 0.3 if np.any(iou_mask): # 三个anchor中存在最少一个和true bbox的iou大于阈值 # 根据真实框的坐标信息来计算所属网格左上角的位置坐标 xind, yind = np.floor(bbox_xywh_scaled[i, 0:2]).astype( np.int32) label[i][yind, xind, iou_mask, :] = 0 label[i][yind, xind, iou_mask, 0:4] = bbox_xywh label[i][yind, xind, iou_mask, 4:5] = 1.0 label[i][yind, xind, iou_mask, 5:] = smooth_onehot bbox_ind = int(bbox_count[i] % self.max_bbox_per_scale) bboxes_xywh[i][bbox_ind, :4] = bbox_xywh bbox_count[i] += 1 exist_positive = True if not exist_positive: # 在该真实框中,3种网格尺寸都不存在iou > 0.3 的 anchor 框 # reshape(-1)将矩阵排成1行,axis=-1,argmax最后返回一个最大值索引 best_anchor_ind = np.argmax(np.array(iou).reshape(-1), axis=-1) # 获取best_anchor_ind所在的网格尺寸索引 best_detect = int(best_anchor_ind / self.anchor_per_scale) # 获取best_anchor_ind在该网格尺寸下的索引 best_anchor = int(best_anchor_ind % self.anchor_per_scale) xind, yind = np.floor(bbox_xywh_scaled[best_detect, 0:2]).astype(np.int32) label[best_detect][yind, xind, best_anchor, :] = 0 label[best_detect][yind, xind, best_anchor, 0:4] = bbox_xywh label[best_detect][yind, xind, best_anchor, 4:5] = 1.0 label[best_detect][yind, xind, best_anchor, 5:] = smooth_onehot bbox_ind = int(bbox_count[best_detect] % self.max_bbox_per_scale) bboxes_xywh[best_detect][bbox_ind, :4] = bbox_xywh bbox_count[best_detect] += 1 label_sbbox, label_mbbox, label_lbbox = label sbboxes, mbboxes, lbboxes = bboxes_xywh return label_sbbox, label_mbbox, label_lbbox, sbboxes, mbboxes, lbboxes
def evaluate(sess, y_pred, y_true): NUM_CLASSES = Config.NUM_CLASSES CLASSES = Config.CLASSES all_detections = [] all_annotations = [] all_aver_precs = {CLASSES[i]:0. for i in range(NUM_CLASSES)} for _ in range(868): y_pred_o, y_true_o = sess.run([y_pred, y_true],feed_dict={is_training:False}) pred_boxes = y_pred_o[0] pred_confs = y_pred_o[1] pred_probs = y_pred_o[2] true_labels_list, true_boxes_list = [], [] true_probs_temp = y_true_o[..., 5: ] true_boxes_temp = y_true_o[..., 0:4] object_mask = true_probs_temp.sum(axis=-1) > 0 true_probs_temp = true_probs_temp[object_mask] true_boxes_temp = true_boxes_temp[object_mask] true_labels_list += np.argmax(true_probs_temp, axis=-1).tolist() true_boxes_list += true_boxes_temp.tolist() pred_boxes, pred_scores, pred_labels = utils.cpu_nms(pred_boxes, pred_confs*pred_probs, NUM_CLASSES, score_thresh=0.3, iou_thresh=0.5) true_boxes = np.array(true_boxes_list) box_centers, box_sizes = true_boxes[:,0:2], true_boxes[:,2:4] true_boxes[:,0:2] = box_centers - box_sizes / 2. true_boxes[:,2:4] = true_boxes[:,0:2] + box_sizes pred_labels_list = [] if pred_labels is None else pred_labels.tolist() all_detections.append( [pred_boxes, pred_scores, pred_labels_list]) all_annotations.append([true_boxes, true_labels_list]) for idx in range(NUM_CLASSES): true_positives = [] scores = [] num_annotations = 0 for i in range(len(all_annotations)): pred_boxes, pred_scores, pred_labels_list = all_detections[i] true_boxes, true_labels_list = all_annotations[i] detected = [] num_annotations += true_labels_list.count(idx) for k in range(len(pred_labels_list)): if pred_labels_list[k] != idx: continue scores.append(pred_scores[k]) ious = utils.bbox_iou(pred_boxes[k:k+1], true_boxes) m = np.argmax(ious) if ious[m] > 0.5 and pred_labels_list[k] == true_labels_list[m] and m not in detected: detected.append(m) true_positives.append(1) else: true_positives.append(0) num_predictions = len(true_positives) true_positives = np.array(true_positives) false_positives = np.ones_like(true_positives) - true_positives # sorted by score indices = np.argsort(-np.array(scores)) false_positives = false_positives[indices] true_positives = true_positives[indices] # compute false positives and true positives false_positives = np.cumsum(false_positives) true_positives = np.cumsum(true_positives) # compute recall and precision recall = true_positives / np.maximum(num_annotations, np.finfo(np.float64).eps) precision = true_positives / np.maximum(num_predictions, np.finfo(np.float64).eps) # compute average precision average_precision = utils.compute_ap(recall, precision) all_aver_precs[CLASSES[idx]] = average_precision MAP = sum(all_aver_precs.values()) / NUM_CLASSES return MAP
def preprocess_true_boxes(self, image, bboxes): label = [ np.zeros(( self.train_output_sizes[i], self.train_output_sizes[i], self.anchor_per_scale, 5 + self.num_classes, )) for i in range(self.num_detection_layers) ] count_overlap = [ np.zeros(( self.train_output_sizes[i], self.train_output_sizes[i], ), dtype=np.int32) for i in range(self.num_detection_layers) ] _, feath, featw, _, _ = np.array(label).shape bboxes_xywh = [ np.zeros((self.max_bbox_per_scale, 4)) for _ in range(self.num_detection_layers) ] bbox_count = np.zeros((self.num_detection_layers, )) """ negative sample 처리 """ if np.cast[np.int]( bboxes[0] [4]) == -1: # bbox_class_ind = np.cast[np.int](bboxes[0][4]) for i in range(cfg.YOLO.NUM_YOLOLAYERS): if cfg.YOLO.NUM_YOLOLAYERS == 3: label_sbbox, label_mbbox, label_lbbox = label sbboxes, mbboxes, lbboxes = bboxes_xywh return label_sbbox, label_mbbox, label_lbbox, sbboxes, mbboxes, lbboxes elif cfg.YOLO.NUM_YOLOLAYERS == 2: label_mbbox, label_lbbox = label mbboxes, lbboxes = bboxes_xywh return label_mbbox, label_lbbox, mbboxes, lbboxes elif cfg.YOLO.NUM_YOLOLAYERS == 1: label_mbbox = label label_mbbox = np.reshape(label_mbbox, [ feath, featw, self.anchor_per_scale, 5 + self.num_classes ]) mbboxes = bboxes_xywh mbboxes = np.reshape(mbboxes, [-1, 4]) return (tf.cast(image, tf.float32), tf.cast(label_mbbox, tf.float32), tf.cast(mbboxes, tf.float32)) for bbox in bboxes: bbox_coor = bbox[:4] bbox_class_ind = np.cast[np.int]( bbox[4]) #tf.cast(bbox[4], tf.int32) # print("bbox_class_ind:{}".format(bbox_class_ind)) # onehot = tf.one_hot(tf.cast(bbox[4],tf.int32), self.num_classes) onehot = np.zeros(self.num_classes, dtype=np.float) onehot[bbox_class_ind] = 1.0 uniform_distribution = np.full(self.num_classes, 1.0 / self.num_classes) deta = 0.01 smooth_onehot = onehot * (1 - deta) + deta * uniform_distribution bbox_xywh = np.concatenate( [ (bbox_coor[2:] + bbox_coor[:2]) * 0.5, bbox_coor[2:] - bbox_coor[:2], ], axis=-1, ) bbox_xywh = np.minimum(bbox_xywh, self.train_input_size - 1) bbox_xywh = np.maximum(bbox_xywh, 0) bbox_xywh_scaled = (1.0 * bbox_xywh[np.newaxis, :] / self.strides[:, np.newaxis]) bbox_xywh_scaled = np.minimum(bbox_xywh_scaled, 19) bbox_xywh_scaled = np.maximum(bbox_xywh_scaled, 0) iou = [] exist_positive = False i = 0 for i in range(self.num_detection_layers ): ## self.num_detection_layers == 1 anchors_xywh = np.zeros( (self.anchor_per_scale, 4)) ## self.anchor_per_scale == 3 anchors_xywh[:, 0:2] = ( np.floor(bbox_xywh_scaled[i, 0:2]).astype(np.int32) + 0.5) anchors_xywh[:, 2: 4] = self.anchors[i] / cfg.YOLO.STRIDES_CUSTOM[i] iou_scale = utils.bbox_iou(bbox_xywh_scaled[i][np.newaxis, :], anchors_xywh) iou.append(iou_scale) iou_mask = iou_scale > 0.3 if np.any(iou_mask): xind, yind = np.floor(bbox_xywh_scaled[i, 0:2]).astype( np.int32) # label[i][yind, xind, iou_mask, :] = 0 # label[i][yind, xind, iou_mask, 0:4] = bbox_xywh # label[i][yind, xind, iou_mask, 4:5] = 1.0 # label[i][yind, xind, iou_mask, 5:] = smooth_onehot label_idx = count_overlap[i][yind, xind] label[i][yind, xind, label_idx:label_idx + 1, :] = 0 label[i][yind, xind, label_idx:label_idx + 1, 0:4] = bbox_xywh label[i][yind, xind, label_idx:label_idx + 1, 4:5] = 1.0 label[i][yind, xind, label_idx:label_idx + 1, 5:] = smooth_onehot count_overlap[i][yind, xind] += 1 # 한 grid 에 중심점 3개 초과시 에러날 것 bbox_ind = int(bbox_count[i] % self.max_bbox_per_scale) bboxes_xywh[i][bbox_ind, :4] = bbox_xywh bbox_count[i] += 1 exist_positive = True if not exist_positive: best_anchor_ind = np.argmax(np.array(iou).reshape(-1), axis=-1) best_detect = int(best_anchor_ind / self.anchor_per_scale) best_anchor = int(best_anchor_ind % self.anchor_per_scale) xind, yind = np.floor(bbox_xywh_scaled[best_detect, 0:2]).astype(np.int32) label_idx = count_overlap[best_detect][yind, xind] label[best_detect][yind, xind, label_idx:label_idx + 1, :] = 0 label[best_detect][yind, xind, label_idx:label_idx + 1, 0:4] = bbox_xywh label[best_detect][yind, xind, label_idx:label_idx + 1, 4:5] = 1.0 label[best_detect][yind, xind, label_idx:label_idx + 1, 5:] = smooth_onehot count_overlap[best_detect][ yind, xind] += 1 # 한 grid 에 중심점 3개 초과시 에러날 것 # label[best_detect][yind, xind, best_anchor, :] = 0 # label[best_detect][yind, xind, best_anchor, 0:4] = bbox_xywh # label[best_detect][yind, xind, best_anchor, 4:5] = 1.0 # label[best_detect][yind, xind, best_anchor, 5:] = smooth_onehot bbox_ind = int(bbox_count[best_detect] % self.max_bbox_per_scale) bboxes_xywh[best_detect][bbox_ind, :4] = bbox_xywh bbox_count[best_detect] += 1 if cfg.YOLO.NUM_YOLOLAYERS == 3: label_sbbox, label_mbbox, label_lbbox = label sbboxes, mbboxes, lbboxes = bboxes_xywh return label_sbbox, label_mbbox, label_lbbox, sbboxes, mbboxes, lbboxes elif cfg.YOLO.NUM_YOLOLAYERS == 2: label_mbbox, label_lbbox = label mbboxes, lbboxes = bboxes_xywh return label_mbbox, label_lbbox, mbboxes, lbboxes elif cfg.YOLO.NUM_YOLOLAYERS == 1: label_mbbox = label label_mbbox = np.reshape( label_mbbox, [feath, featw, self.anchor_per_scale, 5 + self.num_classes]) mbboxes = bboxes_xywh mbboxes = np.reshape(mbboxes, [-1, 4]) return (tf.cast(image, tf.float32), tf.cast(label_mbbox, tf.float32), tf.cast(mbboxes, tf.float32))
def preprocess_true_boxes(self, bboxes, num_detection_layers): label = [ np.zeros(( self.train_output_sizes[i], self.train_output_sizes[i], self.anchor_per_scale, 5 + self.num_classes, )) for i in range(num_detection_layers) ] count_overlap = [ np.zeros(( self.train_output_sizes[i], self.train_output_sizes[i], ), dtype=np.int32) for i in range(num_detection_layers) ] bboxes_xywh = [ np.zeros((self.max_bbox_per_scale, 4)) for _ in range(num_detection_layers) ] bbox_count = np.zeros((num_detection_layers, )) for bbox in bboxes: bbox_coor = bbox[:4] bbox_class_ind = bbox[4] onehot = np.zeros(self.num_classes, dtype=np.float) onehot[bbox_class_ind] = 1.0 uniform_distribution = np.full(self.num_classes, 1.0 / self.num_classes) deta = 0.01 smooth_onehot = onehot * (1 - deta) + deta * uniform_distribution bbox_xywh = np.concatenate( [ (bbox_coor[2:] + bbox_coor[:2]) * 0.5, bbox_coor[2:] - bbox_coor[:2], ], axis=-1, ) bbox_xywh_scaled = (1.0 * bbox_xywh[np.newaxis, :] / self.strides[:, np.newaxis]) iou = [] exist_positive = False for i in range(num_detection_layers): anchors_xywh = np.zeros((self.anchor_per_scale, 4)) anchors_xywh[:, 0:2] = ( np.floor(bbox_xywh_scaled[i, 0:2]).astype(np.int32) + 0.5) # anchors_xywh[:, 2:4] = self.anchors[i] anchors_xywh[:, 2: 4] = self.anchors[i] / cfg.YOLO.STRIDES_CUSTOM[i] iou_scale = utils.bbox_iou(bbox_xywh_scaled[i][np.newaxis, :], anchors_xywh) iou.append(iou_scale) iou_mask = iou_scale > 0.3 if np.any(iou_mask): xind, yind = np.floor(bbox_xywh_scaled[i, 0:2]).astype( np.int32) label_idx = count_overlap[i][yind, xind] # label[i][yind, xind, iou_mask, :] = 0 # label[i][yind, xind, iou_mask, 0:4] = bbox_xywh # label[i][yind, xind, iou_mask, 4:5] = 1.0 # label[i][yind, xind, iou_mask, 5:] = smooth_onehot label[i][yind, xind, label_idx:label_idx + 1, :] = 0 label[i][yind, xind, label_idx:label_idx + 1, 0:4] = bbox_xywh label[i][yind, xind, label_idx:label_idx + 1, 4:5] = 1.0 label[i][yind, xind, label_idx:label_idx + 1, 5:] = smooth_onehot count_overlap[i][yind, xind] += 1 # 한 grid 에 중심점 3개 초과시 에러날 것 bbox_ind = int(bbox_count[i] % self.max_bbox_per_scale) bboxes_xywh[i][bbox_ind, :4] = bbox_xywh bbox_count[i] += 1 exist_positive = True if not exist_positive: best_anchor_ind = np.argmax(np.array(iou).reshape(-1), axis=-1) best_detect = int(best_anchor_ind / self.anchor_per_scale) best_anchor = int(best_anchor_ind % self.anchor_per_scale) xind, yind = np.floor(bbox_xywh_scaled[best_detect, 0:2]).astype(np.int32) label_idx = count_overlap[best_detect][yind, xind] label[best_detect][yind, xind, label_idx:label_idx + 1, :] = 0 label[best_detect][yind, xind, label_idx:label_idx + 1, 0:4] = bbox_xywh label[best_detect][yind, xind, label_idx:label_idx + 1, 4:5] = 1.0 label[best_detect][yind, xind, label_idx:label_idx + 1, 5:] = smooth_onehot count_overlap[best_detect][ yind, xind] += 1 # 한 grid 에 중심점 3개 초과시 에러날 것 ## 원래 # label[best_detect][yind, xind, best_anchor, :] = 0 # label[best_detect][yind, xind, best_anchor, 0:4] = bbox_xywh # label[best_detect][yind, xind, best_anchor, 4:5] = 1.0 # label[best_detect][yind, xind, best_anchor, 5:] = smooth_onehot bbox_ind = int(bbox_count[best_detect] % self.max_bbox_per_scale) bboxes_xywh[best_detect][bbox_ind, :4] = bbox_xywh bbox_count[best_detect] += 1 if cfg.YOLO.NUM_YOLOLAYERS == 3: label_sbbox, label_mbbox, label_lbbox = label sbboxes, mbboxes, lbboxes = bboxes_xywh return label_sbbox, label_mbbox, label_lbbox, sbboxes, mbboxes, lbboxes elif cfg.YOLO.NUM_YOLOLAYERS == 2: label_mbbox, label_lbbox = label mbboxes, lbboxes = bboxes_xywh return label_mbbox, label_lbbox, mbboxes, lbboxes elif cfg.YOLO.NUM_YOLOLAYERS == 1: label_mbbox = label mbboxes = bboxes_xywh return label_mbbox, mbboxes
def nms_convertedw(boxes, num_classes, iou_threshold=0.5, score_threshold=0.25,max_boxes_per_class=50): batch, num_bbox, xywhcp = tf.keras.backend.int_shape(boxes) boxes = np.array(boxes).reshape(1, -1, xywhcp) # (batch, -1, xywhcp) boxes_conf = boxes[..., 4:] boxes_conf = np.max(boxes_conf, axis=-1, keepdims=True) conf_mask = boxes_conf >= score_threshold boxes_conf = boxes_conf[conf_mask] boxes_conf = np.reshape(boxes_conf, newshape=(1, boxes_conf.shape[0], 1)) conf_mask = np.tile(conf_mask, (1, 1, 4 + num_classes)) boxes = boxes[conf_mask] boxes = np.reshape(boxes, newshape=(1, -1, 4 + num_classes)) boxes_classes = np.reshape(np.argmax(boxes[..., 4:], axis=-1), newshape=(1, -1, 1)) boxes_coord = boxes[..., :4] bboxes_coord = [] bboxes_scores = [] bboxes_classes = [] for class_ind in range(num_classes): mask_class = boxes_classes[..., 0:1] == class_ind boxes_class = boxes_classes[mask_class] boxes_conf_class = boxes_conf[mask_class] mask_class = np.tile(mask_class, (1, 1, 4)) boxes_coord_class = boxes_coord[mask_class] boxes_coord_class = np.reshape(boxes_coord_class, (1, -1, 4)) # conf 내림차순 정렬 sorted_idx = np.argsort(boxes_conf_class) sorted_idx = sorted_idx[::-1] boxes_class = np.reshape(boxes_class, newshape=(len(sorted_idx), 1)) boxes_class = boxes_class[sorted_idx] # boxes_class = np.expand_dims(boxes_class, axis=0) boxes_conf_class = np.reshape(boxes_conf_class, newshape=(len(sorted_idx), 1)) boxes_conf_class = boxes_conf_class[sorted_idx] # boxes_conf_class = np.expand_dims(boxes_conf_class, axis=0) boxes_coord_class = np.reshape(boxes_coord_class, newshape=(len(sorted_idx), 4)) boxes_coord_class = boxes_coord_class[sorted_idx] # boxes_coord_class = np.expand_dims(boxes_coord_class, axis=0) best_conf_ind = 0 num_process = boxes_class.shape[0] while best_conf_ind + 1 < num_process: iou_scores = utils.bbox_iou(boxes_coord_class[best_conf_ind:best_conf_ind + 1, :], boxes_coord_class[best_conf_ind + 1:, :]) iou_mask = iou_scores < iou_threshold iou_mask = np.reshape(iou_mask, newshape=(-1, 1)) boxes_class = np.vstack([boxes_class[:best_conf_ind, :], np.expand_dims(boxes_class[best_conf_ind + 1:, :][iou_mask], axis=-1)]) boxes_conf_class = np.vstack([boxes_conf_class[:best_conf_ind, :], np.expand_dims(boxes_conf_class[best_conf_ind + 1:, :][iou_mask], axis=-1)]) iou_mask = np.tile(iou_mask, (1, 4)) boxes_coord_class = np.vstack([boxes_coord_class[:best_conf_ind, :], np.reshape(boxes_coord_class[best_conf_ind + 1:, :][iou_mask], newshape=(-1, 4))]) best_conf_ind += 1 num_process, _ = np.array(boxes_coord_class).shape bboxes_coord.append(boxes_coord_class) bboxes_scores.append(boxes_conf_class) bboxes_classes.append(boxes_class) bboxes_coord = np.vstack(bboxes_coord) bboxes_scores = np.vstack(bboxes_scores) bboxes_classes = np.vstack(bboxes_classes) return bboxes_coord, bboxes_scores, bboxes_classes