diff --git a/tests/ut/data/dataset/golden/random_resize_with_bbox_op_01_c_result.npz b/tests/ut/data/dataset/golden/random_resize_with_bbox_op_01_c_result.npz new file mode 100644 index 0000000000000000000000000000000000000000..a5623304ba43eddb4656aafa663157636dae5528 Binary files /dev/null and b/tests/ut/data/dataset/golden/random_resize_with_bbox_op_01_c_result.npz differ diff --git a/tests/ut/data/dataset/golden/resize_with_bbox_op_01_c_result.npz b/tests/ut/data/dataset/golden/resize_with_bbox_op_01_c_result.npz new file mode 100644 index 0000000000000000000000000000000000000000..19e8f4440e0b6f1f8c38d962c705303559dcab0b Binary files /dev/null and b/tests/ut/data/dataset/golden/resize_with_bbox_op_01_c_result.npz differ diff --git a/tests/ut/python/dataset/test_random_resize_with_bbox.py b/tests/ut/python/dataset/test_random_resize_with_bbox.py index 66c185d647924e1d3cb41dc89676159dbd7d750f..b0c1c40a800e4a4a64f12fe536bc1325f2db61a9 100644 --- a/tests/ut/python/dataset/test_random_resize_with_bbox.py +++ b/tests/ut/python/dataset/test_random_resize_with_bbox.py @@ -15,251 +15,180 @@ """ Testing the random resize with bounding boxes op in DE """ -from enum import Enum -import matplotlib.pyplot as plt -import matplotlib.patches as patches import numpy as np import mindspore.dataset as ds -from mindspore import log as logger import mindspore.dataset.transforms.vision.c_transforms as c_vision +from mindspore import log as logger +from util import visualize_with_bounding_boxes, InvalidBBoxType, check_bad_bbox, \ + config_get_set_seed, config_get_set_num_parallel_workers, save_and_check_md5 GENERATE_GOLDEN = False -DATA_DIR = "../data/dataset/testVOC2012" +DATA_DIR = "../data/dataset/testVOC2012_2" def fix_annotate(bboxes): """ + Fix annotations to format followed by mindspore. :param bboxes: in [label, x_min, y_min, w, h, truncate, difficult] format :return: annotation in [x_min, y_min, w, h, label, truncate, difficult] format """ - for bbox in bboxes: - tmp = bbox[0] - bbox[0] = bbox[1] - bbox[1] = bbox[2] - bbox[2] = bbox[3] - bbox[3] = bbox[4] - bbox[4] = tmp + for (i, box) in enumerate(bboxes): + bboxes[i] = np.roll(box, -1) return bboxes -class BoxType(Enum): +def test_random_resize_with_bbox_op_rand_c(plot_vis=False): """ - Defines box types for test cases + Prints images and bboxes side by side with and without RandomResizeWithBBox Op applied, + tests with MD5 check, expected to pass """ - WidthOverflow = 1 - HeightOverflow = 2 - NegativeXY = 3 - OnEdge = 4 - WrongShape = 5 + logger.info("test_random_resize_with_bbox_rand_c") + original_seed = config_get_set_seed(1) + original_num_parallel_workers = config_get_set_num_parallel_workers(1) + # Load dataset + dataVoc1 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", + decode=True, shuffle=False) -class AddBadAnnotation: # pylint: disable=too-few-public-methods - """ - Used to add erroneous bounding boxes to object detection pipelines. - Usage: - >>> # Adds a box that covers the whole image. Good for testing edge cases - >>> de = de.map(input_columns=["image", "annotation"], - >>> output_columns=["image", "annotation"], - >>> operations=AddBadAnnotation(BoxType.OnEdge)) - """ + dataVoc2 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", + decode=True, shuffle=False) - def __init__(self, box_type): - self.box_type = box_type - - def __call__(self, img, bboxes): - """ - Used to generate erroneous bounding box examples on given img. - :param img: image where the bounding boxes are. - :param bboxes: in [x_min, y_min, w, h, label, truncate, difficult] format - :return: bboxes with bad examples added - """ - height = img.shape[0] - width = img.shape[1] - if self.box_type == BoxType.WidthOverflow: - # use box that overflows on width - return img, np.array([[0, 0, width + 1, height - 1, 0, 0, 0]]).astype(np.uint32) - - if self.box_type == BoxType.HeightOverflow: - # use box that overflows on height - return img, np.array([[0, 0, width - 1, height + 1, 0, 0, 0]]).astype(np.uint32) - - if self.box_type == BoxType.NegativeXY: - # use box with negative xy - return img, np.array([[-10, -10, width - 1, height - 1, 0, 0, 0]]).astype(np.uint32) - - if self.box_type == BoxType.OnEdge: - # use box that covers the whole image - return img, np.array([[0, 0, width - 1, height - 1, 0, 0, 0]]).astype(np.uint32) - - if self.box_type == BoxType.WrongShape: - # use box that covers the whole image - return img, np.array([[0, 0, width - 1]]).astype(np.uint32) - return img, bboxes - - -def check_bad_box(data, box_type, expected_error): - try: - test_op = c_vision.RandomResizeWithBBox(100) # DEFINE TEST OP HERE -- (PROB 1 IN CASE OF RANDOM) - data = data.map(input_columns=["annotation"], - output_columns=["annotation"], - operations=fix_annotate) - # map to use width overflow - data = data.map(input_columns=["image", "annotation"], - output_columns=["image", "annotation"], - columns_order=["image", "annotation"], - operations=AddBadAnnotation(box_type)) # Add column for "annotation" - # map to apply ops - data = data.map(input_columns=["image", "annotation"], - output_columns=["image", "annotation"], - columns_order=["image", "annotation"], - operations=[test_op]) # Add column for "annotation" - for _, _ in enumerate(data.create_dict_iterator()): - break - except RuntimeError as e: - logger.info("Got an exception in DE: {}".format(str(e))) - assert expected_error in str(e) - - -def add_bounding_boxes(axis, bboxes): - """ - :param axis: axis to modify - :param bboxes: bounding boxes to draw on the axis - :return: None - """ - for bbox in bboxes: - rect = patches.Rectangle((bbox[0], bbox[1]), - bbox[2], bbox[3], - linewidth=1, edgecolor='r', facecolor='none') - # Add the patch to the Axes - axis.add_patch(rect) - - -def visualize(unaugmented_data, augment_data): - for idx, (un_aug_item, aug_item) in \ - enumerate(zip(unaugmented_data.create_dict_iterator(), augment_data.create_dict_iterator())): - axis = plt.subplot(141) - plt.imshow(un_aug_item["image"]) - add_bounding_boxes(axis, un_aug_item["annotation"]) # add Orig BBoxes - plt.title("Original" + str(idx + 1)) - logger.info("Original ", str(idx + 1), " :", un_aug_item["annotation"]) - - axis = plt.subplot(142) - plt.imshow(aug_item["image"]) - add_bounding_boxes(axis, aug_item["annotation"]) # add AugBBoxes - plt.title("Augmented" + str(idx + 1)) - logger.info("Augmented ", str(idx + 1), " ", aug_item["annotation"], "\n") - plt.show() - - -def test_random_resize_with_bbox_op(plot=False): + test_op = c_vision.RandomResizeWithBBox(200) + + dataVoc1 = dataVoc1.map(input_columns=["annotation"], + output_columns=["annotation"], + operations=fix_annotate) + dataVoc2 = dataVoc2.map(input_columns=["annotation"], + output_columns=["annotation"], + operations=fix_annotate) + # map to apply ops + dataVoc2 = dataVoc2.map(input_columns=["image", "annotation"], + output_columns=["image", "annotation"], + columns_order=["image", "annotation"], + operations=[test_op]) + + filename = "random_resize_with_bbox_op_01_c_result.npz" + save_and_check_md5(dataVoc2, filename, generate_golden=GENERATE_GOLDEN) + + unaugSamp, augSamp = [], [] + + for unAug, Aug in zip(dataVoc1.create_dict_iterator(), dataVoc2.create_dict_iterator()): + unaugSamp.append(unAug) + augSamp.append(Aug) + + if plot_vis: + visualize_with_bounding_boxes(unaugSamp, augSamp) + + # Restore config setting + ds.config.set_seed(original_seed) + ds.config.set_num_parallel_workers(original_num_parallel_workers) + + +def test_random_resize_with_bbox_op_edge_c(plot_vis=False): """ - Test random_resize_with_bbox_op + Prints images and bboxes side by side with and without RandomresizeWithBBox Op applied, + applied on dynamically generated edge case, expected to pass. edge case is when bounding + box has dimensions as the image itself. """ - logger.info("Test random resize with bbox") + logger.info("test_random_resize_with_bbox_op_edge_c") + dataVoc1 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", + decode=True, shuffle=False) - # original images - data_original = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", decode=True, shuffle=False) + dataVoc2 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", + decode=True, shuffle=False) - # augmented images - data_augmented = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", decode=True, shuffle=False) + test_op = c_vision.RandomResizeWithBBox(500) - data_original = data_original.map(input_columns=["annotation"], - output_columns=["annotation"], - operations=fix_annotate) + dataVoc1 = dataVoc1.map(input_columns=["annotation"], + output_columns=["annotation"], + operations=fix_annotate) + dataVoc2 = dataVoc2.map(input_columns=["annotation"], + output_columns=["annotation"], + operations=fix_annotate) - data_augmented = data_augmented.map(input_columns=["annotation"], - output_columns=["annotation"], - operations=fix_annotate) + # maps to convert data into valid edge case data + dataVoc1 = dataVoc1.map(input_columns=["image", "annotation"], + output_columns=["image", "annotation"], + columns_order=["image", "annotation"], + operations=[lambda img, bboxes: ( + img, np.array([[0, 0, img.shape[1], img.shape[0]]]).astype(bboxes.dtype))]) - # define map operations - test_op = c_vision.RandomResizeWithBBox(100) # input value being the target size of resizeOp + dataVoc2 = dataVoc2.map(input_columns=["image", "annotation"], + output_columns=["image", "annotation"], + columns_order=["image", "annotation"], + operations=[lambda img, bboxes: ( + img, np.array([[0, 0, img.shape[1], img.shape[0]]]).astype(bboxes.dtype)), test_op]) - data_augmented = data_augmented.map(input_columns=["image", "annotation"], - output_columns=["image", "annotation"], - columns_order=["image", "annotation"], operations=[test_op]) - if plot: - visualize(data_original, data_augmented) + unaugSamp, augSamp = [], [] + for unAug, Aug in zip(dataVoc1.create_dict_iterator(), dataVoc2.create_dict_iterator()): + unaugSamp.append(unAug) + augSamp.append(Aug) -def test_random_resize_with_bbox_invalid_bounds(): - data_voc2 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", decode=True, shuffle=False) - check_bad_box(data_voc2, BoxType.WidthOverflow, "bounding boxes is out of bounds of the image") - data_voc2 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", decode=True, shuffle=False) - check_bad_box(data_voc2, BoxType.HeightOverflow, "bounding boxes is out of bounds of the image") - data_voc2 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", decode=True, shuffle=False) - check_bad_box(data_voc2, BoxType.NegativeXY, "min_x") - data_voc2 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", decode=True, shuffle=False) - check_bad_box(data_voc2, BoxType.WrongShape, "4 features") + if plot_vis: + visualize_with_bounding_boxes(unaugSamp, augSamp) -def test_random_resize_with_bbox_invalid_size(): +def test_random_resize_with_bbox_op_invalid_c(): + """ + Test RandomResizeWithBBox Op on invalid constructor parameters, expected to raise ValueError """ - Test random_resize_with_bbox_op - """ - logger.info("Test random resize with bbox with invalid target size") + logger.info("test_random_resize_with_bbox_op_invalid_c") - # original images - data = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", decode=True, shuffle=False) + try: + # zero value for resize + c_vision.RandomResizeWithBBox(0) - data = data.map(input_columns=["annotation"], - output_columns=["annotation"], - operations=fix_annotate) + except ValueError as err: + logger.info("Got an exception in DE: {}".format(str(err))) + assert "Input is not" in str(err) - # negative target size as input try: - test_op = c_vision.RandomResizeWithBBox(-10) # DEFINE TEST OP HERE -- (PROB 1 IN CASE OF RANDOM) + # one of the size values is zero + c_vision.RandomResizeWithBBox((0, 100)) - # map to apply ops - data = data.map(input_columns=["image", "annotation"], - output_columns=["image", "annotation"], - columns_order=["image", "annotation"], - operations=[test_op]) # Add column for "annotation" + except ValueError as err: + logger.info("Got an exception in DE: {}".format(str(err))) + assert "Input is not" in str(err) - for _, _ in enumerate(data.create_dict_iterator()): - break + try: + # negative value for resize + c_vision.RandomResizeWithBBox(-10) - except ValueError as e: - logger.info("Got an exception in DE: {}".format(str(e))) - print(e) - assert "Input is not" in str(e) + except ValueError as err: + logger.info("Got an exception in DE: {}".format(str(err))) + assert "Input is not" in str(err) - # zero target size as input try: - test_op = c_vision.RandomResizeWithBBox(0) # DEFINE TEST OP HERE -- (PROB 1 IN CASE OF RANDOM) + # invalid input shape + c_vision.RandomResizeWithBBox((100, 100, 100)) - # map to apply ops - data = data.map(input_columns=["image", "annotation"], - output_columns=["image", "annotation"], - columns_order=["image", "annotation"], - operations=[test_op]) # Add column for "annotation" + except TypeError as err: + logger.info("Got an exception in DE: {}".format(str(err))) + assert "Size should be" in str(err) - for _, _ in enumerate(data.create_dict_iterator()): - break - except ValueError as e: - logger.info("Got an exception in DE: {}".format(str(e))) - assert "Input is not" in str(e) - - # invalid input shape - try: - test_op = c_vision.RandomResizeWithBBox((10, 10, 10)) # DEFINE TEST OP HERE -- (PROB 1 IN CASE OF RANDOM) - - # map to apply ops - data = data.map(input_columns=["image", "annotation"], - output_columns=["image", "annotation"], - columns_order=["image", "annotation"], - operations=[test_op]) # Add column for "annotation" +def test_random_resize_with_bbox_op_bad_c(): + """ + Tests RandomResizeWithBBox Op with invalid bounding boxes, expected to catch multiple errors + """ + logger.info("test_random_resize_with_bbox_op_bad_c") + test_op = c_vision.RandomResizeWithBBox((400, 300)) - for _, _ in enumerate(data.create_dict_iterator()): - break + data_voc2 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", decode=True, shuffle=False) + check_bad_bbox(data_voc2, test_op, InvalidBBoxType.WidthOverflow, "bounding boxes is out of bounds of the image") + data_voc2 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", decode=True, shuffle=False) + check_bad_bbox(data_voc2, test_op, InvalidBBoxType.HeightOverflow, "bounding boxes is out of bounds of the image") + data_voc2 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", decode=True, shuffle=False) + check_bad_bbox(data_voc2, test_op, InvalidBBoxType.NegativeXY, "min_x") + data_voc2 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", decode=True, shuffle=False) + check_bad_bbox(data_voc2, test_op, InvalidBBoxType.WrongShape, "4 features") - except TypeError as e: - logger.info("Got an exception in DE: {}".format(str(e))) - assert "Size should be" in str(e) if __name__ == "__main__": - test_random_resize_with_bbox_op(plot=False) - test_random_resize_with_bbox_invalid_bounds() - test_random_resize_with_bbox_invalid_size() + test_random_resize_with_bbox_op_rand_c(plot_vis=False) + test_random_resize_with_bbox_op_edge_c(plot_vis=False) + test_random_resize_with_bbox_op_invalid_c() + test_random_resize_with_bbox_op_bad_c() diff --git a/tests/ut/python/dataset/test_resize_with_bbox.py b/tests/ut/python/dataset/test_resize_with_bbox.py index 8b07f17f1a890209e982d79830adce0e4a7e4f08..75500de65327f857942f84130772f4403cdf5433 100644 --- a/tests/ut/python/dataset/test_resize_with_bbox.py +++ b/tests/ut/python/dataset/test_resize_with_bbox.py @@ -15,281 +15,151 @@ """ Testing the resize with bounding boxes op in DE """ -from enum import Enum import numpy as np -import matplotlib.patches as patches -import matplotlib.pyplot as plt +import mindspore.dataset as ds import mindspore.dataset.transforms.vision.c_transforms as c_vision + from mindspore import log as logger -import mindspore.dataset as ds +from util import visualize_with_bounding_boxes, InvalidBBoxType, check_bad_bbox, \ + save_and_check_md5 GENERATE_GOLDEN = False -DATA_DIR = "../data/dataset/testVOC2012" +DATA_DIR = "../data/dataset/testVOC2012_2" def fix_annotate(bboxes): """ + Fix annotations to format followed by mindspore. :param bboxes: in [label, x_min, y_min, w, h, truncate, difficult] format :return: annotation in [x_min, y_min, w, h, label, truncate, difficult] format """ - for bbox in bboxes: - tmp = bbox[0] - bbox[0] = bbox[1] - bbox[1] = bbox[2] - bbox[2] = bbox[3] - bbox[3] = bbox[4] - bbox[4] = tmp + for (i, box) in enumerate(bboxes): + bboxes[i] = np.roll(box, -1) return bboxes -class BoxType(Enum): +def test_resize_with_bbox_op_c(plot_vis=False): """ - Defines box types for test cases + Prints images and bboxes side by side with and without ResizeWithBBox Op applied, + tests with MD5 check, expected to pass """ - WidthOverflow = 1 - HeightOverflow = 2 - NegativeXY = 3 - OnEdge = 4 - WrongShape = 5 + logger.info("test_resize_with_bbox_op_c") + # Load dataset + dataVoc1 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", + decode=True, shuffle=False) -class AddBadAnnotation: # pylint: disable=too-few-public-methods - """ - Used to add erroneous bounding boxes to object detection pipelines. - Usage: - >>> # Adds a box that covers the whole image. Good for testing edge cases - >>> de = de.map(input_columns=["image", "annotation"], - >>> output_columns=["image", "annotation"], - >>> operations=AddBadAnnotation(BoxType.OnEdge)) - """ + dataVoc2 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", + decode=True, shuffle=False) - def __init__(self, box_type): - self.box_type = box_type - - def __call__(self, img, bboxes): - """ - Used to generate erroneous bounding box examples on given img. - :param img: image where the bounding boxes are. - :param bboxes: in [x_min, y_min, w, h, label, truncate, difficult] format - :return: bboxes with bad examples added - """ - height = img.shape[0] - width = img.shape[1] - if self.box_type == BoxType.WidthOverflow: - # use box that overflows on width - return img, np.array([[0, 0, width + 1, height - 1, 0, 0, 0]]).astype(np.uint32) - - if self.box_type == BoxType.HeightOverflow: - # use box that overflows on height - return img, np.array([[0, 0, width - 1, height + 1, 0, 0, 0]]).astype(np.uint32) - - if self.box_type == BoxType.NegativeXY: - # use box with negative xy - return img, np.array([[-10, -10, width - 1, height - 1, 0, 0, 0]]).astype(np.uint32) - - if self.box_type == BoxType.OnEdge: - # use box that covers the whole image - return img, np.array([[0, 0, width - 1, height - 1, 0, 0, 0]]).astype(np.uint32) - - if self.box_type == BoxType.WrongShape: - # use box that covers the whole image - return img, np.array([[0, 0, width - 1]]).astype(np.uint32) - return img, bboxes - - -def check_bad_box(data, box_type, expected_error): - try: - test_op = c_vision.ResizeWithBBox(100) - data = data.map(input_columns=["annotation"], - output_columns=["annotation"], - operations=fix_annotate) - # map to use width overflow - data = data.map(input_columns=["image", "annotation"], - output_columns=["image", "annotation"], - columns_order=["image", "annotation"], - operations=AddBadAnnotation(box_type)) # Add column for "annotation" - # map to apply ops - data = data.map(input_columns=["image", "annotation"], - output_columns=["image", "annotation"], - columns_order=["image", "annotation"], - operations=[test_op]) # Add column for "annotation" - for _, _ in enumerate(data.create_dict_iterator()): - break - except RuntimeError as e: - logger.info("Got an exception in DE: {}".format(str(e))) - assert expected_error in str(e) - - -def add_bounding_boxes(axis, bboxes): - """ - :param axis: axis to modify - :param bboxes: bounding boxes to draw on the axis - :return: None - """ - for bbox in bboxes: - rect = patches.Rectangle((bbox[0], bbox[1]), - bbox[2], bbox[3], - linewidth=1, edgecolor='r', facecolor='none') - # Add the patch to the Axes - axis.add_patch(rect) - - -def visualize(unaugmented_data, augment_data): - for idx, (un_aug_item, aug_item) in enumerate( - zip(unaugmented_data.create_dict_iterator(), augment_data.create_dict_iterator())): - axis = plt.subplot(141) - plt.imshow(un_aug_item["image"]) - add_bounding_boxes(axis, un_aug_item["annotation"]) # add Orig BBoxes - plt.title("Original" + str(idx + 1)) - logger.info("Original ", str(idx + 1), " :", un_aug_item["annotation"]) - - axis = plt.subplot(142) - plt.imshow(aug_item["image"]) - add_bounding_boxes(axis, aug_item["annotation"]) # add AugBBoxes - plt.title("Augmented" + str(idx + 1)) - logger.info("Augmented ", str(idx + 1), " ", aug_item["annotation"], "\n") - plt.show() - - -def test_resize_with_bbox_op(plot=False): - """ - Test resize_with_bbox_op - """ - logger.info("Test resize with bbox") - - # original images - data_original = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", decode=True, shuffle=False) - - # augmented images - data_augmented = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", decode=True, shuffle=False) - - data_original = data_original.map(input_columns=["annotation"], - output_columns=["annotation"], - operations=fix_annotate) + test_op = c_vision.ResizeWithBBox(200) - data_augmented = data_augmented.map(input_columns=["annotation"], - output_columns=["annotation"], - operations=fix_annotate) + dataVoc1 = dataVoc1.map(input_columns=["annotation"], + output_columns=["annotation"], + operations=fix_annotate) + dataVoc2 = dataVoc2.map(input_columns=["annotation"], + output_columns=["annotation"], + operations=fix_annotate) + # map to apply ops + dataVoc2 = dataVoc2.map(input_columns=["image", "annotation"], + output_columns=["image", "annotation"], + columns_order=["image", "annotation"], + operations=[test_op]) - # define map operations - test_op = c_vision.ResizeWithBBox(100) # input value being the target size of resizeOp + filename = "resize_with_bbox_op_01_c_result.npz" + save_and_check_md5(dataVoc2, filename, generate_golden=GENERATE_GOLDEN) - data_augmented = data_augmented.map(input_columns=["image", "annotation"], - output_columns=["image", "annotation"], - columns_order=["image", "annotation"], operations=[test_op]) - if plot: - visualize(data_original, data_augmented) + unaugSamp, augSamp = [], [] + for unAug, Aug in zip(dataVoc1.create_dict_iterator(), dataVoc2.create_dict_iterator()): + unaugSamp.append(unAug) + augSamp.append(Aug) -def test_resize_with_bbox_invalid_bounds(): - data_voc2 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", decode=True, shuffle=False) - check_bad_box(data_voc2, BoxType.WidthOverflow, "bounding boxes is out of bounds of the image") - data_voc2 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", decode=True, shuffle=False) - check_bad_box(data_voc2, BoxType.HeightOverflow, "bounding boxes is out of bounds of the image") - data_voc2 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", decode=True, shuffle=False) - check_bad_box(data_voc2, BoxType.NegativeXY, "min_x") - data_voc2 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", decode=True, shuffle=False) - check_bad_box(data_voc2, BoxType.WrongShape, "4 features") + if plot_vis: + visualize_with_bounding_boxes(unaugSamp, augSamp) -def test_resize_with_bbox_invalid_size(): +def test_resize_with_bbox_op_edge_c(plot_vis=False): """ - Test resize_with_bbox_op - """ - logger.info("Test resize with bbox with invalid target size") + Prints images and bboxes side by side with and without ResizeWithBBox Op applied, + applied on dynamically generated edge case, expected to pass. edge case is when bounding + box has dimensions as the image itself. + """ + logger.info("test_resize_with_bbox_op_edge_c") + dataVoc1 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", + decode=True, shuffle=False) - # original images - data = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", decode=True, shuffle=False) + dataVoc2 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", + decode=True, shuffle=False) - data = data.map(input_columns=["annotation"], - output_columns=["annotation"], - operations=fix_annotate) + test_op = c_vision.ResizeWithBBox(500) - # negative target size as input - try: - test_op = c_vision.ResizeWithBBox(-10) + dataVoc1 = dataVoc1.map(input_columns=["annotation"], + output_columns=["annotation"], + operations=fix_annotate) + dataVoc2 = dataVoc2.map(input_columns=["annotation"], + output_columns=["annotation"], + operations=fix_annotate) - # map to apply ops - data = data.map(input_columns=["image", "annotation"], - output_columns=["image", "annotation"], - columns_order=["image", "annotation"], - operations=[test_op]) # Add column for "annotation" + # maps to convert data into valid edge case data + dataVoc1 = dataVoc1.map(input_columns=["image", "annotation"], + output_columns=["image", "annotation"], + columns_order=["image", "annotation"], + operations=[lambda img, bboxes: ( + img, np.array([[0, 0, img.shape[1], img.shape[0]]]).astype(bboxes.dtype))]) - for _, _ in enumerate(data.create_dict_iterator()): - break + # Test Op added to list of Operations here + dataVoc2 = dataVoc2.map(input_columns=["image", "annotation"], + output_columns=["image", "annotation"], + columns_order=["image", "annotation"], + operations=[lambda img, bboxes: ( + img, np.array([[0, 0, img.shape[1], img.shape[0]]]).astype(bboxes.dtype)), test_op]) - except ValueError as e: - logger.info("Got an exception in DE: {}".format(str(e))) - assert "Input is not" in str(e) + unaugSamp, augSamp = [], [] - # zero target size as input - try: - test_op = c_vision.ResizeWithBBox(0) + for unAug, Aug in zip(dataVoc1.create_dict_iterator(), dataVoc2.create_dict_iterator()): + unaugSamp.append(unAug) + augSamp.append(Aug) - # map to apply ops - data = data.map(input_columns=["image", "annotation"], - output_columns=["image", "annotation"], - columns_order=["image", "annotation"], - operations=[test_op]) # Add column for "annotation" + if plot_vis: + visualize_with_bounding_boxes(unaugSamp, augSamp) - for _, _ in enumerate(data.create_dict_iterator()): - break - except ValueError as e: - logger.info("Got an exception in DE: {}".format(str(e))) - assert "Input is not" in str(e) +def test_resize_with_bbox_op_invalid_c(): + """ + Test ResizeWithBBox Op on invalid constructor parameters, expected to raise ValueError + """ + logger.info("test_resize_with_bbox_op_invalid_c") - # invalid input shape try: - test_op = c_vision.ResizeWithBBox((10, 10, 10)) + # invalid interpolation value + c_vision.ResizeWithBBox(400, interpolation="invalid") - # map to apply ops - data = data.map(input_columns=["image", "annotation"], - output_columns=["image", "annotation"], - columns_order=["image", "annotation"], - operations=[test_op]) # Add column for "annotation" + except ValueError as err: + logger.info("Got an exception in DE: {}".format(str(err))) + assert "interpolation" in str(err) - for _, _ in enumerate(data.create_dict_iterator()): - break - except TypeError as e: - logger.info("Got an exception in DE: {}".format(str(e))) - assert "Size should be" in str(e) - - -def test_resize_with_bbox_invalid_interpolation(): +def test_resize_with_bbox_op_bad_c(): """ - Test resize_with_bbox_op - """ - logger.info("Test resize with bbox with invalid interpolation size") - - # original images - data = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", decode=True, shuffle=False) - - data = data.map(input_columns=["annotation"], - output_columns=["annotation"], - operations=fix_annotate) - - # invalid interpolation - try: - test_op = c_vision.ResizeWithBBox(100, interpolation="invalid") - - # map to apply ops - data = data.map(input_columns=["image", "annotation"], - output_columns=["image", "annotation"], - columns_order=["image", "annotation"], - operations=[test_op]) # Add column for "annotation" + Tests ResizeWithBBox Op with invalid bounding boxes, expected to catch multiple errors + """ + logger.info("test_resize_with_bbox_op_bad_c") + test_op = c_vision.ResizeWithBBox((200, 300)) - for _, _ in enumerate(data.create_dict_iterator()): - break + data_voc2 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", decode=True, shuffle=False) + check_bad_bbox(data_voc2, test_op, InvalidBBoxType.WidthOverflow, "bounding boxes is out of bounds of the image") + data_voc2 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", decode=True, shuffle=False) + check_bad_bbox(data_voc2, test_op, InvalidBBoxType.HeightOverflow, "bounding boxes is out of bounds of the image") + data_voc2 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", decode=True, shuffle=False) + check_bad_bbox(data_voc2, test_op, InvalidBBoxType.NegativeXY, "min_x") + data_voc2 = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", decode=True, shuffle=False) + check_bad_bbox(data_voc2, test_op, InvalidBBoxType.WrongShape, "4 features") - except ValueError as e: - logger.info("Got an exception in DE: {}".format(str(e))) - assert "interpolation" in str(e) if __name__ == "__main__": - test_resize_with_bbox_op(plot=False) - test_resize_with_bbox_invalid_bounds() - test_resize_with_bbox_invalid_size() - test_resize_with_bbox_invalid_interpolation() + test_resize_with_bbox_op_c(plot_vis=False) + test_resize_with_bbox_op_edge_c(plot_vis=False) + test_resize_with_bbox_op_invalid_c() + test_resize_with_bbox_op_bad_c()