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 RandomAffine op in DE 17""" 18import numpy as np 19import mindspore.dataset as ds 20import mindspore.dataset.transforms.py_transforms 21import mindspore.dataset.vision.py_transforms as py_vision 22import mindspore.dataset.vision.c_transforms as c_vision 23from mindspore import log as logger 24from util import visualize_list, save_and_check_md5, \ 25 config_get_set_seed, config_get_set_num_parallel_workers 26 27GENERATE_GOLDEN = False 28 29DATA_DIR = ["../data/dataset/test_tf_file_3_images/train-0000-of-0001.data"] 30SCHEMA_DIR = "../data/dataset/test_tf_file_3_images/datasetSchema.json" 31MNIST_DATA_DIR = "../data/dataset/testMnistData" 32 33 34def test_random_affine_op(plot=False): 35 """ 36 Test RandomAffine in python transformations 37 """ 38 logger.info("test_random_affine_op") 39 # define map operations 40 transforms1 = [ 41 py_vision.Decode(), 42 py_vision.RandomAffine(degrees=15, translate=(0.1, 0.1), scale=(0.9, 1.1)), 43 py_vision.ToTensor() 44 ] 45 transform1 = mindspore.dataset.transforms.py_transforms.Compose(transforms1) 46 47 transforms2 = [ 48 py_vision.Decode(), 49 py_vision.ToTensor() 50 ] 51 transform2 = mindspore.dataset.transforms.py_transforms.Compose(transforms2) 52 53 # First dataset 54 data1 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False) 55 data1 = data1.map(operations=transform1, input_columns=["image"]) 56 # Second dataset 57 data2 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False) 58 data2 = data2.map(operations=transform2, input_columns=["image"]) 59 60 image_affine = [] 61 image_original = [] 62 for item1, item2 in zip(data1.create_dict_iterator(num_epochs=1, output_numpy=True), 63 data2.create_dict_iterator(num_epochs=1, output_numpy=True)): 64 image1 = (item1["image"].transpose(1, 2, 0) * 255).astype(np.uint8) 65 image2 = (item2["image"].transpose(1, 2, 0) * 255).astype(np.uint8) 66 image_affine.append(image1) 67 image_original.append(image2) 68 if plot: 69 visualize_list(image_original, image_affine) 70 71 72def test_random_affine_op_c(plot=False): 73 """ 74 Test RandomAffine in C transformations 75 """ 76 logger.info("test_random_affine_op_c") 77 # define map operations 78 transforms1 = [ 79 c_vision.Decode(), 80 c_vision.RandomAffine(degrees=0, translate=(0.5, 0.5, 0, 0)) 81 ] 82 83 transforms2 = [ 84 c_vision.Decode() 85 ] 86 87 # First dataset 88 data1 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False) 89 data1 = data1.map(operations=transforms1, input_columns=["image"]) 90 # Second dataset 91 data2 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False) 92 data2 = data2.map(operations=transforms2, input_columns=["image"]) 93 94 image_affine = [] 95 image_original = [] 96 for item1, item2 in zip(data1.create_dict_iterator(num_epochs=1, output_numpy=True), 97 data2.create_dict_iterator(num_epochs=1, output_numpy=True)): 98 image1 = item1["image"] 99 image2 = item2["image"] 100 image_affine.append(image1) 101 image_original.append(image2) 102 if plot: 103 visualize_list(image_original, image_affine) 104 105 106def test_random_affine_md5(): 107 """ 108 Test RandomAffine with md5 comparison 109 """ 110 logger.info("test_random_affine_md5") 111 original_seed = config_get_set_seed(55) 112 original_num_parallel_workers = config_get_set_num_parallel_workers(1) 113 # define map operations 114 transforms = [ 115 py_vision.Decode(), 116 py_vision.RandomAffine(degrees=(-5, 15), translate=(0.1, 0.3), 117 scale=(0.9, 1.1), shear=(-10, 10, -5, 5)), 118 py_vision.ToTensor() 119 ] 120 transform = mindspore.dataset.transforms.py_transforms.Compose(transforms) 121 122 # Generate dataset 123 data = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False) 124 data = data.map(operations=transform, input_columns=["image"]) 125 126 # check results with md5 comparison 127 filename = "random_affine_01_result.npz" 128 save_and_check_md5(data, filename, generate_golden=GENERATE_GOLDEN) 129 130 # Restore configuration 131 ds.config.set_seed(original_seed) 132 ds.config.set_num_parallel_workers((original_num_parallel_workers)) 133 134 135def test_random_affine_c_md5(): 136 """ 137 Test RandomAffine C Op with md5 comparison 138 """ 139 logger.info("test_random_affine_c_md5") 140 original_seed = config_get_set_seed(1) 141 original_num_parallel_workers = config_get_set_num_parallel_workers(1) 142 # define map operations 143 transforms = [ 144 c_vision.Decode(), 145 c_vision.RandomAffine(degrees=(-5, 15), translate=(-0.1, 0.1, -0.3, 0.3), 146 scale=(0.9, 1.1), shear=(-10, 10, -5, 5)) 147 ] 148 149 # Generate dataset 150 data = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False) 151 data = data.map(operations=transforms, input_columns=["image"]) 152 153 # check results with md5 comparison 154 filename = "random_affine_01_c_result.npz" 155 save_and_check_md5(data, filename, generate_golden=GENERATE_GOLDEN) 156 157 # Restore configuration 158 ds.config.set_seed(original_seed) 159 ds.config.set_num_parallel_workers((original_num_parallel_workers)) 160 161 162def test_random_affine_default_c_md5(): 163 """ 164 Test RandomAffine C Op (default params) with md5 comparison 165 """ 166 logger.info("test_random_affine_default_c_md5") 167 original_seed = config_get_set_seed(1) 168 original_num_parallel_workers = config_get_set_num_parallel_workers(1) 169 # define map operations 170 transforms = [ 171 c_vision.Decode(), 172 c_vision.RandomAffine(degrees=0) 173 ] 174 175 # Generate dataset 176 data = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False) 177 data = data.map(operations=transforms, input_columns=["image"]) 178 179 # check results with md5 comparison 180 filename = "random_affine_01_default_c_result.npz" 181 save_and_check_md5(data, filename, generate_golden=GENERATE_GOLDEN) 182 183 # Restore configuration 184 ds.config.set_seed(original_seed) 185 ds.config.set_num_parallel_workers((original_num_parallel_workers)) 186 187 188def test_random_affine_py_exception_non_pil_images(): 189 """ 190 Test RandomAffine: input img is ndarray and not PIL, expected to raise RuntimeError 191 """ 192 logger.info("test_random_affine_exception_negative_degrees") 193 dataset = ds.MnistDataset(MNIST_DATA_DIR, num_samples=3, num_parallel_workers=3) 194 try: 195 transform = mindspore.dataset.transforms.py_transforms.Compose([py_vision.ToTensor(), 196 py_vision.RandomAffine(degrees=(15, 15))]) 197 dataset = dataset.map(operations=transform, input_columns=["image"], num_parallel_workers=3) 198 for _ in dataset.create_dict_iterator(num_epochs=1): 199 pass 200 except RuntimeError as e: 201 logger.info("Got an exception in DE: {}".format(str(e))) 202 assert "Pillow image" in str(e) 203 204 205def test_random_affine_exception_negative_degrees(): 206 """ 207 Test RandomAffine: input degrees in negative, expected to raise ValueError 208 """ 209 logger.info("test_random_affine_exception_negative_degrees") 210 try: 211 _ = py_vision.RandomAffine(degrees=-15) 212 except ValueError as e: 213 logger.info("Got an exception in DE: {}".format(str(e))) 214 assert str(e) == "Input degrees is not within the required interval of [0, 16777216]." 215 216 217def test_random_affine_exception_translation_range(): 218 """ 219 Test RandomAffine: translation value is not in [-1, 1], expected to raise ValueError 220 """ 221 logger.info("test_random_affine_exception_translation_range") 222 try: 223 _ = c_vision.RandomAffine(degrees=15, translate=(0.1, 1.5)) 224 except ValueError as e: 225 logger.info("Got an exception in DE: {}".format(str(e))) 226 assert str(e) == "Input translate at 1 is not within the required interval of [-1.0, 1.0]." 227 logger.info("test_random_affine_exception_translation_range") 228 try: 229 _ = c_vision.RandomAffine(degrees=15, translate=(-2, 1.5)) 230 except ValueError as e: 231 logger.info("Got an exception in DE: {}".format(str(e))) 232 assert str(e) == "Input translate at 0 is not within the required interval of [-1.0, 1.0]." 233 234 235def test_random_affine_exception_scale_value(): 236 """ 237 Test RandomAffine: scale is not valid, expected to raise ValueError 238 """ 239 logger.info("test_random_affine_exception_scale_value") 240 try: 241 _ = py_vision.RandomAffine(degrees=15, scale=(0.0, 0.0)) 242 except ValueError as e: 243 logger.info("Got an exception in DE: {}".format(str(e))) 244 assert str(e) == "Input scale[1] must be greater than 0." 245 246 try: 247 _ = py_vision.RandomAffine(degrees=15, scale=(2.0, 1.1)) 248 except ValueError as e: 249 logger.info("Got an exception in DE: {}".format(str(e))) 250 assert str(e) == "Input scale[1] must be equal to or greater than scale[0]." 251 252 253def test_random_affine_exception_shear_value(): 254 """ 255 Test RandomAffine: shear is a number but is not positive, expected to raise ValueError 256 """ 257 logger.info("test_random_affine_exception_shear_value") 258 try: 259 _ = py_vision.RandomAffine(degrees=15, shear=-5) 260 except ValueError as e: 261 logger.info("Got an exception in DE: {}".format(str(e))) 262 assert str(e) == "Input shear must be greater than 0." 263 264 try: 265 _ = py_vision.RandomAffine(degrees=15, shear=(5, 1)) 266 except ValueError as e: 267 logger.info("Got an exception in DE: {}".format(str(e))) 268 assert str(e) == "Input shear[1] must be equal to or greater than shear[0]" 269 270 try: 271 _ = py_vision.RandomAffine(degrees=15, shear=(5, 1, 2, 8)) 272 except ValueError as e: 273 logger.info("Got an exception in DE: {}".format(str(e))) 274 assert str(e) == "Input shear[1] must be equal to or greater than shear[0] and " \ 275 "shear[3] must be equal to or greater than shear[2]." 276 277 try: 278 _ = py_vision.RandomAffine(degrees=15, shear=(5, 9, 2, 1)) 279 except ValueError as e: 280 logger.info("Got an exception in DE: {}".format(str(e))) 281 assert str(e) == "Input shear[1] must be equal to or greater than shear[0] and " \ 282 "shear[3] must be equal to or greater than shear[2]." 283 284 285def test_random_affine_exception_degrees_size(): 286 """ 287 Test RandomAffine: degrees is a list or tuple and its length is not 2, 288 expected to raise TypeError 289 """ 290 logger.info("test_random_affine_exception_degrees_size") 291 try: 292 _ = py_vision.RandomAffine(degrees=[15]) 293 except TypeError as e: 294 logger.info("Got an exception in DE: {}".format(str(e))) 295 assert str(e) == "If degrees is a sequence, the length must be 2." 296 297 298def test_random_affine_exception_translate_size(): 299 """ 300 Test RandomAffine: translate is not list or a tuple of length 2, 301 expected to raise TypeError 302 """ 303 logger.info("test_random_affine_exception_translate_size") 304 try: 305 _ = py_vision.RandomAffine(degrees=15, translate=(0.1)) 306 except TypeError as e: 307 logger.info("Got an exception in DE: {}".format(str(e))) 308 assert str( 309 e) == "Argument translate with value 0.1 is not of type [<class 'list'>," \ 310 " <class 'tuple'>], but got <class 'float'>." 311 312 313def test_random_affine_exception_scale_size(): 314 """ 315 Test RandomAffine: scale is not a list or tuple of length 2, 316 expected to raise TypeError 317 """ 318 logger.info("test_random_affine_exception_scale_size") 319 try: 320 _ = py_vision.RandomAffine(degrees=15, scale=(0.5)) 321 except TypeError as e: 322 logger.info("Got an exception in DE: {}".format(str(e))) 323 assert str(e) == "Argument scale with value 0.5 is not of type [<class 'tuple'>," \ 324 " <class 'list'>], but got <class 'float'>." 325 326 327def test_random_affine_exception_shear_size(): 328 """ 329 Test RandomAffine: shear is not a list or tuple of length 2 or 4, 330 expected to raise TypeError 331 """ 332 logger.info("test_random_affine_exception_shear_size") 333 try: 334 _ = py_vision.RandomAffine(degrees=15, shear=(-5, 5, 10)) 335 except TypeError as e: 336 logger.info("Got an exception in DE: {}".format(str(e))) 337 assert str(e) == "shear must be of length 2 or 4." 338 339 340if __name__ == "__main__": 341 test_random_affine_op(plot=True) 342 test_random_affine_op_c(plot=True) 343 test_random_affine_md5() 344 test_random_affine_c_md5() 345 test_random_affine_default_c_md5() 346 test_random_affine_py_exception_non_pil_images() 347 test_random_affine_exception_negative_degrees() 348 test_random_affine_exception_translation_range() 349 test_random_affine_exception_scale_value() 350 test_random_affine_exception_shear_value() 351 test_random_affine_exception_degrees_size() 352 test_random_affine_exception_translate_size() 353 test_random_affine_exception_scale_size() 354 test_random_affine_exception_shear_size() 355