Merge pull request !5189 from islam_amin/fixed_translate_affinetags/v1.0.0
| @@ -131,7 +131,7 @@ PYBIND_REGISTER(RandomResizeWithBBoxOp, 1, ([](const py::module *m) { | |||
| PYBIND_REGISTER(RandomPosterizeOp, 1, ([](const py::module *m) { | |||
| (void)py::class_<RandomPosterizeOp, TensorOp, std::shared_ptr<RandomPosterizeOp>>(*m, | |||
| "RandomPosterizeOp") | |||
| .def(py::init<uint8_t, uint8_t>()); | |||
| .def(py::init<std::vector<uint8_t>>()); | |||
| })); | |||
| PYBIND_REGISTER(UniformAugOp, 1, ([](const py::module *m) { | |||
| @@ -219,8 +219,8 @@ std::shared_ptr<RandomHorizontalFlipOperation> RandomHorizontalFlip(float prob) | |||
| } | |||
| // Function to create RandomPosterizeOperation. | |||
| std::shared_ptr<RandomPosterizeOperation> RandomPosterize(uint8_t min_bit, uint8_t max_bit) { | |||
| auto op = std::make_shared<RandomPosterizeOperation>(min_bit, max_bit); | |||
| std::shared_ptr<RandomPosterizeOperation> RandomPosterize(const std::vector<uint8_t> &bit_range) { | |||
| auto op = std::make_shared<RandomPosterizeOperation>(bit_range); | |||
| // Input validation | |||
| if (!op->ValidateParams()) { | |||
| return nullptr; | |||
| @@ -383,7 +383,7 @@ CutMixBatchOperation::CutMixBatchOperation(ImageBatchFormat image_batch_format, | |||
| bool CutMixBatchOperation::ValidateParams() { | |||
| if (alpha_ <= 0) { | |||
| MS_LOG(ERROR) << "CutMixBatch: alpha cannot be negative."; | |||
| MS_LOG(ERROR) << "CutMixBatch: alpha must be a positive floating value however it is: " << alpha_; | |||
| return false; | |||
| } | |||
| if (prob_ < 0 || prob_ > 1) { | |||
| @@ -616,7 +616,7 @@ RandomAffineOperation::RandomAffineOperation(const std::vector<float_t> °rees | |||
| bool RandomAffineOperation::ValidateParams() { | |||
| // Degrees | |||
| if (degrees_.size() != 2) { | |||
| MS_LOG(ERROR) << "RandomAffine: degrees vector has incorrect size: degrees.size() = " << degrees_.size(); | |||
| MS_LOG(ERROR) << "RandomAffine: degrees expecting size 2, got: degrees.size() = " << degrees_.size(); | |||
| return false; | |||
| } | |||
| if (degrees_[0] > degrees_[1]) { | |||
| @@ -625,16 +625,43 @@ bool RandomAffineOperation::ValidateParams() { | |||
| return false; | |||
| } | |||
| // Translate | |||
| if (translate_range_.size() != 2) { | |||
| MS_LOG(ERROR) << "RandomAffine: translate_range vector has incorrect size: translate_range.size() = " | |||
| if (translate_range_.size() != 2 && translate_range_.size() != 4) { | |||
| MS_LOG(ERROR) << "RandomAffine: translate_range expecting size 2 or 4, got: translate_range.size() = " | |||
| << translate_range_.size(); | |||
| return false; | |||
| } | |||
| if (translate_range_[0] > translate_range_[1]) { | |||
| MS_LOG(ERROR) << "RandomAffine: minimum of translate range is greater than maximum: min = " << translate_range_[0] | |||
| << ", max = " << translate_range_[1]; | |||
| MS_LOG(ERROR) << "RandomAffine: minimum of translate range on x is greater than maximum: min = " | |||
| << translate_range_[0] << ", max = " << translate_range_[1]; | |||
| return false; | |||
| } | |||
| if (translate_range_[0] < -1 || translate_range_[0] > 1) { | |||
| MS_LOG(ERROR) << "RandomAffine: minimum of translate range on x is out of range of [-1, 1], value = " | |||
| << translate_range_[0]; | |||
| return false; | |||
| } | |||
| if (translate_range_[1] < -1 || translate_range_[1] > 1) { | |||
| MS_LOG(ERROR) << "RandomAffine: maximum of translate range on x is out of range of [-1, 1], value = " | |||
| << translate_range_[1]; | |||
| return false; | |||
| } | |||
| if (translate_range_.size() == 4) { | |||
| if (translate_range_[2] > translate_range_[3]) { | |||
| MS_LOG(ERROR) << "RandomAffine: minimum of translate range on y is greater than maximum: min = " | |||
| << translate_range_[2] << ", max = " << translate_range_[3]; | |||
| return false; | |||
| } | |||
| if (translate_range_[2] < -1 || translate_range_[2] > 1) { | |||
| MS_LOG(ERROR) << "RandomAffine: minimum of translate range on y is out of range of [-1, 1], value = " | |||
| << translate_range_[2]; | |||
| return false; | |||
| } | |||
| if (translate_range_[3] < -1 || translate_range_[3] > 1) { | |||
| MS_LOG(ERROR) << "RandomAffine: maximum of translate range on y is out of range of [-1, 1], value = " | |||
| << translate_range_[3]; | |||
| return false; | |||
| } | |||
| } | |||
| // Scale | |||
| if (scale_range_.size() != 2) { | |||
| MS_LOG(ERROR) << "RandomAffine: scale_range vector has incorrect size: scale_range.size() = " | |||
| @@ -647,8 +674,8 @@ bool RandomAffineOperation::ValidateParams() { | |||
| return false; | |||
| } | |||
| // Shear | |||
| if (shear_ranges_.size() != 4) { | |||
| MS_LOG(ERROR) << "RandomAffine: shear_ranges vector has incorrect size: shear_ranges.size() = " | |||
| if (shear_ranges_.size() != 2 && shear_ranges_.size() != 4) { | |||
| MS_LOG(ERROR) << "RandomAffine: shear_ranges expecting size 2 or 4, got: shear_ranges.size() = " | |||
| << shear_ranges_.size(); | |||
| return false; | |||
| } | |||
| @@ -657,7 +684,7 @@ bool RandomAffineOperation::ValidateParams() { | |||
| << shear_ranges_[0] << ", max = " << shear_ranges_[1]; | |||
| return false; | |||
| } | |||
| if (shear_ranges_[2] > shear_ranges_[3]) { | |||
| if (shear_ranges_.size() == 4 && shear_ranges_[2] > shear_ranges_[3]) { | |||
| MS_LOG(ERROR) << "RandomAffine: minimum of vertical shear range is greater than maximum: min = " << shear_ranges_[2] | |||
| << ", max = " << scale_range_[3]; | |||
| return false; | |||
| @@ -671,6 +698,12 @@ bool RandomAffineOperation::ValidateParams() { | |||
| } | |||
| std::shared_ptr<TensorOp> RandomAffineOperation::Build() { | |||
| if (shear_ranges_.size() == 2) { | |||
| shear_ranges_.resize(4); | |||
| } | |||
| if (translate_range_.size() == 2) { | |||
| translate_range_.resize(4); | |||
| } | |||
| auto tensor_op = std::make_shared<RandomAffineOp>(degrees_, translate_range_, scale_range_, shear_ranges_, | |||
| interpolation_, fill_value_); | |||
| return tensor_op; | |||
| @@ -737,27 +770,31 @@ std::shared_ptr<TensorOp> RandomHorizontalFlipOperation::Build() { | |||
| } | |||
| // RandomPosterizeOperation | |||
| RandomPosterizeOperation::RandomPosterizeOperation(uint8_t min_bit, uint8_t max_bit) | |||
| : min_bit_(min_bit), max_bit_(max_bit) {} | |||
| RandomPosterizeOperation::RandomPosterizeOperation(const std::vector<uint8_t> &bit_range) : bit_range_(bit_range) {} | |||
| bool RandomPosterizeOperation::ValidateParams() { | |||
| if (min_bit_ < 1 || min_bit_ > 8) { | |||
| MS_LOG(ERROR) << "RandomPosterize: min_bit value is out of range [1-8]: " << min_bit_; | |||
| if (bit_range_.size() != 2) { | |||
| MS_LOG(ERROR) << "RandomPosterize: bit_range needs to be of size 2 but is of size: " << bit_range_.size(); | |||
| return false; | |||
| } | |||
| if (bit_range_[0] < 1 || bit_range_[0] > 8) { | |||
| MS_LOG(ERROR) << "RandomPosterize: min_bit value is out of range [1-8]: " << bit_range_[0]; | |||
| return false; | |||
| } | |||
| if (max_bit_ < 1 || max_bit_ > 8) { | |||
| MS_LOG(ERROR) << "RandomPosterize: max_bit value is out of range [1-8]: " << max_bit_; | |||
| if (bit_range_[1] < 1 || bit_range_[1] > 8) { | |||
| MS_LOG(ERROR) << "RandomPosterize: max_bit value is out of range [1-8]: " << bit_range_[1]; | |||
| return false; | |||
| } | |||
| if (max_bit_ < min_bit_) { | |||
| MS_LOG(ERROR) << "RandomPosterize: max_bit value is less than min_bit: max =" << max_bit_ << ", min = " << min_bit_; | |||
| if (bit_range_[1] < bit_range_[0]) { | |||
| MS_LOG(ERROR) << "RandomPosterize: max_bit value is less than min_bit: max =" << bit_range_[1] | |||
| << ", min = " << bit_range_[0]; | |||
| return false; | |||
| } | |||
| return true; | |||
| } | |||
| std::shared_ptr<TensorOp> RandomPosterizeOperation::Build() { | |||
| std::shared_ptr<RandomPosterizeOp> tensor_op = std::make_shared<RandomPosterizeOp>(min_bit_, max_bit_); | |||
| std::shared_ptr<RandomPosterizeOp> tensor_op = std::make_shared<RandomPosterizeOp>(bit_range_); | |||
| return tensor_op; | |||
| } | |||
| @@ -161,16 +161,21 @@ std::shared_ptr<PadOperation> Pad(std::vector<int32_t> padding, std::vector<uint | |||
| /// \brief Function to create a RandomAffine TensorOperation. | |||
| /// \notes Applies a Random Affine transformation on input image in RGB or Greyscale mode. | |||
| /// \param[in] degrees A float vector size 2, representing the starting and ending degree | |||
| /// \param[in] translate_range A float vector size 2, representing percentages of translation on x and y axes. | |||
| /// \param[in] translate_range A float vector size 2 or 4, representing percentages of translation on x and y axes. | |||
| /// if size is 2, (min_dx, max_dx, 0, 0) | |||
| /// if size is 4, (min_dx, max_dx, min_dy, max_dy) | |||
| /// all values are in range [-1, 1] | |||
| /// \param[in] scale_range A float vector size 2, representing the starting and ending scales in the range. | |||
| /// \param[in] shear_ranges A float vector size 4, representing the starting and ending shear degrees vertically and | |||
| /// horizontally. | |||
| /// \param[in] shear_ranges A float vector size 2 or 4, representing the starting and ending shear degrees vertically | |||
| /// and horizontally. | |||
| /// if size is 2, (min_shear_x, max_shear_x, 0, 0) | |||
| /// if size is 4, (min_shear_x, max_shear_x, min_shear_y, max_shear_y) | |||
| /// \param[in] interpolation An enum for the mode of interpolation | |||
| /// \param[in] fill_value A uint8_t vector size 3, representing the pixel intensity of the borders, it is used to | |||
| /// fill R, G, B channels respectively. | |||
| /// \return Shared pointer to the current TensorOperation. | |||
| std::shared_ptr<RandomAffineOperation> RandomAffine( | |||
| const std::vector<float_t> °rees, const std::vector<float_t> &translate_range = {0.0, 0.0}, | |||
| const std::vector<float_t> °rees, const std::vector<float_t> &translate_range = {0.0, 0.0, 0.0, 0.0}, | |||
| const std::vector<float_t> &scale_range = {1.0, 1.0}, const std::vector<float_t> &shear_ranges = {0.0, 0.0, 0.0, 0.0}, | |||
| InterpolationMode interpolation = InterpolationMode::kNearestNeighbour, | |||
| const std::vector<uint8_t> &fill_value = {0, 0, 0}); | |||
| @@ -223,10 +228,9 @@ std::shared_ptr<RandomHorizontalFlipOperation> RandomHorizontalFlip(float prob = | |||
| /// \brief Function to create a RandomPosterize TensorOperation. | |||
| /// \notes Tensor operation to perform random posterize. | |||
| /// \param[in] min_bit - uint8_t representing the minimum bit in range. (Default=8) | |||
| /// \param[in] max_bit - uint8_t representing the maximum bit in range. (Default=8) | |||
| /// \param[in] bit_range - uint8_t vector representing the minimum and maximum bit in range. (Default={4, 8}) | |||
| /// \return Shared pointer to the current TensorOperation. | |||
| std::shared_ptr<RandomPosterizeOperation> RandomPosterize(uint8_t min_bit = 8, uint8_t max_bit = 8); | |||
| std::shared_ptr<RandomPosterizeOperation> RandomPosterize(const std::vector<uint8_t> &bit_range = {4, 8}); | |||
| /// \brief Function to create a RandomRotation TensorOp | |||
| /// \notes Rotates the image according to parameters | |||
| @@ -530,7 +534,7 @@ class RandomHorizontalFlipOperation : public TensorOperation { | |||
| class RandomPosterizeOperation : public TensorOperation { | |||
| public: | |||
| explicit RandomPosterizeOperation(uint8_t min_bit = 8, uint8_t max_bit = 8); | |||
| explicit RandomPosterizeOperation(const std::vector<uint8_t> &bit_range = {4, 8}); | |||
| ~RandomPosterizeOperation() = default; | |||
| @@ -539,8 +543,7 @@ class RandomPosterizeOperation : public TensorOperation { | |||
| bool ValidateParams() override; | |||
| private: | |||
| uint8_t min_bit_; | |||
| uint8_t max_bit_; | |||
| std::vector<uint8_t> bit_range_; | |||
| }; | |||
| class RandomRotationOperation : public TensorOperation { | |||
| @@ -27,7 +27,7 @@ namespace mindspore { | |||
| namespace dataset { | |||
| const std::vector<float_t> RandomAffineOp::kDegreesRange = {0.0, 0.0}; | |||
| const std::vector<float_t> RandomAffineOp::kTranslationPercentages = {0.0, 0.0}; | |||
| const std::vector<float_t> RandomAffineOp::kTranslationPercentages = {0.0, 0.0, 0.0, 0.0}; | |||
| const std::vector<float_t> RandomAffineOp::kScaleRange = {1.0, 1.0}; | |||
| const std::vector<float_t> RandomAffineOp::kShearRanges = {0.0, 0.0, 0.0, 0.0}; | |||
| const InterpolationMode RandomAffineOp::kDefInterpolation = InterpolationMode::kNearestNeighbour; | |||
| @@ -50,14 +50,16 @@ Status RandomAffineOp::Compute(const std::shared_ptr<Tensor> &input, std::shared | |||
| IO_CHECK(input, output); | |||
| dsize_t height = input->shape()[0]; | |||
| dsize_t width = input->shape()[1]; | |||
| float_t max_dx = translate_range_[0] * height; | |||
| float_t max_dy = translate_range_[1] * width; | |||
| float_t min_dx = translate_range_[0] * width; | |||
| float_t max_dx = translate_range_[1] * width; | |||
| float_t min_dy = translate_range_[2] * height; | |||
| float_t max_dy = translate_range_[3] * height; | |||
| float_t degrees = 0.0; | |||
| RETURN_IF_NOT_OK(GenerateRealNumber(degrees_range_[0], degrees_range_[1], &rnd_, °rees)); | |||
| float_t translation_x = 0.0; | |||
| RETURN_IF_NOT_OK(GenerateRealNumber(-1 * max_dx, max_dx, &rnd_, &translation_x)); | |||
| RETURN_IF_NOT_OK(GenerateRealNumber(min_dx, max_dx, &rnd_, &translation_x)); | |||
| float_t translation_y = 0.0; | |||
| RETURN_IF_NOT_OK(GenerateRealNumber(-1 * max_dy, max_dy, &rnd_, &translation_y)); | |||
| RETURN_IF_NOT_OK(GenerateRealNumber(min_dy, max_dy, &rnd_, &translation_y)); | |||
| float_t scale = 1.0; | |||
| RETURN_IF_NOT_OK(GenerateRealNumber(scale_range_[0], scale_range_[1], &rnd_, &scale)); | |||
| float_t shear_x = 0.0; | |||
| @@ -24,16 +24,16 @@ | |||
| namespace mindspore { | |||
| namespace dataset { | |||
| const uint8_t RandomPosterizeOp::kMinBit = 8; | |||
| const uint8_t RandomPosterizeOp::kMaxBit = 8; | |||
| const std::vector<uint8_t> RandomPosterizeOp::kBitRange = {4, 8}; | |||
| RandomPosterizeOp::RandomPosterizeOp(uint8_t min_bit, uint8_t max_bit) | |||
| : PosterizeOp(min_bit), min_bit_(min_bit), max_bit_(max_bit) { | |||
| RandomPosterizeOp::RandomPosterizeOp(const std::vector<uint8_t> &bit_range) | |||
| : PosterizeOp(bit_range[0]), bit_range_(bit_range) { | |||
| rnd_.seed(GetSeed()); | |||
| } | |||
| Status RandomPosterizeOp::Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) { | |||
| bit_ = (min_bit_ == max_bit_) ? min_bit_ : std::uniform_int_distribution<uint8_t>(min_bit_, max_bit_)(rnd_); | |||
| bit_ = (bit_range_[0] == bit_range_[1]) ? bit_range_[0] | |||
| : std::uniform_int_distribution<uint8_t>(bit_range_[0], bit_range_[1])(rnd_); | |||
| return PosterizeOp::Compute(input, output); | |||
| } | |||
| } // namespace dataset | |||
| @@ -28,13 +28,11 @@ namespace dataset { | |||
| class RandomPosterizeOp : public PosterizeOp { | |||
| public: | |||
| /// Default values | |||
| static const uint8_t kMinBit; | |||
| static const uint8_t kMaxBit; | |||
| static const std::vector<uint8_t> kBitRange; | |||
| /// \brief Constructor | |||
| /// \param[in] min_bit: Minimum bit in range | |||
| /// \param[in] max_bit: Maximum bit in range | |||
| explicit RandomPosterizeOp(uint8_t min_bit = kMinBit, uint8_t max_bit = kMaxBit); | |||
| /// \param[in] bit_range: Minimum and maximum bits in range | |||
| explicit RandomPosterizeOp(const std::vector<uint8_t> &bit_range = kBitRange); | |||
| ~RandomPosterizeOp() override = default; | |||
| @@ -45,8 +43,7 @@ class RandomPosterizeOp : public PosterizeOp { | |||
| /// Member variables | |||
| private: | |||
| std::string kRandomPosterizeOp = "RandomPosterizeOp"; | |||
| uint8_t min_bit_; | |||
| uint8_t max_bit_; | |||
| std::vector<uint8_t> bit_range_; | |||
| std::mt19937 rnd_; | |||
| }; | |||
| } // namespace dataset | |||
| @@ -64,6 +64,7 @@ DE_C_BORDER_TYPE = {Border.CONSTANT: cde.BorderType.DE_BORDER_CONSTANT, | |||
| DE_C_IMAGE_BATCH_FORMAT = {ImageBatchFormat.NHWC: cde.ImageBatchFormat.DE_IMAGE_BATCH_FORMAT_NHWC, | |||
| ImageBatchFormat.NCHW: cde.ImageBatchFormat.DE_IMAGE_BATCH_FORMAT_NCHW} | |||
| def parse_padding(padding): | |||
| if isinstance(padding, numbers.Number): | |||
| padding = [padding] * 4 | |||
| @@ -237,11 +238,16 @@ class RandomAffine(cde.RandomAffineOp): | |||
| degrees (int or float or sequence): Range of the rotation degrees. | |||
| If degrees is a number, the range will be (-degrees, degrees). | |||
| If degrees is a sequence, it should be (min, max). | |||
| translate (sequence, optional): Sequence (tx, ty) of maximum translation in | |||
| translate (sequence, optional): Sequence (tx_min, tx_max, ty_min, ty_max) of minimum/maximum translation in | |||
| x(horizontal) and y(vertical) directions (default=None). | |||
| The horizontal and vertical shift is selected randomly from the range: | |||
| (-tx*width, tx*width) and (-ty*height, ty*height), respectively. | |||
| If None, no translations gets applied. | |||
| (tx_min*width, tx_max*width) and (ty_min*height, ty_max*height), respectively. | |||
| If a tuple or list of size 2, then a translate parallel to the x axis in the range of | |||
| (translate[0], translate[1]) is applied. | |||
| If a tuple of list of size 4, then a translate parallel to x axis in the range of | |||
| (translate[0], translate[1]) and a translate parallel to y axis in the range of | |||
| (translate[2], translate[3]) are applied. | |||
| If None, no translation is applied. | |||
| scale (sequence, optional): Scaling factor interval (default=None, original scale is used). | |||
| shear (int or float or sequence, optional): Range of shear factor (default=None). | |||
| If a number 'shear', then a shear parallel to the x axis in the range of (-shear, +shear) is applied. | |||
| @@ -266,18 +272,18 @@ class RandomAffine(cde.RandomAffineOp): | |||
| Raises: | |||
| ValueError: If degrees is negative. | |||
| ValueError: If translation value is not between 0 and 1. | |||
| ValueError: If translation value is not between -1 and 1. | |||
| ValueError: If scale is not positive. | |||
| ValueError: If shear is a number but is not positive. | |||
| TypeError: If degrees is not a number or a list or a tuple. | |||
| If degrees is a list or tuple, its length is not 2. | |||
| TypeError: If translate is specified but is not list or a tuple of length 2. | |||
| TypeError: If translate is specified but is not list or a tuple of length 2 or 4. | |||
| TypeError: If scale is not a list or tuple of length 2.'' | |||
| TypeError: If shear is not a list or tuple of length 2 or 4. | |||
| TypeError: If fill_value is not a single integer or a 3-tuple. | |||
| Examples: | |||
| >>> c_transform.RandomAffine(degrees=15, translate=(0.1, 0.1), scale=(0.9, 1.1)) | |||
| >>> c_transform.RandomAffine(degrees=15, translate=(-0.1, 0.1, 0, 0), scale=(0.9, 1.1)) | |||
| """ | |||
| @check_random_affine | |||
| @@ -300,7 +306,7 @@ class RandomAffine(cde.RandomAffineOp): | |||
| # translation | |||
| if translate is None: | |||
| translate = (0.0, 0.0) | |||
| translate = (0.0, 0.0, 0.0, 0.0) | |||
| # scale | |||
| if scale is None: | |||
| @@ -467,7 +473,7 @@ class RandomPosterize(cde.RandomPosterizeOp): | |||
| bits values should always be in range of [1,8], and include at | |||
| least one integer values in the given range. It should be in | |||
| (min, max) or integer format. If min=max, then it is a single fixed | |||
| magnitude operation (default=8). | |||
| magnitude operation (default=[4,8]). | |||
| """ | |||
| @check_posterize | |||
| @@ -475,7 +481,7 @@ class RandomPosterize(cde.RandomPosterizeOp): | |||
| self.bits = bits | |||
| if isinstance(bits, int): | |||
| bits = (bits, bits) | |||
| super().__init__(bits[0], bits[1]) | |||
| super().__init__(bits) | |||
| class RandomVerticalFlip(cde.RandomVerticalFlipOp): | |||
| @@ -523,10 +523,10 @@ def check_random_affine(method): | |||
| if translate is not None: | |||
| type_check(translate, (list, tuple), "translate") | |||
| type_check_list(translate, (int, float), "translate") | |||
| if len(translate) != 2: | |||
| raise TypeError("translate should be a list or tuple of length 2.") | |||
| if len(translate) != 2 and len(translate) != 4: | |||
| raise TypeError("translate should be a list or tuple of length 2 or 4.") | |||
| for i, t in enumerate(translate): | |||
| check_value(t, [0.0, 1.0], "translate at {0}".format(i)) | |||
| check_value(t, [-1.0, 1.0], "translate at {0}".format(i)) | |||
| if scale is not None: | |||
| type_check(scale, (tuple, list), "scale") | |||
| @@ -620,10 +620,10 @@ TEST_F(MindDataTestPipeline, TestRandomAffineFail) { | |||
| std::shared_ptr<TensorOperation> affine = vision::RandomAffine({0.0, 0.0}, {}); | |||
| EXPECT_EQ(affine, nullptr); | |||
| // Invalid number of values for translate | |||
| affine = vision::RandomAffine({0.0, 0.0}, {1, 1, 1, 1}); | |||
| affine = vision::RandomAffine({0.0, 0.0}, {1, 1, 1, 1, 1}); | |||
| EXPECT_EQ(affine, nullptr); | |||
| // Invalid number of values for shear | |||
| affine = vision::RandomAffine({30.0, 30.0}, {0.0, 0.0}, {2.0, 2.0}, {10.0, 10.0}); | |||
| affine = vision::RandomAffine({30.0, 30.0}, {0.0, 0.0}, {2.0, 2.0}, {10.0}); | |||
| EXPECT_EQ(affine, nullptr); | |||
| } | |||
| @@ -642,7 +642,7 @@ TEST_F(MindDataTestPipeline, TestRandomAffineSuccess1) { | |||
| // Create objects for the tensor ops | |||
| std::shared_ptr<TensorOperation> affine = | |||
| vision::RandomAffine({30.0, 30.0}, {0.0, 0.0}, {2.0, 2.0}, {10.0, 10.0, 20.0, 20.0}); | |||
| vision::RandomAffine({30.0, 30.0}, {-1.0, 1.0, -1.0, 1.0}, {2.0, 2.0}, {10.0, 10.0, 20.0, 20.0}); | |||
| EXPECT_NE(affine, nullptr); | |||
| // Create a Map operation on ds | |||
| @@ -844,13 +844,16 @@ TEST_F(MindDataTestPipeline, TestRandomPosterizeFail) { | |||
| // Create objects for the tensor ops | |||
| // Invalid max > 8 | |||
| std::shared_ptr<TensorOperation> posterize = vision::RandomPosterize(1, 9); | |||
| std::shared_ptr<TensorOperation> posterize = vision::RandomPosterize({1, 9}); | |||
| EXPECT_EQ(posterize, nullptr); | |||
| // Invalid min < 1 | |||
| posterize = vision::RandomPosterize(0, 8); | |||
| posterize = vision::RandomPosterize({0, 8}); | |||
| EXPECT_EQ(posterize, nullptr); | |||
| // min > max | |||
| posterize = vision::RandomPosterize(8, 1); | |||
| posterize = vision::RandomPosterize({8, 1}); | |||
| EXPECT_EQ(posterize, nullptr); | |||
| // empty | |||
| posterize = vision::RandomPosterize({}); | |||
| EXPECT_EQ(posterize, nullptr); | |||
| } | |||
| @@ -869,7 +872,7 @@ TEST_F(MindDataTestPipeline, TestRandomPosterizeSuccess1) { | |||
| // Create objects for the tensor ops | |||
| std::shared_ptr<TensorOperation> posterize = | |||
| vision::RandomPosterize(1, 4); | |||
| vision::RandomPosterize({1, 4}); | |||
| EXPECT_NE(posterize, nullptr); | |||
| // Create a Map operation on ds | |||
| @@ -33,8 +33,9 @@ TEST_F(MindDataTestRandomAffineOp, TestOp1) { | |||
| MS_LOG(INFO) << "Doing testRandomAffineOp."; | |||
| std::shared_ptr<Tensor> output_tensor; | |||
| std::unique_ptr<RandomAffineOp> op(new RandomAffineOp({30.0, 30.0}, {0.0, 0.0}, {2.0, 2.0}, {10.0, 10.0, 20.0, 20.0}, | |||
| InterpolationMode::kNearestNeighbour, {255, 0, 0})); | |||
| std::unique_ptr<RandomAffineOp> op(new RandomAffineOp({30.0, 30.0}, {0.0, 0.0, 0.0, 0.0}, {2.0, 2.0}, | |||
| {10.0, 10.0, 20.0, 20.0}, InterpolationMode::kNearestNeighbour, | |||
| {255, 0, 0})); | |||
| EXPECT_TRUE(op->OneToOne()); | |||
| Status s = op->Compute(input_tensor_, &output_tensor); | |||
| EXPECT_TRUE(s.IsOk()); | |||
| @@ -33,7 +33,7 @@ TEST_F(MindDataTestRandomPosterizeOp, TestOp1) { | |||
| MS_LOG(INFO) << "Doing testRandomPosterize."; | |||
| std::shared_ptr<Tensor> output_tensor; | |||
| std::unique_ptr<RandomPosterizeOp> op(new RandomPosterizeOp(1, 1)); | |||
| std::unique_ptr<RandomPosterizeOp> op(new RandomPosterizeOp({1, 1})); | |||
| EXPECT_TRUE(op->OneToOne()); | |||
| Status s = op->Compute(input_tensor_, &output_tensor); | |||
| EXPECT_TRUE(s.IsOk()); | |||
| @@ -75,7 +75,7 @@ def test_random_affine_op_c(plot=False): | |||
| # define map operations | |||
| transforms1 = [ | |||
| c_vision.Decode(), | |||
| c_vision.RandomAffine(degrees=15, translate=(0.1, 0.1), scale=(0.9, 1.1)) | |||
| c_vision.RandomAffine(degrees=0, translate=(0.5, 0.5, 0, 0)) | |||
| ] | |||
| transforms2 = [ | |||
| @@ -139,7 +139,7 @@ def test_random_affine_c_md5(): | |||
| # define map operations | |||
| transforms = [ | |||
| c_vision.Decode(), | |||
| c_vision.RandomAffine(degrees=(-5, 15), translate=(0.1, 0.3), | |||
| c_vision.RandomAffine(degrees=(-5, 15), translate=(-0.1, 0.1, -0.3, 0.3), | |||
| scale=(0.9, 1.1), shear=(-10, 10, -5, 5)) | |||
| ] | |||
| @@ -156,9 +156,35 @@ def test_random_affine_c_md5(): | |||
| ds.config.set_num_parallel_workers((original_num_parallel_workers)) | |||
| def test_random_affine_default_c_md5(): | |||
| """ | |||
| Test RandomAffine C Op (default params) with md5 comparison | |||
| """ | |||
| logger.info("test_random_affine_default_c_md5") | |||
| original_seed = config_get_set_seed(1) | |||
| original_num_parallel_workers = config_get_set_num_parallel_workers(1) | |||
| # define map operations | |||
| transforms = [ | |||
| c_vision.Decode(), | |||
| c_vision.RandomAffine(degrees=0) | |||
| ] | |||
| # Generate dataset | |||
| data = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False) | |||
| data = data.map(input_columns=["image"], operations=transforms) | |||
| # check results with md5 comparison | |||
| filename = "random_affine_01_default_c_result.npz" | |||
| save_and_check_md5(data, filename, generate_golden=GENERATE_GOLDEN) | |||
| # Restore configuration | |||
| ds.config.set_seed(original_seed) | |||
| ds.config.set_num_parallel_workers((original_num_parallel_workers)) | |||
| def test_random_affine_py_exception_non_pil_images(): | |||
| """ | |||
| Test RandomAffine: input img is ndarray and not PIL, expected to raise TypeError | |||
| Test RandomAffine: input img is ndarray and not PIL, expected to raise RuntimeError | |||
| """ | |||
| logger.info("test_random_affine_exception_negative_degrees") | |||
| dataset = ds.MnistDataset(MNIST_DATA_DIR, num_parallel_workers=3) | |||
| @@ -188,14 +214,20 @@ def test_random_affine_exception_negative_degrees(): | |||
| def test_random_affine_exception_translation_range(): | |||
| """ | |||
| Test RandomAffine: translation value is not in [0, 1], expected to raise ValueError | |||
| Test RandomAffine: translation value is not in [-1, 1], expected to raise ValueError | |||
| """ | |||
| logger.info("test_random_affine_exception_translation_range") | |||
| try: | |||
| _ = py_vision.RandomAffine(degrees=15, translate=(0.1, 1.5)) | |||
| _ = c_vision.RandomAffine(degrees=15, translate=(0.1, 1.5)) | |||
| except ValueError as e: | |||
| logger.info("Got an exception in DE: {}".format(str(e))) | |||
| assert str(e) == "Input translate at 1 is not within the required interval of (-1.0 to 1.0)." | |||
| logger.info("test_random_affine_exception_translation_range") | |||
| try: | |||
| _ = c_vision.RandomAffine(degrees=15, translate=(-2, 1.5)) | |||
| except ValueError as e: | |||
| logger.info("Got an exception in DE: {}".format(str(e))) | |||
| assert str(e) == "Input translate at 1 is not within the required interval of (0.0 to 1.0)." | |||
| assert str(e) == "Input translate at 0 is not within the required interval of (-1.0 to 1.0)." | |||
| def test_random_affine_exception_scale_value(): | |||
| @@ -308,6 +340,7 @@ if __name__ == "__main__": | |||
| test_random_affine_op_c(plot=True) | |||
| test_random_affine_md5() | |||
| test_random_affine_c_md5() | |||
| test_random_affine_default_c_md5() | |||
| test_random_affine_py_exception_non_pil_images() | |||
| test_random_affine_exception_negative_degrees() | |||
| test_random_affine_exception_translation_range() | |||
| @@ -114,6 +114,47 @@ def test_random_posterize_op_fixed_point_c(plot=False, run_golden=True): | |||
| visualize_list(image_original, image_posterize) | |||
| def test_random_posterize_default_c_md5(plot=False, run_golden=True): | |||
| """ | |||
| Test RandomPosterize C Op (default params) with md5 comparison | |||
| """ | |||
| logger.info("test_random_posterize_default_c_md5") | |||
| original_seed = config_get_set_seed(5) | |||
| original_num_parallel_workers = config_get_set_num_parallel_workers(1) | |||
| # define map operations | |||
| transforms1 = [ | |||
| c_vision.Decode(), | |||
| c_vision.RandomPosterize() | |||
| ] | |||
| # First dataset | |||
| data1 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False) | |||
| data1 = data1.map(input_columns=["image"], operations=transforms1) | |||
| # Second dataset | |||
| data2 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False) | |||
| data2 = data2.map(input_columns=["image"], operations=[c_vision.Decode()]) | |||
| image_posterize = [] | |||
| image_original = [] | |||
| for item1, item2 in zip(data1.create_dict_iterator(), data2.create_dict_iterator()): | |||
| image1 = item1["image"] | |||
| image2 = item2["image"] | |||
| image_posterize.append(image1) | |||
| image_original.append(image2) | |||
| if run_golden: | |||
| # check results with md5 comparison | |||
| filename = "random_posterize_01_default_result_c.npz" | |||
| save_and_check_md5(data1, filename, generate_golden=GENERATE_GOLDEN) | |||
| if plot: | |||
| visualize_list(image_original, image_posterize) | |||
| # Restore configuration | |||
| ds.config.set_seed(original_seed) | |||
| ds.config.set_num_parallel_workers(original_num_parallel_workers) | |||
| def test_random_posterize_exception_bit(): | |||
| """ | |||
| Test RandomPosterize: out of range input bits and invalid type | |||
| @@ -150,6 +191,7 @@ def test_random_posterize_exception_bit(): | |||
| logger.info("Got an exception in DE: {}".format(str(e))) | |||
| assert str(e) == "Size of bits should be a single integer or a list/tuple (min, max) of length 2." | |||
| def test_rescale_with_random_posterize(): | |||
| """ | |||
| Test RandomPosterize: only support CV_8S/CV_8U | |||
| @@ -171,8 +213,10 @@ def test_rescale_with_random_posterize(): | |||
| logger.info("Got an exception in DE: {}".format(str(e))) | |||
| assert "Input image data type can not be float" in str(e) | |||
| if __name__ == "__main__": | |||
| test_random_posterize_op_c(plot=False, run_golden=False) | |||
| test_random_posterize_op_fixed_point_c(plot=False) | |||
| test_random_posterize_default_c_md5(plot=False) | |||
| test_random_posterize_exception_bit() | |||
| test_rescale_with_random_posterize() | |||