Ejemplo n.º 1
0
def test_offsets():

    original = BoundBoxArray.from_boundboxes([(0, 0, 0.5, 0.5),
                                              (0.3, 0.4, 0.6, 0.9)])
    default_boxes = BoundBoxArray.from_boundboxes([(0, 0, 0.5, 0.4),
                                                   (0.2, 0.4, 0.6, 0.9)])

    # get offsets
    offsets = calculate_offsets(default_boxes, original)
    offsets = BoundBoxArray.from_centerboxes(offsets)

    # apply them to get original bboxes
    recovered = apply_offsets(default_boxes, offsets)
    recovered = BoundBoxArray.from_centerboxes(recovered)

    assert np.allclose(original, recovered)
Ejemplo n.º 2
0
def test_iou(non_overlapping_boundboxes, full_and_quarter_boundboxes):
    """Test IOU calculation"""

    first, second = non_overlapping_boundboxes
    first = BoundBoxArray.from_boundboxes(first)
    second = BoundBoxArray.from_boundboxes(second)

    assert np.allclose(first.iou(second), np.zeros((2, 2)))
    assert np.allclose(second.iou(first), np.zeros((2, 2)))
    assert np.allclose(first.iou(first), np.eye(2))
    assert np.allclose(second.iou(second), np.eye(2))

    full, quarter = full_and_quarter_boundboxes
    full = BoundBoxArray.from_boundboxes(full)
    quarter = BoundBoxArray.from_boundboxes(quarter)

    assert np.allclose(full.iou(quarter), np.array(0.25))
    assert np.allclose(quarter.iou(full), np.array(0.25))
Ejemplo n.º 3
0
def test_random_hflip():

    bboxes = BoundBoxArray.from_boundboxes([(100, 100, 200, 200)],
                                           classnames=["cat"])
    image = AnnotatedImage(np.ones((300, 300, 3)), bboxes)
    image = image.normalize_bboxes()

    flipped_image = image.random_hflip(probability=1.0)
    # check that centered bbox wasn't flipped
    assert np.allclose(flipped_image.bboxes.boundboxes.as_matrix(),
                       image.bboxes.boundboxes.as_matrix())
    # but image was
    assert np.array_equal(np.fliplr(image.image), flipped_image.image)

    bboxes = BoundBoxArray.from_boundboxes([(0, 0, 150, 300)],
                                           classnames=["cat"])
    image = AnnotatedImage(np.ones((300, 300, 3)), bboxes)
    image = image.normalize_bboxes()

    flipped_image = image.random_hflip(probability=1.0)
    assert np.allclose(flipped_image.bboxes.boundboxes.as_matrix(),
                       np.array([0.5, 0, 1, 1]))
    assert np.array_equal(np.fliplr(image.image), flipped_image.image)
Ejemplo n.º 4
0
def parse_annotation(annotation):
    """Parses PascalVOC-like .xml annotation. BoundBoxArray is returned"""

    root = xml_parser.parse(annotation).getroot()

    boxes = list()
    classnames = list()

    for obj in root.findall('object'):
        # xmin, ymin, xmax, ymax
        boxes.append([int(coord.text) for coord in obj.find('bndbox')])
        classnames.append(obj.find('name').text)

    return BoundBoxArray.from_boundboxes(boxes, classnames)
Ejemplo n.º 5
0
def crop(image, selection):
    """Crops selection (which is a 4-length tuple
    with normalized (to (0, 1) interval)
    (x_min, y_min, x_max, y_max) coordinates) from image"""

    x_min, y_min, x_max, y_max = selection
    height, width = image.size

    x_min_int = int(x_min * width)
    y_min_int = int(y_min * height)
    x_max_int = int(x_max * width)
    y_max_int = int(y_max * height)

    cropped_image = image.image[y_min_int:y_max_int, x_min_int:x_max_int]
    cropped_image = imresize(cropped_image, image.size)

    scale_x = (x_max - x_min)
    scale_y = (y_max - y_min)
    normalized_bboxes = image.normalize_bboxes().bboxes
    # discard all bboxes that lie outside the crop
    valid_bboxes = (
        (normalized_bboxes.centerboxes.x_center > x_min) &
        (normalized_bboxes.centerboxes.x_center < x_max) &
        (normalized_bboxes.centerboxes.y_center < y_max) &
        (normalized_bboxes.centerboxes.y_center > y_min)
    )

    # return original image if there are no bboxes in the selection
    if not valid_bboxes.any():
        return image

    normalized_bboxes = normalized_bboxes[valid_bboxes]
    cropped_bboxes = normalized_bboxes.clip(
        vertical_clip_value=(y_min, y_max),
        horizontal_clip_value=(x_min, x_max)
    )
    shift = [x_min, y_min, x_min, y_min]
    shifted_bboxes = cropped_bboxes.boundboxes.as_matrix() - shift
    shifted_bboxes = BoundBoxArray.from_boundboxes(
        shifted_bboxes,
        classnames=cropped_bboxes.classnames
    )
    resized_bboxes = shifted_bboxes.rescale((scale_y, scale_x)).clip()
    
    cropped = image.__class__(cropped_image,
                              resized_bboxes,
                              filename=image.filename,
                              bboxes_normalized=True)
    
    return cropped
Ejemplo n.º 6
0
def test_labels_and_offsets():

    default_boxes = BoundBoxArray.from_boundboxes([(0, 0, 0.5, 0.5),
                                                   (0, 0, 1.0, 1.0),
                                                   (0.45, 0.45, 0.9, 0.9)])

    bboxes = BoundBoxArray.from_boundboxes([(0, 0, 150, 150), (0, 0, 120, 120),
                                            (150, 150, 300, 300)],
                                           classnames=["cat", "pig", "dog"])
    class_mapping = dict(cat=1, pig=2, dog=3)
    threshold = 0.5

    image = AnnotatedImage(np.ones((300, 300, 3)), bboxes)
    image = image.normalize_bboxes()

    labels, offsets = image.labels_and_offsets(default_boxes, threshold,
                                               class_mapping)

    # cat matched to first, dog matched to third
    # pig wasn't matched since cat has higher IOU
    assert (labels == [1, 0, 3]).all()
    # cat matched perfectly, second default box
    # wasn't matched
    assert (offsets[[0, 1]] == [0, 0, 0, 0]).all()
Ejemplo n.º 7
0
def test_boundbox_creation(boundboxes, centerboxes, boxes, classnames):

    from_boundboxes = BoundBoxArray.from_boundboxes(boundboxes, classnames)

    assert from_boundboxes.shape == (2, 8)
    assert (from_boundboxes.index == classnames).all()

    from_centerboxes = BoundBoxArray.from_centerboxes(centerboxes, classnames)

    assert from_boundboxes.equals(from_centerboxes)

    from_boxes = BoundBoxArray.from_boxes(boxes, classnames)

    assert from_boundboxes.equals(from_boxes)
    assert from_centerboxes.equals(from_boxes)
Ejemplo n.º 8
0
def test_random_crop():

    bboxes = BoundBoxArray.from_boundboxes([(0, 0, 150, 150), (0, 0, 120, 120),
                                            (150, 150, 300, 300)],
                                           classnames=["cat", "pig", "dog"])
    image = AnnotatedImage(np.ones((300, 300, 3)), bboxes)
    image = image.normalize_bboxes()

    # perform 20 random crops
    for _ in range(20):
        cropped_image = image.random_crop(probability=0.9)
        assert cropped_image.size == (300, 300)
        assert (cropped_image.bboxes.x_min >= 0).all()
        assert (cropped_image.bboxes.y_min >= 0).all()
        assert (cropped_image.bboxes.x_max <= 1).all()
        assert (cropped_image.bboxes.y_max <= 1).all()
Ejemplo n.º 9
0
def hflip(image):
    """Flips an instance of AnnotatedImage"""

    flipped_image = np.fliplr(image.image)
    normalized_image = image.normalize_bboxes()

    bboxes = normalized_image.bboxes.boundboxes
    flipped_bboxes = (1 - bboxes.x_max, 1 - bboxes.y_max,
                      1 - bboxes.x_min, 1 - bboxes.y_min)
    flipped_bboxes = np.array(flipped_bboxes, dtype=np.float32).T
    flipped_bboxes = BoundBoxArray.from_boundboxes(
        flipped_bboxes,
        classnames=bboxes.classnames
    )
    flipped = image.__class__(flipped_image,
                              flipped_bboxes,
                              filename=image.filename,
                              bboxes_normalized=True)
    return flipped