1# Copyright 2019 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 RandomRotation op in DE 17""" 18import numpy as np 19import cv2 20 21import mindspore.dataset as ds 22import mindspore.dataset.transforms.py_transforms 23import mindspore.dataset.vision.c_transforms as c_vision 24import mindspore.dataset.vision.py_transforms as py_vision 25from mindspore.dataset.vision.utils import Inter 26from mindspore import log as logger 27from util import visualize_image, visualize_list, diff_mse, save_and_check_md5, \ 28 config_get_set_seed, config_get_set_num_parallel_workers 29 30DATA_DIR = ["../data/dataset/test_tf_file_3_images/train-0000-of-0001.data"] 31SCHEMA_DIR = "../data/dataset/test_tf_file_3_images/datasetSchema.json" 32 33GENERATE_GOLDEN = False 34 35 36def test_random_rotation_op_c(plot=False): 37 """ 38 Test RandomRotation in c++ transformations op 39 """ 40 logger.info("test_random_rotation_op_c") 41 42 # First dataset 43 data1 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, shuffle=False) 44 decode_op = c_vision.Decode() 45 # use [90, 90] to force rotate 90 degrees, expand is set to be True to match output size 46 random_rotation_op = c_vision.RandomRotation((90, 90), expand=True) 47 data1 = data1.map(operations=decode_op, input_columns=["image"]) 48 data1 = data1.map(operations=random_rotation_op, input_columns=["image"]) 49 50 # Second dataset 51 data2 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False) 52 data2 = data2.map(operations=decode_op, input_columns=["image"]) 53 54 num_iter = 0 55 for item1, item2 in zip(data1.create_dict_iterator(num_epochs=1, output_numpy=True), 56 data2.create_dict_iterator(num_epochs=1, output_numpy=True)): 57 if num_iter > 0: 58 break 59 rotation_de = item1["image"] 60 original = item2["image"] 61 logger.info("shape before rotate: {}".format(original.shape)) 62 rotation_cv = cv2.rotate(original, cv2.ROTATE_90_COUNTERCLOCKWISE) 63 mse = diff_mse(rotation_de, rotation_cv) 64 logger.info("random_rotation_op_{}, mse: {}".format(num_iter + 1, mse)) 65 assert mse == 0 66 num_iter += 1 67 if plot: 68 visualize_image(original, rotation_de, mse, rotation_cv) 69 70 71def test_random_rotation_op_py(plot=False): 72 """ 73 Test RandomRotation in python transformations op 74 """ 75 logger.info("test_random_rotation_op_py") 76 77 # First dataset 78 data1 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, shuffle=False) 79 # use [90, 90] to force rotate 90 degrees, expand is set to be True to match output size 80 transform1 = mindspore.dataset.transforms.py_transforms.Compose([py_vision.Decode(), 81 py_vision.RandomRotation((90, 90), expand=True), 82 py_vision.ToTensor()]) 83 data1 = data1.map(operations=transform1, input_columns=["image"]) 84 85 # Second dataset 86 data2 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False) 87 transform2 = mindspore.dataset.transforms.py_transforms.Compose([py_vision.Decode(), 88 py_vision.ToTensor()]) 89 data2 = data2.map(operations=transform2, input_columns=["image"]) 90 91 num_iter = 0 92 for item1, item2 in zip(data1.create_dict_iterator(num_epochs=1, output_numpy=True), 93 data2.create_dict_iterator(num_epochs=1, output_numpy=True)): 94 if num_iter > 0: 95 break 96 rotation_de = (item1["image"].transpose(1, 2, 0) * 255).astype(np.uint8) 97 original = (item2["image"].transpose(1, 2, 0) * 255).astype(np.uint8) 98 logger.info("shape before rotate: {}".format(original.shape)) 99 rotation_cv = cv2.rotate(original, cv2.ROTATE_90_COUNTERCLOCKWISE) 100 mse = diff_mse(rotation_de, rotation_cv) 101 logger.info("random_rotation_op_{}, mse: {}".format(num_iter + 1, mse)) 102 assert mse == 0 103 num_iter += 1 104 if plot: 105 visualize_image(original, rotation_de, mse, rotation_cv) 106 107def test_random_rotation_op_py_ANTIALIAS(): 108 """ 109 Test RandomRotation in python transformations op 110 """ 111 logger.info("test_random_rotation_op_py_ANTIALIAS") 112 113 # First dataset 114 data1 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, shuffle=False) 115 # use [90, 90] to force rotate 90 degrees, expand is set to be True to match output size 116 transform1 = mindspore.dataset.transforms.py_transforms.Compose([py_vision.Decode(), 117 py_vision.RandomRotation((90, 90), 118 expand=True, 119 resample=Inter.ANTIALIAS), 120 py_vision.ToTensor()]) 121 data1 = data1.map(operations=transform1, input_columns=["image"]) 122 123 num_iter = 0 124 for _ in data1.create_dict_iterator(num_epochs=1, output_numpy=True): 125 num_iter += 1 126 logger.info("use RandomRotation by Inter.ANTIALIAS process {} images.".format(num_iter)) 127 128def test_random_rotation_expand(): 129 """ 130 Test RandomRotation op 131 """ 132 logger.info("test_random_rotation_op") 133 134 # First dataset 135 data1 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False) 136 decode_op = c_vision.Decode() 137 # expand is set to be True to match output size 138 random_rotation_op = c_vision.RandomRotation((0, 90), expand=True) 139 data1 = data1.map(operations=decode_op, input_columns=["image"]) 140 data1 = data1.map(operations=random_rotation_op, input_columns=["image"]) 141 142 num_iter = 0 143 for item in data1.create_dict_iterator(num_epochs=1): 144 rotation = item["image"] 145 logger.info("shape after rotate: {}".format(rotation.shape)) 146 num_iter += 1 147 148 149def test_random_rotation_md5(): 150 """ 151 Test RandomRotation with md5 check 152 """ 153 logger.info("Test RandomRotation with md5 check") 154 original_seed = config_get_set_seed(5) 155 original_num_parallel_workers = config_get_set_num_parallel_workers(1) 156 157 # First dataset 158 data1 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False) 159 decode_op = c_vision.Decode() 160 resize_op = c_vision.RandomRotation((0, 90), 161 expand=True, 162 resample=Inter.BILINEAR, 163 center=(50, 50), 164 fill_value=150) 165 data1 = data1.map(operations=decode_op, input_columns=["image"]) 166 data1 = data1.map(operations=resize_op, input_columns=["image"]) 167 168 # Second dataset 169 data2 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, shuffle=False) 170 transform2 = mindspore.dataset.transforms.py_transforms.Compose([py_vision.Decode(), 171 py_vision.RandomRotation((0, 90), 172 expand=True, 173 resample=Inter.BILINEAR, 174 center=(50, 50), 175 fill_value=150), 176 py_vision.ToTensor()]) 177 data2 = data2.map(operations=transform2, input_columns=["image"]) 178 179 # Compare with expected md5 from images 180 filename1 = "random_rotation_01_c_result.npz" 181 save_and_check_md5(data1, filename1, generate_golden=GENERATE_GOLDEN) 182 filename2 = "random_rotation_01_py_result.npz" 183 save_and_check_md5(data2, filename2, generate_golden=GENERATE_GOLDEN) 184 185 # Restore configuration 186 ds.config.set_seed(original_seed) 187 ds.config.set_num_parallel_workers(original_num_parallel_workers) 188 189 190def test_rotation_diff(plot=False): 191 """ 192 Test RandomRotation op 193 """ 194 logger.info("test_random_rotation_op") 195 196 # First dataset 197 data1 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False) 198 decode_op = c_vision.Decode() 199 200 rotation_op = c_vision.RandomRotation((45, 45)) 201 ctrans = [decode_op, 202 rotation_op 203 ] 204 205 data1 = data1.map(operations=ctrans, input_columns=["image"]) 206 207 # Second dataset 208 transforms = [ 209 py_vision.Decode(), 210 py_vision.RandomRotation((45, 45)), 211 py_vision.ToTensor(), 212 ] 213 transform = mindspore.dataset.transforms.py_transforms.Compose(transforms) 214 data2 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False) 215 data2 = data2.map(operations=transform, input_columns=["image"]) 216 217 num_iter = 0 218 image_list_c, image_list_py = [], [] 219 for item1, item2 in zip(data1.create_dict_iterator(num_epochs=1, output_numpy=True), 220 data2.create_dict_iterator(num_epochs=1, output_numpy=True)): 221 num_iter += 1 222 c_image = item1["image"] 223 py_image = (item2["image"].transpose(1, 2, 0) * 255).astype(np.uint8) 224 image_list_c.append(c_image) 225 image_list_py.append(py_image) 226 227 logger.info("shape of c_image: {}".format(c_image.shape)) 228 logger.info("shape of py_image: {}".format(py_image.shape)) 229 230 logger.info("dtype of c_image: {}".format(c_image.dtype)) 231 logger.info("dtype of py_image: {}".format(py_image.dtype)) 232 233 mse = diff_mse(c_image, py_image) 234 assert mse < 0.001 # Rounding error 235 if plot: 236 visualize_list(image_list_c, image_list_py, visualize_mode=2) 237 238 239if __name__ == "__main__": 240 test_random_rotation_op_c(plot=True) 241 test_random_rotation_op_py(plot=True) 242 test_random_rotation_op_py_ANTIALIAS() 243 test_random_rotation_expand() 244 test_random_rotation_md5() 245 test_rotation_diff(plot=True) 246