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
Beispiel #2
0
    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]
Beispiel #4
0
    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
Beispiel #5
0
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
Beispiel #6
0
    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))
Beispiel #7
0
    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
Beispiel #8
0
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