Skip to content

Commit

Permalink
Fix Affine BB aug using only 2 corner points
Browse files Browse the repository at this point in the history
This fixes a bug where the bounding box augmentation
in Affine uses only two corner cordinates (top-left,
bottom-right) instead of all four, leading to malformed
output bounding boxes during rotation and shear.

This bug was likely introduced by #451 (2d3fdb7,
single_step_augment).
  • Loading branch information
aleju committed Nov 4, 2019
1 parent 510c021 commit 8ac38b3
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 3 deletions.
20 changes: 17 additions & 3 deletions imgaug/augmenters/geometric.py
Original file line number Diff line number Diff line change
Expand Up @@ -1007,9 +1007,23 @@ def _augment_batch(self, batch, random_state, parents, hooks):
if (not _is_identity_matrix(matrix)
and not cbaoi.empty
and not (0 in cbaoi.shape[0:2])):
coords = cbaoi.to_xy_array()
coords_aug = tf.matrix_transform(coords, matrix.params)
cbaoi = cbaoi.fill_from_xy_array_(coords_aug)
# TODO this is hacky
if augm_name == "bounding_boxes":
# Ensure that 4 points are used for bbs.
# to_keypoints_on_images() does return 4 points,
# to_xy_array() does not.
kpsoi = cbaoi.to_keypoints_on_image()
coords = kpsoi.to_xy_array()
coords_aug = tf.matrix_transform(coords,
matrix.params)
kpsoi = kpsoi.fill_from_xy_array_(coords_aug)
cbaoi = cbaoi.invert_to_keypoints_on_image_(
kpsoi)
else:
coords = cbaoi.to_xy_array()
coords_aug = tf.matrix_transform(coords,
matrix.params)
cbaoi = cbaoi.fill_from_xy_array_(coords_aug)

cbaoi.shape = output_shape
augm_value[i] = cbaoi
Expand Down
21 changes: 21 additions & 0 deletions test/augmenters/test_geometric.py
Original file line number Diff line number Diff line change
Expand Up @@ -1851,6 +1851,27 @@ def test_alignment_between_images_and_smaller_heatmaps_for_fixed_rot(self):
assert hm_aug.arr_0to1.shape == (28, 24, 1)
assert (same / img_aug_mask.size) >= 0.9

def test_bounding_boxes_have_expected_shape_after_augmentation(self):
image = np.zeros((100, 100), dtype=np.uint8)
image[20:80, 20:80] = 255
bb = ia.BoundingBox(x1=20, y1=20, x2=80, y2=80)
bbsoi = ia.BoundingBoxesOnImage([bb], shape=image.shape)
for rotate in [10, 20, 40, 80, 120]:
with self.subTest(rotate=rotate):
aug = iaa.Affine(rotate=rotate, order=0)

image_aug, bbsoi_aug = aug(image=image, bounding_boxes=bbsoi)

xx = np.nonzero(np.max(image_aug > 100, axis=0))[0]
yy = np.nonzero(np.max(image_aug > 100, axis=1))[0]
bb_exp_x1 = xx[0]
bb_exp_x2 = xx[-1]
bb_exp_y1 = yy[0]
bb_exp_y2 = yy[-1]
bb_expected = ia.BoundingBox(x1=bb_exp_x1, y1=bb_exp_y1,
x2=bb_exp_x2, y2=bb_exp_y2)
assert bbsoi_aug.bounding_boxes[0].iou(bb_expected) > 0.95


class TestAffine_cval(unittest.TestCase):
@property
Expand Down

0 comments on commit 8ac38b3

Please sign in to comment.