Пример #1
0
    def run(self, netout):
        anchors = [
            0.57273, 0.677385, 1.87446, 2.06253, 3.33843, 5.47434, 7.88282,
            3.52778, 9.77052, 9.16828
        ]
        nms_threshold = 0.2
        """Convert Yolo network output to bounding box
        
        # Args
            netout : 4d-array, shape of (grid_h, grid_w, num of boxes per grid, 5 + n_classes)
                YOLO neural network output array
        
        # Returns
            boxes : array, shape of (N, 4)
                coordinate scale is normalized [0, 1]
            probs : array, shape of (N, nb_classes)
        """
        grid_h, grid_w, nb_box = netout.shape[:3]
        boxes = []

        # decode the output by the network
        netout[..., 4] = _sigmoid(netout[..., 4])
        netout[..., 5:] = netout[..., 4][..., np.newaxis] * _softmax(
            netout[..., 5:])
        netout[..., 5:] *= netout[..., 5:] > self._threshold

        for row in range(grid_h):
            for col in range(grid_w):
                for b in range(nb_box):
                    # from 4th element onwards are confidence and class classes
                    classes = netout[row, col, b, 5:]

                    if np.sum(classes) > 0:
                        # first 4 elements are x, y, w, and h
                        x, y, w, h = netout[row, col, b, :4]

                        x = (col + _sigmoid(x)
                             ) / grid_w  # center position, unit: image width
                        y = (row + _sigmoid(y)
                             ) / grid_h  # center position, unit: image height
                        w = anchors[2 * b + 0] * np.exp(
                            w) / grid_w  # unit: image width
                        h = anchors[2 * b + 1] * np.exp(
                            h) / grid_h  # unit: image height
                        confidence = netout[row, col, b, 4]
                        box = BoundBox(x, y, w, h, confidence, classes)
                        boxes.append(box)

        boxes = nms_boxes(boxes, len(classes), nms_threshold, self._threshold)
        boxes, probs = boxes_to_array(boxes)
        return boxes, probs
Пример #2
0
def decode_netout(netout, anchors, obj_thresh, net_h, net_w):
    grid_h, grid_w = netout.shape[:2]
    nb_box = 3
    netout = netout.reshape((grid_h, grid_w, nb_box, -1))
    nb_class = netout.shape[-1] - 5

    boxes = []

    netout[..., :2] = _sigmoid(netout[..., :2])
    netout[..., 4:] = _sigmoid(netout[..., 4:])
    netout[..., 5:] = netout[..., 4][..., np.newaxis] * netout[..., 5:]
    netout[..., 5:] *= netout[..., 5:] > obj_thresh

    for i in range(grid_h * grid_w):
        row = i // grid_w
        col = i % grid_w

        for b in range(nb_box):
            # 4th element is objectness score
            objectness = netout[row, col, b, 4]

            if (objectness <= obj_thresh): continue

            # first 4 elements are x, y, w, and h
            x, y, w, h = netout[row, col, b, :4]

            x = (col + x) / grid_w  # center position, unit: image width
            y = (row + y) / grid_h  # center position, unit: image height
            w = anchors[2 * b + 0] * np.exp(w) / net_w  # unit: image width
            h = anchors[2 * b + 1] * np.exp(h) / net_h  # unit: image height

            # last elements are class probabilities
            classes = netout[row, col, b, 5:]

            box = BoundBox(x - w / 2, y - h / 2, x + w / 2, y + h / 2,
                           objectness, classes)

            boxes.append(box)

    return boxes
Пример #3
0
def NMS(final_probs, final_bbox):
    boxes = list()
    indices = set()
    #np.intp_t pred_length,class_length,class_loop,index,index2

    pred_length = final_bbox.shape[0]
    class_length = final_probs.shape[1]
    for class_loop in range(class_length):
        for index in range(pred_length):
            if final_probs[index, class_loop] == 0: continue
            for index2 in range(index + 1, pred_length):
                if final_probs[index2, class_loop] == 0: continue
                if index == index2: continue
                if box_iou_c(final_bbox[index, 0], final_bbox[index, 1],
                             final_bbox[index, 2], final_bbox[index, 3],
                             final_bbox[index2, 0], final_bbox[index2, 1],
                             final_bbox[index2, 2], final_bbox[index2,
                                                               3]) >= 0.4:
                    if final_probs[index2,
                                   class_loop] > final_probs[index,
                                                             class_loop]:
                        final_probs[index, class_loop] = 0
                        break
                    final_probs[index2, class_loop] = 0

            if index not in indices:
                bb = BoundBox(class_length)
                bb.x = final_bbox[index, 0]
                bb.y = final_bbox[index, 1]
                bb.w = final_bbox[index, 2]
                bb.h = final_bbox[index, 3]
                bb.c = final_bbox[index, 4]
                bb.probs = np.asarray(final_probs[index, :])
                boxes.append(bb)
                indices.add(index)
    return boxes
Пример #4
0
def decode_netout(netout, anchors, obj_thresh, net_size, nb_box=3):
    n_rows, n_cols = netout.shape[:2]
    netout = netout.reshape((n_rows, n_cols, nb_box, -1))

    boxes = []
    for row in range(n_rows):
        for col in range(n_cols):
            for b in range(nb_box):
                x, y, w, h = _decode_coords(netout, row, col, b, anchors)
                objectness, classes = _activate_probs(netout[row, col, b, 4],
                                                      netout[row, col, b,
                                                             5:], obj_thresh)

                x /= n_cols
                y /= n_rows
                w /= net_size
                h /= net_size

                if objectness > obj_thresh:
                    box = BoundBox(x, y, w, h, objectness, classes)
                    boxes.append(box)

    return boxes
Пример #5
0
def postprocess(meta, net_out, imgcv, annotate=False):
    '''
    citation: https://github.com/thtrieu/darkflow/blob/99f9a95468f9bd858d610530524f83612bf635eb/net/yolov2/test.py
    meta: meta data
    net_out:output from the CNN
    imgcv: original image array
    annotate: anntoate bounding box to the image or not
    '''

    # meta
    meta = meta
    H, W, _ = meta['out_size']
    threshold = meta['thresh']
    C, B = meta['classes'], meta['num']
    anchors = meta['anchors']
    net_out = net_out.reshape([H, W, B, -1])

    boxes = list()
    for row in range(H):
        for col in range(W):
            for b in range(B):
                bx = BoundBox(C)
                bx.x, bx.y, bx.w, bx.h, bx.c = net_out[row, col, b, :5]
                bx.c = expit(bx.c)
                bx.x = (col + expit(bx.x)) / W
                bx.y = (row + expit(bx.y)) / H
                bx.w = math.exp(bx.w) * anchors[2 * b + 0] / W
                bx.h = math.exp(bx.h) * anchors[2 * b + 1] / H
                classes = net_out[row, col, b, 5:]
                bx.probs = _softmax(classes) * bx.c
                bx.probs *= bx.probs > threshold
                boxes.append(bx)

    # non max suppress boxes
    for c in range(C):
        for i in range(len(boxes)):
            boxes[i].class_num = c
        boxes = sorted(boxes, key=prob_compare, reverse=True)
        for i in range(len(boxes)):
            boxi = boxes[i]
            if boxi.probs[c] == 0: continue
            for j in range(i + 1, len(boxes)):
                boxj = boxes[j]
                if box_iou(boxi, boxj) >= .4:
                    boxes[j].probs[c] = 0.

    colors = meta['colors']
    labels = meta['labels']
    h, w, _ = imgcv.shape

    outboxes = []
    for b in boxes:
        max_indx = np.argmax(b.probs)
        max_prob = b.probs[max_indx]
        label = labels[max_indx]
        # print(max_prob)
        if max_prob > threshold:
            left = int(round((b.x - b.w / 2.) * w))
            right = int(round((b.x + b.w / 2.) * w))
            top = int(round((b.y - b.h / 2.) * h))
            bot = int(round((b.y + b.h / 2.) * h))
            if left < 0: left = 0
            if right > w - 1: right = w - 1
            if top < 0: top = 0
            if bot > h - 1: bot = h - 1

            x_box = left
            y_box = top
            w_box = right - left
            h_box = bot - top
            #print({"x":x_box,"y":y_box,"w":w_box,"h":h_box,"conf":max_prob})
            outboxes.append({
                "x": x_box,
                "y": y_box,
                "w": w_box,
                "h": h_box,
                "conf": float(max_prob)
            })

            if annotate:
                thick = int((h + w) / 300)
                mess = '%03.3f' % max_prob
                cv2.rectangle(imgcv, (left, top), (right, bot),
                              colors[max_indx], thick)
                cv2.putText(imgcv, mess, (left + thick * 4, top + thick * 6),
                            0, 1e-3 * h, colors[max_indx], thick // 3)

    return outboxes, imgcv