diff --git a/mindspore/ccsrc/minddata/dataset/api/iterator.cc b/mindspore/ccsrc/minddata/dataset/api/iterator.cc index 096c91ec3b..4db49962f4 100644 --- a/mindspore/ccsrc/minddata/dataset/api/iterator.cc +++ b/mindspore/ccsrc/minddata/dataset/api/iterator.cc @@ -38,7 +38,6 @@ Status Iterator::GetNextRowCharIF(MSTensorMapChar *row) { return rc; } for (auto de_tensor : md_map) { - CHECK_FAIL_RETURN_UNEXPECTED(de_tensor.second->HasData(), "Apply transform failed, output tensor has no data"); std::vector col_name(de_tensor.first.begin(), de_tensor.first.end()); row->insert(std::make_pair(col_name, mindspore::MSTensor(std::make_shared(de_tensor.second)))); } @@ -57,10 +56,8 @@ Status Iterator::GetNextRow(MSTensorVec *row) { row->clear(); return rc; } - for (auto de_tensor : md_row) { - CHECK_FAIL_RETURN_UNEXPECTED(de_tensor->HasData(), "Apply transform failed, output tensor has no data"); - row->push_back(mindspore::MSTensor(std::make_shared(de_tensor))); - } + std::transform(md_row.begin(), md_row.end(), std::back_inserter(*row), + [](auto t) { return mindspore::MSTensor(std::make_shared(t)); }); return Status::OK(); } diff --git a/mindspore/ccsrc/minddata/dataset/include/vision.h b/mindspore/ccsrc/minddata/dataset/include/vision.h index 67439c7660..6b84f4216e 100644 --- a/mindspore/ccsrc/minddata/dataset/include/vision.h +++ b/mindspore/ccsrc/minddata/dataset/include/vision.h @@ -398,6 +398,7 @@ class RandomCropDecodeResize final : public TensorTransform { /// \brief RandomCropWithBBox TensorTransform. /// \notes Crop the input image at a random location and adjust bounding boxes accordingly. +/// If cropped area is out of bbox, the return bbox will be empty. class RandomCropWithBBox final : public TensorTransform { public: /// \brief Constructor. @@ -578,6 +579,7 @@ class RandomResizedCrop final : public TensorTransform { /// \brief RandomResizedCropWithBBox TensorTransform. /// \notes Crop the input image to a random size and aspect ratio. +/// If cropped area is out of bbox, the return bbox will be empty. class RandomResizedCropWithBBox final : public TensorTransform { public: /// \brief Constructor. diff --git a/mindspore/dataset/core/validator_helpers.py b/mindspore/dataset/core/validator_helpers.py index c4827f77d4..c80772b000 100644 --- a/mindspore/dataset/core/validator_helpers.py +++ b/mindspore/dataset/core/validator_helpers.py @@ -84,6 +84,14 @@ def check_value_cutoff(value, valid_range, arg_name=""): valid_range[1])) +def check_value_ratio(value, valid_range, arg_name=""): + arg_name = pad_arg_name(arg_name) + if value <= valid_range[0] or value > valid_range[1]: + raise ValueError( + "Input {0}is not within the required interval of ({1}, {2}].".format(arg_name, valid_range[0], + valid_range[1])) + + def check_value_normalize_std(value, valid_range, arg_name=""): arg_name = pad_arg_name(arg_name) if value <= valid_range[0] or value > valid_range[1]: diff --git a/mindspore/dataset/vision/py_transforms.py b/mindspore/dataset/vision/py_transforms.py index 4b0a7cb902..c6666a618f 100644 --- a/mindspore/dataset/vision/py_transforms.py +++ b/mindspore/dataset/vision/py_transforms.py @@ -974,7 +974,7 @@ class RandomErasing: """ Erase the pixels, within a selected rectangle region, to the given value. - Randomly applied on the input NumPy image array with a given probability. + Randomly applied on the input NumPy image array of shape (C, H, W) with a given probability. Zhun Zhong et al. 'Random Erasing Data Augmentation' 2017 See https://arxiv.org/pdf/1708.04896.pdf diff --git a/mindspore/dataset/vision/validators.py b/mindspore/dataset/vision/validators.py index efd5d0ad50..f3ee5d3ba7 100644 --- a/mindspore/dataset/vision/validators.py +++ b/mindspore/dataset/vision/validators.py @@ -21,7 +21,7 @@ from mindspore._c_dataengine import TensorOp, TensorOperation from mindspore.dataset.core.validator_helpers import check_value, check_uint8, FLOAT_MAX_INTEGER, check_pos_float32, \ check_float32, check_2tuple, check_range, check_positive, INT32_MAX, parse_user_args, type_check, type_check_list, \ - check_c_tensor_op, UINT8_MAX, check_value_normalize_std, check_value_cutoff + check_c_tensor_op, UINT8_MAX, check_value_normalize_std, check_value_cutoff, check_value_ratio from .utils import Inter, Border, ImageBatchFormat @@ -153,7 +153,8 @@ def check_random_color_adjust_param(value, input_name, center=1, bound=(0, FLOAT def check_erasing_value(value): - if not (isinstance(value, (numbers.Number, str, bytes)) or + if not (isinstance(value, (numbers.Number,)) or + (isinstance(value, (str,)) and value == 'random') or (isinstance(value, (tuple, list)) and len(value) == 3)): raise ValueError("The value for erasing should be either a single value, " "or a string 'random', or a sequence of 3 elements for RGB respectively.") @@ -479,6 +480,18 @@ def check_random_erasing(method): def new_method(self, *args, **kwargs): [prob, scale, ratio, value, inplace, max_attempts], _ = parse_user_args(method, *args, **kwargs) + type_check(prob, (float, int,), "prob") + type_check_list(scale, (float, int,), "scale") + if len(scale) != 2: + raise TypeError("scale should be a list or tuple of length 2.") + type_check_list(ratio, (float, int,), "ratio") + if len(ratio) != 2: + raise TypeError("ratio should be a list or tuple of length 2.") + type_check(value, (int, list, tuple, str), "value") + type_check(inplace, (bool,), "inplace") + type_check(max_attempts, (int,), "max_attempts") + check_erasing_value(value) + check_value(prob, [0., 1.], "prob") if scale[0] > scale[1]: raise ValueError("scale should be in (min,max) format. Got (max,min).") @@ -486,11 +499,14 @@ def check_random_erasing(method): check_positive(scale[1], "scale[1]") if ratio[0] > ratio[1]: raise ValueError("ratio should be in (min,max) format. Got (max,min).") - check_range(ratio, [0, FLOAT_MAX_INTEGER]) - check_positive(ratio[0], "ratio[0]") - check_positive(ratio[1], "ratio[1]") - check_erasing_value(value) - type_check(inplace, (bool,), "inplace") + check_value_ratio(ratio[0], [0, FLOAT_MAX_INTEGER]) + check_value_ratio(ratio[1], [0, FLOAT_MAX_INTEGER]) + if isinstance(value, int): + check_value(value, (0, 255)) + if isinstance(value, (list, tuple)): + for item in value: + type_check(item, (int,), "value") + check_value(item, [0, 255], "value") check_value(max_attempts, (1, FLOAT_MAX_INTEGER)) return method(self, *args, **kwargs)