• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2020 Huawei Technologies Co., Ltd
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14# ==============================================================================
15"""
16Testing the bounding box augment op in DE
17"""
18
19import numpy as np
20import mindspore.log as logger
21import mindspore.dataset as ds
22import mindspore.dataset.vision.c_transforms as c_vision
23
24from util import visualize_with_bounding_boxes, InvalidBBoxType, check_bad_bbox, \
25    config_get_set_seed, config_get_set_num_parallel_workers, save_and_check_md5
26
27GENERATE_GOLDEN = False
28
29# updated VOC dataset with correct annotations
30DATA_DIR = "../data/dataset/testVOC2012_2"
31DATA_DIR_2 = ["../data/dataset/testCOCO/train/",
32              "../data/dataset/testCOCO/annotations/train.json"]  # DATA_DIR, ANNOTATION_DIR
33
34
35def test_bounding_box_augment_with_rotation_op(plot_vis=False):
36    """
37    Test BoundingBoxAugment op (passing rotation op as transform)
38    Prints images side by side with and without Aug applied + bboxes to compare and test
39    """
40    logger.info("test_bounding_box_augment_with_rotation_op")
41
42    original_seed = config_get_set_seed(0)
43    original_num_parallel_workers = config_get_set_num_parallel_workers(1)
44
45    dataVoc1 = ds.VOCDataset(DATA_DIR, task="Detection", usage="train", shuffle=False, decode=True)
46    dataVoc2 = ds.VOCDataset(DATA_DIR, task="Detection", usage="train", shuffle=False, decode=True)
47
48    # Ratio is set to 1 to apply rotation on all bounding boxes.
49    test_op = c_vision.BoundingBoxAugment(c_vision.RandomRotation(90), 1)
50
51    # map to apply ops
52    dataVoc2 = dataVoc2.map(operations=[test_op], input_columns=["image", "bbox"],
53                            output_columns=["image", "bbox"],
54                            column_order=["image", "bbox"])
55
56    filename = "bounding_box_augment_rotation_c_result.npz"
57    save_and_check_md5(dataVoc2, filename, generate_golden=GENERATE_GOLDEN)
58
59    unaugSamp, augSamp = [], []
60
61    for unAug, Aug in zip(dataVoc1.create_dict_iterator(num_epochs=1, output_numpy=True),
62                          dataVoc2.create_dict_iterator(num_epochs=1, output_numpy=True)):
63        unaugSamp.append(unAug)
64        augSamp.append(Aug)
65
66    if plot_vis:
67        visualize_with_bounding_boxes(unaugSamp, augSamp)
68
69    # Restore config setting
70    ds.config.set_seed(original_seed)
71    ds.config.set_num_parallel_workers(original_num_parallel_workers)
72
73
74def test_bounding_box_augment_with_crop_op(plot_vis=False):
75    """
76    Test BoundingBoxAugment op (passing crop op as transform)
77    Prints images side by side with and without Aug applied + bboxes to compare and test
78    """
79    logger.info("test_bounding_box_augment_with_crop_op")
80
81    original_seed = config_get_set_seed(0)
82    original_num_parallel_workers = config_get_set_num_parallel_workers(1)
83
84    dataVoc1 = ds.VOCDataset(DATA_DIR, task="Detection", usage="train", shuffle=False, decode=True)
85    dataVoc2 = ds.VOCDataset(DATA_DIR, task="Detection", usage="train", shuffle=False, decode=True)
86
87    # Ratio is set to 0.9 to apply RandomCrop of size (50, 50) on 90% of the bounding boxes.
88    test_op = c_vision.BoundingBoxAugment(c_vision.RandomCrop(50), 0.9)
89
90    # map to apply ops
91    dataVoc2 = dataVoc2.map(operations=[test_op], input_columns=["image", "bbox"],
92                            output_columns=["image", "bbox"],
93                            column_order=["image", "bbox"])
94
95    filename = "bounding_box_augment_crop_c_result.npz"
96    save_and_check_md5(dataVoc2, filename, generate_golden=GENERATE_GOLDEN)
97
98    unaugSamp, augSamp = [], []
99
100    for unAug, Aug in zip(dataVoc1.create_dict_iterator(num_epochs=1, output_numpy=True),
101                          dataVoc2.create_dict_iterator(num_epochs=1, output_numpy=True)):
102        unaugSamp.append(unAug)
103        augSamp.append(Aug)
104
105    if plot_vis:
106        visualize_with_bounding_boxes(unaugSamp, augSamp)
107
108    # Restore config setting
109    ds.config.set_seed(original_seed)
110    ds.config.set_num_parallel_workers(original_num_parallel_workers)
111
112
113def test_bounding_box_augment_valid_ratio_c(plot_vis=False):
114    """
115    Test BoundingBoxAugment op (testing with valid ratio, less than 1.
116    Prints images side by side with and without Aug applied + bboxes to compare and test
117    """
118    logger.info("test_bounding_box_augment_valid_ratio_c")
119
120    original_seed = config_get_set_seed(1)
121    original_num_parallel_workers = config_get_set_num_parallel_workers(1)
122
123    dataVoc1 = ds.VOCDataset(DATA_DIR, task="Detection", usage="train", shuffle=False, decode=True)
124    dataVoc2 = ds.VOCDataset(DATA_DIR, task="Detection", usage="train", shuffle=False, decode=True)
125
126    test_op = c_vision.BoundingBoxAugment(c_vision.RandomHorizontalFlip(1), 0.9)
127
128    # map to apply ops
129    dataVoc2 = dataVoc2.map(operations=[test_op], input_columns=["image", "bbox"],
130                            output_columns=["image", "bbox"],
131                            column_order=["image", "bbox"])  # Add column for "bbox"
132
133    filename = "bounding_box_augment_valid_ratio_c_result.npz"
134    save_and_check_md5(dataVoc2, filename, generate_golden=GENERATE_GOLDEN)
135
136    unaugSamp, augSamp = [], []
137
138    for unAug, Aug in zip(dataVoc1.create_dict_iterator(num_epochs=1, output_numpy=True),
139                          dataVoc2.create_dict_iterator(num_epochs=1, output_numpy=True)):
140        unaugSamp.append(unAug)
141        augSamp.append(Aug)
142
143    if plot_vis:
144        visualize_with_bounding_boxes(unaugSamp, augSamp)
145
146    # Restore config setting
147    ds.config.set_seed(original_seed)
148    ds.config.set_num_parallel_workers(original_num_parallel_workers)
149
150
151def test_bounding_box_augment_op_coco_c(plot_vis=False):
152    """
153    Prints images and bboxes side by side with and without BoundingBoxAugment Op applied,
154    Testing with COCO dataset
155    """
156    logger.info("test_bounding_box_augment_op_coco_c")
157
158    dataCoco1 = ds.CocoDataset(DATA_DIR_2[0], annotation_file=DATA_DIR_2[1], task="Detection",
159                               decode=True, shuffle=False)
160
161    dataCoco2 = ds.CocoDataset(DATA_DIR_2[0], annotation_file=DATA_DIR_2[1], task="Detection",
162                               decode=True, shuffle=False)
163
164    test_op = c_vision.BoundingBoxAugment(c_vision.RandomHorizontalFlip(1), 1)
165
166    dataCoco2 = dataCoco2.map(operations=[test_op], input_columns=["image", "bbox"],
167                              output_columns=["image", "bbox"],
168                              column_order=["image", "bbox"])
169
170    unaugSamp, augSamp = [], []
171
172    for unAug, Aug in zip(dataCoco1.create_dict_iterator(num_epochs=1, output_numpy=True),
173                          dataCoco2.create_dict_iterator(num_epochs=1, output_numpy=True)):
174        unaugSamp.append(unAug)
175        augSamp.append(Aug)
176
177    if plot_vis:
178        visualize_with_bounding_boxes(unaugSamp, augSamp, "bbox")
179
180
181def test_bounding_box_augment_valid_edge_c(plot_vis=False):
182    """
183    Test BoundingBoxAugment op (testing with valid edge case, box covering full image).
184    Prints images side by side with and without Aug applied + bboxes to compare and test
185    """
186    logger.info("test_bounding_box_augment_valid_edge_c")
187
188    original_seed = config_get_set_seed(1)
189    original_num_parallel_workers = config_get_set_num_parallel_workers(1)
190
191    dataVoc1 = ds.VOCDataset(DATA_DIR, task="Detection", usage="train", shuffle=False, decode=True)
192    dataVoc2 = ds.VOCDataset(DATA_DIR, task="Detection", usage="train", shuffle=False, decode=True)
193
194    test_op = c_vision.BoundingBoxAugment(c_vision.RandomHorizontalFlip(1), 1)
195
196    # map to apply ops
197    # Add column for "bbox"
198    dataVoc1 = dataVoc1.map(
199        operations=lambda img, bbox: (img, np.array([[0, 0, img.shape[1], img.shape[0], 0, 0, 0]]).astype(np.float32)),
200        input_columns=["image", "bbox"],
201        output_columns=["image", "bbox"],
202        column_order=["image", "bbox"])
203    dataVoc2 = dataVoc2.map(
204        operations=lambda img, bbox: (img, np.array([[0, 0, img.shape[1], img.shape[0], 0, 0, 0]]).astype(np.float32)),
205        input_columns=["image", "bbox"],
206        output_columns=["image", "bbox"],
207        column_order=["image", "bbox"])
208    dataVoc2 = dataVoc2.map(operations=[test_op], input_columns=["image", "bbox"],
209                            output_columns=["image", "bbox"],
210                            column_order=["image", "bbox"])
211    filename = "bounding_box_augment_valid_edge_c_result.npz"
212    save_and_check_md5(dataVoc2, filename, generate_golden=GENERATE_GOLDEN)
213
214    unaugSamp, augSamp = [], []
215
216    for unAug, Aug in zip(dataVoc1.create_dict_iterator(num_epochs=1, output_numpy=True),
217                          dataVoc2.create_dict_iterator(num_epochs=1, output_numpy=True)):
218        unaugSamp.append(unAug)
219        augSamp.append(Aug)
220
221    if plot_vis:
222        visualize_with_bounding_boxes(unaugSamp, augSamp)
223
224    # Restore config setting
225    ds.config.set_seed(original_seed)
226    ds.config.set_num_parallel_workers(original_num_parallel_workers)
227
228
229def test_bounding_box_augment_invalid_ratio_c():
230    """
231    Test BoundingBoxAugment op with invalid input ratio
232    """
233    logger.info("test_bounding_box_augment_invalid_ratio_c")
234
235    dataVoc2 = ds.VOCDataset(DATA_DIR, task="Detection", usage="train", shuffle=False, decode=True)
236
237    try:
238        # ratio range is from 0 - 1
239        test_op = c_vision.BoundingBoxAugment(c_vision.RandomHorizontalFlip(1), 1.5)
240        # map to apply ops
241        dataVoc2 = dataVoc2.map(operations=[test_op], input_columns=["image", "bbox"],
242                                output_columns=["image", "bbox"],
243                                column_order=["image", "bbox"])  # Add column for "bbox"
244    except ValueError as error:
245        logger.info("Got an exception in DE: {}".format(str(error)))
246        assert "Input ratio is not within the required interval of [0.0, 1.0]." in str(error)
247
248
249def test_bounding_box_augment_invalid_bounds_c():
250    """
251    Test BoundingBoxAugment op with invalid bboxes.
252    """
253    logger.info("test_bounding_box_augment_invalid_bounds_c")
254
255    test_op = c_vision.BoundingBoxAugment(c_vision.RandomHorizontalFlip(1),
256                                          1)
257
258    dataVoc2 = ds.VOCDataset(DATA_DIR, task="Detection", usage="train", shuffle=False, decode=True)
259    check_bad_bbox(dataVoc2, test_op, InvalidBBoxType.WidthOverflow, "bounding boxes is out of bounds of the image")
260    dataVoc2 = ds.VOCDataset(DATA_DIR, task="Detection", usage="train", shuffle=False, decode=True)
261    check_bad_bbox(dataVoc2, test_op, InvalidBBoxType.HeightOverflow, "bounding boxes is out of bounds of the image")
262    dataVoc2 = ds.VOCDataset(DATA_DIR, task="Detection", usage="train", shuffle=False, decode=True)
263    check_bad_bbox(dataVoc2, test_op, InvalidBBoxType.NegativeXY, "negative value")
264    dataVoc2 = ds.VOCDataset(DATA_DIR, task="Detection", usage="train", shuffle=False, decode=True)
265    check_bad_bbox(dataVoc2, test_op, InvalidBBoxType.WrongShape, "4 features")
266
267
268if __name__ == "__main__":
269    # set to false to not show plots
270    test_bounding_box_augment_with_rotation_op(plot_vis=False)
271    test_bounding_box_augment_with_crop_op(plot_vis=False)
272    test_bounding_box_augment_op_coco_c(plot_vis=False)
273    test_bounding_box_augment_valid_ratio_c(plot_vis=False)
274    test_bounding_box_augment_valid_edge_c(plot_vis=False)
275    test_bounding_box_augment_invalid_ratio_c()
276    test_bounding_box_augment_invalid_bounds_c()
277