diff --git a/mindspore/ccsrc/minddata/dataset/api/vision.cc b/mindspore/ccsrc/minddata/dataset/api/vision.cc index 2b2cb3b190..636528c7f1 100644 --- a/mindspore/ccsrc/minddata/dataset/api/vision.cc +++ b/mindspore/ccsrc/minddata/dataset/api/vision.cc @@ -32,6 +32,7 @@ #endif #include "minddata/dataset/kernels/image/decode_op.h" #ifndef ENABLE_ANDROID +#include "minddata/dataset/kernels/image/equalize_op.h" #include "minddata/dataset/kernels/image/hwc_to_chw_op.h" #include "minddata/dataset/kernels/image/invert_op.h" #include "minddata/dataset/kernels/image/mixup_batch_op.h" @@ -49,7 +50,10 @@ #include "minddata/dataset/kernels/image/random_horizontal_flip_op.h" #include "minddata/dataset/kernels/image/random_horizontal_flip_with_bbox_op.h" #include "minddata/dataset/kernels/image/random_posterize_op.h" +#include "minddata/dataset/kernels/image/random_resize_op.h" +#include "minddata/dataset/kernels/image/random_resize_with_bbox_op.h" #include "minddata/dataset/kernels/image/random_rotation_op.h" +#include "minddata/dataset/kernels/image/random_select_subpolicy_op.h" #include "minddata/dataset/kernels/image/random_sharpness_op.h" #include "minddata/dataset/kernels/image/random_solarize_op.h" #include "minddata/dataset/kernels/image/random_vertical_flip_op.h" @@ -61,6 +65,8 @@ #include "minddata/dataset/kernels/image/resize_with_bbox_op.h" #include "minddata/dataset/kernels/image/rgba_to_bgr_op.h" #include "minddata/dataset/kernels/image/rgba_to_rgb_op.h" +#include "minddata/dataset/kernels/image/soft_dvpp/soft_dvpp_decode_random_crop_resize_jpeg_op.h" +#include "minddata/dataset/kernels/image/soft_dvpp/soft_dvpp_decode_resize_jpeg_op.h" #include "minddata/dataset/kernels/image/swap_red_blue_op.h" #include "minddata/dataset/kernels/image/uniform_aug_op.h" #endif @@ -78,10 +84,7 @@ namespace vision { std::shared_ptr AutoContrast(float cutoff, std::vector ignore) { auto op = std::make_shared(cutoff, ignore); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create BoundingBoxAugmentOperation. @@ -89,20 +92,14 @@ std::shared_ptr BoundingBoxAugment(std::shared_ptr< float ratio) { auto op = std::make_shared(transform, ratio); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create CenterCropOperation. std::shared_ptr CenterCrop(std::vector size) { auto op = std::make_shared(size); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } #endif @@ -110,80 +107,63 @@ std::shared_ptr CenterCrop(std::vector size) { std::shared_ptr Crop(std::vector coordinates, std::vector size) { auto op = std::make_shared(coordinates, size); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } #ifndef ENABLE_ANDROID // Function to create CutMixBatchOperation. std::shared_ptr CutMixBatch(ImageBatchFormat image_batch_format, float alpha, float prob) { auto op = std::make_shared(image_batch_format, alpha, prob); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create CutOutOp. std::shared_ptr CutOut(int32_t length, int32_t num_patches) { auto op = std::make_shared(length, num_patches); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create DecodeOperation. std::shared_ptr Decode(bool rgb) { auto op = std::make_shared(rgb); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; +} + +// Function to create EqualizeOperation. +std::shared_ptr Equalize() { + auto op = std::make_shared(); + // Input validation + return op->ValidateParams() ? op : nullptr; } // Function to create HwcToChwOperation. std::shared_ptr HWC2CHW() { auto op = std::make_shared(); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create InvertOperation. std::shared_ptr Invert() { auto op = std::make_shared(); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create MixUpBatchOperation. std::shared_ptr MixUpBatch(float alpha) { auto op = std::make_shared(alpha); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create NormalizeOperation. std::shared_ptr Normalize(std::vector mean, std::vector std) { auto op = std::make_shared(mean, std); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create PadOperation. @@ -191,10 +171,7 @@ std::shared_ptr Pad(std::vector padding, std::vector(padding, fill_value, padding_mode); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create RandomAffineOperation. @@ -207,20 +184,14 @@ std::shared_ptr RandomAffine(const std::vector & auto op = std::make_shared(degrees, translate_range, scale_range, shear_ranges, interpolation, fill_value); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create RandomColorOperation. std::shared_ptr RandomColor(float t_lb, float t_ub) { auto op = std::make_shared(t_lb, t_ub); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } std::shared_ptr RandomColorOperation::Build() { @@ -234,10 +205,7 @@ std::shared_ptr RandomColorAdjust(std::vector std::vector saturation, std::vector hue) { auto op = std::make_shared(brightness, contrast, saturation, hue); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create RandomCropOperation. @@ -246,10 +214,7 @@ std::shared_ptr RandomCrop(std::vector size, std:: BorderType padding_mode) { auto op = std::make_shared(size, padding, pad_if_needed, fill_value, padding_mode); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create RandomCropDecodeResizeOperation. @@ -260,10 +225,7 @@ std::shared_ptr RandomCropDecodeResize(std::vec int32_t max_attempts) { auto op = std::make_shared(size, scale, ratio, interpolation, max_attempts); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create RandomCropWithBBoxOperation. @@ -272,40 +234,42 @@ std::shared_ptr RandomCropWithBBox(std::vector(size, padding, pad_if_needed, fill_value, padding_mode); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create RandomHorizontalFlipOperation. std::shared_ptr RandomHorizontalFlip(float prob) { auto op = std::make_shared(prob); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create RandomHorizontalFlipOperation. std::shared_ptr RandomHorizontalFlipWithBBox(float prob) { auto op = std::make_shared(prob); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create RandomPosterizeOperation. std::shared_ptr RandomPosterize(const std::vector &bit_range) { auto op = std::make_shared(bit_range); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; +} + +// Function to create RandomResizeOperation. +std::shared_ptr RandomResize(std::vector size) { + auto op = std::make_shared(size); + // Input validation + return op->ValidateParams() ? op : nullptr; +} + +// Function to create RandomResizeWithBBoxOperation. +std::shared_ptr RandomResizeWithBBox(std::vector size) { + auto op = std::make_shared(size); + // Input validation + return op->ValidateParams() ? op : nullptr; } // Function to create RandomResizedCropOperation. @@ -314,10 +278,7 @@ std::shared_ptr RandomResizedCrop(std::vector(size, scale, ratio, interpolation, max_attempts); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create RandomRotationOperation. @@ -326,60 +287,50 @@ std::shared_ptr RandomRotation(std::vector degre std::vector fill_value) { auto op = std::make_shared(degrees, resample, expand, center, fill_value); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create RandomSharpnessOperation. std::shared_ptr RandomSharpness(std::vector degrees) { auto op = std::make_shared(degrees); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create RandomSolarizeOperation. std::shared_ptr RandomSolarize(std::vector threshold) { auto op = std::make_shared(threshold); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; +} + +// Function to create RandomSelectSubpolicyOperation. +std::shared_ptr RandomSelectSubpolicy( + std::vector, double>>> policy) { + auto op = std::make_shared(policy); + // Input validation + return op->ValidateParams() ? op : nullptr; } // Function to create RandomVerticalFlipOperation. std::shared_ptr RandomVerticalFlip(float prob) { auto op = std::make_shared(prob); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create RandomVerticalFlipWithBBoxOperation. std::shared_ptr RandomVerticalFlipWithBBox(float prob) { auto op = std::make_shared(prob); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create RescaleOperation. std::shared_ptr Rescale(float rescale, float shift) { auto op = std::make_shared(rescale, shift); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } #endif @@ -387,10 +338,7 @@ std::shared_ptr Rescale(float rescale, float shift) { std::shared_ptr Resize(std::vector size, InterpolationMode interpolation) { auto op = std::make_shared(size, interpolation); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } #ifndef ENABLE_ANDROID @@ -398,40 +346,43 @@ std::shared_ptr Resize(std::vector size, Interpolation std::shared_ptr ResizeWithBBox(std::vector size, InterpolationMode interpolation) { auto op = std::make_shared(size, interpolation); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create RgbaToBgrOperation. std::shared_ptr RGBA2BGR() { auto op = std::make_shared(); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create RgbaToRgbOperation. std::shared_ptr RGBA2RGB() { auto op = std::make_shared(); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; +} + +// Function to create SoftDvppDecodeRandomCropResizeJpegOperation. +std::shared_ptr SoftDvppDecodeRandomCropResizeJpeg( + std::vector size, std::vector scale, std::vector ratio, int32_t max_attempts) { + auto op = std::make_shared(size, scale, ratio, max_attempts); + // Input validation + return op->ValidateParams() ? op : nullptr; +} + +// Function to create SoftDvppDecodeResizeJpegOperation. +std::shared_ptr SoftDvppDecodeResizeJpeg(std::vector size) { + auto op = std::make_shared(size); + // Input validation + return op->ValidateParams() ? op : nullptr; } // Function to create SwapRedBlueOperation. std::shared_ptr SwapRedBlue() { auto op = std::make_shared(); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } // Function to create UniformAugOperation. @@ -439,10 +390,7 @@ std::shared_ptr UniformAugment(std::vector(transforms, num_ops); // Input validation - if (!op->ValidateParams()) { - return nullptr; - } - return op; + return op->ValidateParams() ? op : nullptr; } #endif @@ -660,6 +608,7 @@ std::shared_ptr CropOperation::Build() { height = size_[0]; width = size_[0]; + // User has specified crop_width. if (size_.size() == 2) { width = size_[1]; } @@ -722,6 +671,11 @@ Status DecodeOperation::ValidateParams() { return Status::OK(); } std::shared_ptr DecodeOperation::Build() { return std::make_shared(rgb_); } +// EqualizeOperation +Status EqualizeOperation::ValidateParams() { return Status::OK(); } + +std::shared_ptr EqualizeOperation::Build() { return std::make_shared(); } + // HwcToChwOperation Status HwcToChwOperation::ValidateParams() { return Status::OK(); } @@ -1417,11 +1371,80 @@ std::shared_ptr RandomPosterizeOperation::Build() { return tensor_op; } +// RandomResizeOperation +RandomResizeOperation::RandomResizeOperation(std::vector size) : size_(size) {} + +Status RandomResizeOperation::ValidateParams() { + // size + if (size_.size() != 2 && size_.size() != 1) { + std::string err_msg = + "RandomResize: size must be a vector of one or two values, got: " + std::to_string(size_.size()); + MS_LOG(ERROR) << err_msg; + RETURN_STATUS_SYNTAX_ERROR(err_msg); + } + if (size_[0] <= 0 || (size_.size() == 2 && size_[1] <= 0)) { + std::string err_msg = "RandomResize: size must only contain positive integers."; + MS_LOG(ERROR) << "RandomResize: size must only contain positive integers, got: " << size_; + RETURN_STATUS_SYNTAX_ERROR(err_msg); + } + return Status::OK(); +} + +std::shared_ptr RandomResizeOperation::Build() { + // If size is a single value, the smaller edge of the image will be + // resized to this value with the same image aspect ratio. + int32_t height = size_[0]; + int32_t width = 0; + + // User specified the width value. + if (size_.size() == 2) { + width = size_[1]; + } + + std::shared_ptr tensor_op = std::make_shared(height, width); + return tensor_op; +} + +// RandomResizeWithBBoxOperation +RandomResizeWithBBoxOperation::RandomResizeWithBBoxOperation(std::vector size) : size_(size) {} + +Status RandomResizeWithBBoxOperation::ValidateParams() { + // size + if (size_.size() != 2 && size_.size() != 1) { + std::string err_msg = + "RandomResizeWithBBox: size must be a vector of one or two values, got: " + std::to_string(size_.size()); + MS_LOG(ERROR) << err_msg; + RETURN_STATUS_SYNTAX_ERROR(err_msg); + } + if (size_[0] <= 0 || (size_.size() == 2 && size_[1] <= 0)) { + std::string err_msg = "RandomResizeWithBBox: size must only contain positive integers."; + MS_LOG(ERROR) << "RandomResizeWithBBox: size must only contain positive integers, got: " << size_; + RETURN_STATUS_SYNTAX_ERROR(err_msg); + } + return Status::OK(); +} + +std::shared_ptr RandomResizeWithBBoxOperation::Build() { + // If size is a single value, the smaller edge of the image will be + // resized to this value with the same image aspect ratio. + int32_t height = size_[0]; + int32_t width = 0; + + // User specified the width value. + if (size_.size() == 2) { + width = size_[1]; + } + + std::shared_ptr tensor_op = std::make_shared(height, width); + return tensor_op; +} + // RandomResizedCropOperation RandomResizedCropOperation::RandomResizedCropOperation(std::vector size, std::vector scale, std::vector ratio, InterpolationMode interpolation, int32_t max_attempts) : size_(size), scale_(scale), ratio_(ratio), interpolation_(interpolation), max_attempts_(max_attempts) {} + Status RandomResizedCropOperation::ValidateParams() { // size if (size_.size() != 2 && size_.size() != 1) { @@ -1455,8 +1478,9 @@ Status RandomResizedCropOperation::ValidateParams() { } // ratio if (ratio_.size() != 2) { - std::string err_msg = "RandomResizedCrop: ratio must be in the format of (min, max)."; - MS_LOG(ERROR) << "RandomResizedCrop: ratio must be in the format of (min, max), but got: " << ratio_; + std::string err_msg = + "RandomResizedCrop: ratio must be a vector of two values, got: " + std::to_string(ratio_.size()); + MS_LOG(ERROR) << err_msg; RETURN_STATUS_SYNTAX_ERROR(err_msg); } if (ratio_[0] < 0 || ratio_[1] < 0) { @@ -1470,12 +1494,23 @@ Status RandomResizedCropOperation::ValidateParams() { << ratio_; RETURN_STATUS_SYNTAX_ERROR(err_msg); } + // max_attempts + if (max_attempts_ < 1) { + std::string err_msg = + "RandomResizedCrop: max_attempts must be greater than or equal to 1, got: " + std::to_string(max_attempts_); + MS_LOG(ERROR) << err_msg; + RETURN_STATUS_SYNTAX_ERROR(err_msg); + } return Status::OK(); } std::shared_ptr RandomResizedCropOperation::Build() { - int32_t height = size_[0], width = size_[0]; - if (size_.size() == 2) width = size_[1]; + int32_t height = size_[0]; + int32_t width = size_[0]; + // User specified the width value. + if (size_.size() == 2) { + width = size_[1]; + } std::shared_ptr tensor_op = std::make_shared( height, width, scale_[0], scale_[1], ratio_[0], ratio_[1], interpolation_, max_attempts_); return tensor_op; @@ -1549,6 +1584,55 @@ std::shared_ptr RandomRotationOperation::Build() { return tensor_op; } +// RandomSelectSubpolicyOperation. +RandomSelectSubpolicyOperation::RandomSelectSubpolicyOperation( + std::vector, double>>> policy) + : policy_(policy) {} + +Status RandomSelectSubpolicyOperation::ValidateParams() { + if (policy_.empty()) { + std::string err_msg = "RandomSelectSubpolicy: policy must not be empty"; + MS_LOG(ERROR) << err_msg; + RETURN_STATUS_SYNTAX_ERROR(err_msg); + } + for (int32_t i = 0; i < policy_.size(); i++) { + if (policy_[i].empty()) { + std::string err_msg = "RandomSelectSubpolicy: policy[" + std::to_string(i) + "] must not be empty"; + MS_LOG(ERROR) << err_msg; + RETURN_STATUS_SYNTAX_ERROR(err_msg); + } + for (int32_t j = 0; j < policy_[i].size(); j++) { + if (policy_[i][j].first == nullptr) { + std::string transform_pos = "[" + std::to_string(i) + "]" + "[" + std::to_string(j) + "]"; + std::string err_msg = "RandomSelectSubpolicy: transform in policy" + transform_pos + " must not be null"; + MS_LOG(ERROR) << err_msg; + RETURN_STATUS_SYNTAX_ERROR(err_msg); + } + if (policy_[i][j].second < 0.0 || policy_[i][j].second > 1.0) { + std::string transform_pos = "[" + std::to_string(i) + "]" + "[" + std::to_string(j) + "]"; + std::string err_msg = "RandomSelectSubpolicy: probability of transform in policy" + transform_pos + + " must be between 0.0 and 1.0, got: " + std::to_string(policy_[i][j].second); + MS_LOG(ERROR) << err_msg; + RETURN_STATUS_SYNTAX_ERROR(err_msg); + } + } + } + return Status::OK(); +} + +std::shared_ptr RandomSelectSubpolicyOperation::Build() { + std::vector policy_tensor_ops; + for (int32_t i = 0; i < policy_.size(); i++) { + Subpolicy sub_policy_tensor_ops; + for (int32_t j = 0; j < policy_[i].size(); j++) { + sub_policy_tensor_ops.push_back(std::make_pair(policy_[i][j].first->Build(), policy_[i][j].second)); + } + policy_tensor_ops.push_back(sub_policy_tensor_ops); + } + std::shared_ptr tensor_op = std::make_shared(policy_tensor_ops); + return tensor_op; +} + // Function to create RandomSharpness. RandomSharpnessOperation::RandomSharpnessOperation(std::vector degrees) : degrees_(degrees) {} @@ -1669,6 +1753,8 @@ Status ResizeOperation::ValidateParams() { } std::shared_ptr ResizeOperation::Build() { + // If size is a single value, the smaller edge of the image will be + // resized to this value with the same image aspect ratio. int32_t height = size_[0]; int32_t width = 0; @@ -1730,6 +1816,115 @@ std::shared_ptr RgbaToRgbOperation::Build() { return tensor_op; } +// SoftDvppDecodeRandomCropResizeJpegOperation +SoftDvppDecodeRandomCropResizeJpegOperation::SoftDvppDecodeRandomCropResizeJpegOperation(std::vector size, + std::vector scale, + std::vector ratio, + int32_t max_attempts) + : size_(size), scale_(scale), ratio_(ratio), max_attempts_(max_attempts) {} + +Status SoftDvppDecodeRandomCropResizeJpegOperation::ValidateParams() { + // size + if (size_.size() != 2 && size_.size() != 1) { + std::string err_msg = "SoftDvppDecodeRandomCropResizeJpeg: size must be a vector of one or two values, got: " + + std::to_string(size_.size()); + MS_LOG(ERROR) << err_msg; + RETURN_STATUS_SYNTAX_ERROR(err_msg); + } + if (size_[0] <= 0 || (size_.size() == 2 && size_[1] <= 0)) { + std::string err_msg = "SoftDvppDecodeRandomCropResizeJpeg: size must only contain positive integers."; + MS_LOG(ERROR) << "SoftDvppDecodeRandomCropResizeJpeg: size must only contain positive integers, got: " << size_; + RETURN_STATUS_SYNTAX_ERROR(err_msg); + } + // scale + if (scale_.size() != 2) { + std::string err_msg = + "SoftDvppDecodeRandomCropResizeJpeg: scale must be a vector of two values, got: " + std::to_string(scale_.size()); + MS_LOG(ERROR) << err_msg; + RETURN_STATUS_SYNTAX_ERROR(err_msg); + } + if (scale_[0] < 0 || scale_[1] < 0) { + std::string err_msg = "SoftDvppDecodeRandomCropResizeJpeg: scale must be greater than or equal to 0."; + MS_LOG(ERROR) << "SoftDvppDecodeRandomCropResizeJpeg: scale must be greater than or equal to 0, got: " << scale_; + RETURN_STATUS_SYNTAX_ERROR(err_msg); + } + if (scale_[1] < scale_[0]) { + std::string err_msg = "SoftDvppDecodeRandomCropResizeJpeg: scale must be in the format of (min, max)."; + MS_LOG(ERROR) << "SoftDvppDecodeRandomCropResizeJpeg: scale must be in the format of (min, max), but got: " + << scale_; + RETURN_STATUS_SYNTAX_ERROR(err_msg); + } + // ratio + if (ratio_.size() != 2) { + std::string err_msg = + "SoftDvppDecodeRandomCropResizeJpeg: ratio must be a vector of two values, got: " + std::to_string(ratio_.size()); + MS_LOG(ERROR) << err_msg; + RETURN_STATUS_SYNTAX_ERROR(err_msg); + } + if (ratio_[0] < 0 || ratio_[1] < 0) { + std::string err_msg = "SoftDvppDecodeRandomCropResizeJpeg: ratio must be greater than or equal to 0."; + MS_LOG(ERROR) << "SoftDvppDecodeRandomCropResizeJpeg: ratio must be greater than or equal to 0, got: " << ratio_; + RETURN_STATUS_SYNTAX_ERROR(err_msg); + } + if (ratio_[1] < ratio_[0]) { + std::string err_msg = "SoftDvppDecodeRandomCropResizeJpeg: ratio must be in the format of (min, max)."; + MS_LOG(ERROR) << "SoftDvppDecodeRandomCropResizeJpeg: ratio must be in the format of (min, max), but got: " + << ratio_; + RETURN_STATUS_SYNTAX_ERROR(err_msg); + } + // max_attempts + if (max_attempts_ < 1) { + std::string err_msg = "SoftDvppDecodeRandomCropResizeJpeg: max_attempts must be greater than or equal to 1, got: " + + std::to_string(max_attempts_); + MS_LOG(ERROR) << err_msg; + RETURN_STATUS_SYNTAX_ERROR(err_msg); + } + return Status::OK(); +} + +std::shared_ptr SoftDvppDecodeRandomCropResizeJpegOperation::Build() { + int32_t height = size_[0]; + int32_t width = size_[0]; + // User specified the width value. + if (size_.size() == 2) { + width = size_[1]; + } + + auto tensor_op = std::make_shared(height, width, scale_[0], scale_[1], + ratio_[0], ratio_[1], max_attempts_); + return tensor_op; +} + +// SoftDvppDecodeResizeJpegOperation +SoftDvppDecodeResizeJpegOperation::SoftDvppDecodeResizeJpegOperation(std::vector size) : size_(size) {} + +Status SoftDvppDecodeResizeJpegOperation::ValidateParams() { + // size + if (size_.empty() || size_.size() > 2) { + std::string err_msg = + "SoftDvppDecodeResizeJpeg: size must be a vector of one or two values, got: " + std::to_string(size_.size()); + MS_LOG(ERROR) << err_msg; + RETURN_STATUS_SYNTAX_ERROR(err_msg); + } + RETURN_IF_NOT_OK(ValidateVectorPositive("SoftDvppDecodeResizeJpeg", size_)); + + return Status::OK(); +} + +std::shared_ptr SoftDvppDecodeResizeJpegOperation::Build() { + // If size is a single value, the smaller edge of the image will be + // resized to this value with the same image aspect ratio. + int32_t height = size_[0]; + int32_t width = 0; + + // User specified the width value. + if (size_.size() == 2) { + width = size_[1]; + } + std::shared_ptr tensor_op = std::make_shared(height, width); + return tensor_op; +} + // SwapRedBlueOperation. SwapRedBlueOperation::SwapRedBlueOperation() {} diff --git a/mindspore/ccsrc/minddata/dataset/include/vision.h b/mindspore/ccsrc/minddata/dataset/include/vision.h index 05d9ae1d82..61131f663f 100644 --- a/mindspore/ccsrc/minddata/dataset/include/vision.h +++ b/mindspore/ccsrc/minddata/dataset/include/vision.h @@ -17,7 +17,9 @@ #ifndef MINDSPORE_CCSRC_MINDDATA_DATASET_INCLUDE_VISION_H_ #define MINDSPORE_CCSRC_MINDDATA_DATASET_INCLUDE_VISION_H_ +#include #include +#include #include #include "minddata/dataset/core/constants.h" #include "minddata/dataset/include/transforms.h" @@ -42,6 +44,7 @@ class CutOutOperation; #endif class DecodeOperation; #ifndef ENABLE_ANDROID +class EqualizeOperation; class HwcToChwOperation; class InvertOperation; class MixUpBatchOperation; @@ -58,8 +61,11 @@ class RandomCropWithBBoxOperation; class RandomHorizontalFlipOperation; class RandomHorizontalFlipWithBBoxOperation; class RandomPosterizeOperation; +class RandomResizeOperation; +class RandomResizeWithBBoxOperation; class RandomResizedCropOperation; class RandomRotationOperation; +class RandomSelectSubpolicyOperation; class RandomSharpnessOperation; class RandomSolarizeOperation; class RandomVerticalFlipOperation; @@ -71,6 +77,8 @@ class ResizeOperation; class ResizeWithBBoxOperation; class RgbaToBgrOperation; class RgbaToRgbOperation; +class SoftDvppDecodeRandomCropResizeJpegOperation; +class SoftDvppDecodeResizeJpegOperation; class SwapRedBlueOperation; class UniformAugOperation; @@ -129,6 +137,12 @@ std::shared_ptr CutOut(int32_t length, int32_t num_patches = 1) std::shared_ptr Decode(bool rgb = true); #ifndef ENABLE_ANDROID + +/// \brief Function to create a Equalize TensorOperation. +/// \notes Apply histogram equalization on input image. +/// \return Shared pointer to the current TensorOperation. +std::shared_ptr Equalize(); + /// \brief Function to create a HwcToChw TensorOperation. /// \notes Transpose the input image; shape (H, W, C) to shape (C, H, W). /// \return Shared pointer to the current TensorOperation. @@ -296,6 +310,21 @@ std::shared_ptr RandomHorizontalFlipWithB /// \return Shared pointer to the current TensorOperation. std::shared_ptr RandomPosterize(const std::vector &bit_range = {4, 8}); +/// \brief Function to create a RandomResize TensorOperation. +/// \notes Resize the input image using a randomly selected interpolation mode. +/// \param[in] size A vector representing the output size of the resized image. +/// If size is a single value, the smaller edge of the image will be resized to this value with +// the same image aspect ratio. If size has 2 values, it should be (height, width). +std::shared_ptr RandomResize(std::vector size); + +/// \brief Function to create a RandomResizeWithBBox TensorOperation. +/// \notes Resize the input image using a randomly selected interpolation mode and adjust +/// bounding boxes accordingly. +/// \param[in] size A vector representing the output size of the resized image. +/// If size is a single value, the smaller edge of the image will be resized to this value with +// the same image aspect ratio. If size has 2 values, it should be (height, width). +std::shared_ptr RandomResizeWithBBox(std::vector size); + /// \brief Function to create a RandomResizedCrop TensorOperation. /// \notes Crop the input image to a random size and aspect ratio. /// \param[in] size A vector representing the output size of the cropped image. @@ -325,6 +354,15 @@ std::shared_ptr RandomRotation( std::vector degrees, InterpolationMode resample = InterpolationMode::kNearestNeighbour, bool expand = false, std::vector center = {-1, -1}, std::vector fill_value = {0, 0, 0}); +/// \brief Function to create a RandomSelectSubpolicy TensorOperation. +/// \notes Choose a random sub-policy from a list to be applied on the input image. A sub-policy is a list of tuples +/// (op, prob), where op is a TensorOp operation and prob is the probability that this op will be applied. Once +/// a sub-policy is selected, each op within the subpolicy with be applied in sequence according to its probability. +/// \param[in] policy Vector of sub-policies to choose from. +/// \return Shared pointer to the current TensorOperation. +std::shared_ptr RandomSelectSubpolicy( + std::vector, double>>> policy); + /// \brief Function to create a RandomSharpness TensorOperation. /// \notes Tensor operation to perform random sharpness. /// \param[in] degrees A float vector of size 2, representing the starting and ending degree to uniformly @@ -390,6 +428,35 @@ std::shared_ptr RGBA2BGR(); /// \return Shared pointer to the current TensorOperation. std::shared_ptr RGBA2RGB(); +/// \brief Function to create a SoftDvppDecodeRandomCropResizeJpeg TensorOperation. +/// \notes Tensor operation to decode, random crop and resize JPEG image using the simulation algorithm of +/// Ascend series chip DVPP module. The usage scenario is consistent with SoftDvppDecodeResizeJpeg. +/// The input image size should be in range [32*32, 8192*8192]. +/// The zoom-out and zoom-in multiples of the image length and width should in the range [1/32, 16]. +/// Only images with an even resolution can be output. The output of odd resolution is not supported. +/// \param[in] size A vector representing the output size of the resized image. +/// If size is a single value, smaller edge of the image will be resized to this value with +/// the same image aspect ratio. If size has 2 values, it should be (height, width). +/// \return Shared pointer to the current TensorOperation. +std::shared_ptr SoftDvppDecodeRandomCropResizeJpeg( + std::vector size, std::vector scale = {0.08, 1.0}, std::vector ratio = {3. / 4., 4. / 3.}, + int32_t max_attempts = 10); + +/// \brief Function to create a SoftDvppDecodeResizeJpeg TensorOperation. +/// \notes Tensor operation to decode and resize JPEG image using the simulation algorithm of Ascend series +/// chip DVPP module. It is recommended to use this algorithm in the following scenarios: +/// When training, the DVPP of the Ascend chip is not used, +/// and the DVPP of the Ascend chip is used during inference, +/// and the accuracy of inference is lower than the accuracy of training; +/// and the input image size should be in range [32*32, 8192*8192]. +/// The zoom-out and zoom-in multiples of the image length and width should in the range [1/32, 16]. +/// Only images with an even resolution can be output. The output of odd resolution is not supported. +/// \param[in] size A vector representing the output size of the resized image. +/// If size is a single value, smaller edge of the image will be resized to this value with +/// the same image aspect ratio. If size has 2 values, it should be (height, width). +/// \return Shared pointer to the current TensorOperation. +std::shared_ptr SoftDvppDecodeResizeJpeg(std::vector size); + /// \brief Function to create a SwapRedBlue TensorOp /// \notes Swaps the red and blue channels in image /// \return Shared pointer to the current TensorOp @@ -512,6 +579,15 @@ class DecodeOperation : public TensorOperation { }; #ifndef ENABLE_ANDROID +class EqualizeOperation : public TensorOperation { + public: + ~EqualizeOperation() = default; + + std::shared_ptr Build() override; + + Status ValidateParams() override; +}; + class HwcToChwOperation : public TensorOperation { public: ~HwcToChwOperation() = default; @@ -735,6 +811,34 @@ class RandomPosterizeOperation : public TensorOperation { std::vector bit_range_; }; +class RandomResizeOperation : public TensorOperation { + public: + explicit RandomResizeOperation(std::vector size); + + ~RandomResizeOperation() = default; + + std::shared_ptr Build() override; + + Status ValidateParams() override; + + private: + std::vector size_; +}; + +class RandomResizeWithBBoxOperation : public TensorOperation { + public: + explicit RandomResizeWithBBoxOperation(std::vector size); + + ~RandomResizeWithBBoxOperation() = default; + + std::shared_ptr Build() override; + + Status ValidateParams() override; + + private: + std::vector size_; +}; + class RandomResizedCropOperation : public TensorOperation { public: explicit RandomResizedCropOperation(std::vector size, std::vector scale = {0.08, 1.0}, @@ -775,6 +879,21 @@ class RandomRotationOperation : public TensorOperation { std::vector fill_value_; }; +class RandomSelectSubpolicyOperation : public TensorOperation { + public: + explicit RandomSelectSubpolicyOperation( + std::vector, double>>> policy); + + ~RandomSelectSubpolicyOperation() = default; + + std::shared_ptr Build() override; + + Status ValidateParams() override; + + private: + std::vector, double>>> policy_; +}; + class RandomSharpnessOperation : public TensorOperation { public: explicit RandomSharpnessOperation(std::vector degrees = {0.1, 1.9}); @@ -902,6 +1021,38 @@ class RgbaToRgbOperation : public TensorOperation { Status ValidateParams() override; }; +class SoftDvppDecodeRandomCropResizeJpegOperation : public TensorOperation { + public: + explicit SoftDvppDecodeRandomCropResizeJpegOperation(std::vector size, std::vector scale, + std::vector ratio, int32_t max_attempts); + + ~SoftDvppDecodeRandomCropResizeJpegOperation() = default; + + std::shared_ptr Build() override; + + Status ValidateParams() override; + + private: + std::vector size_; + std::vector scale_; + std::vector ratio_; + int32_t max_attempts_; +}; + +class SoftDvppDecodeResizeJpegOperation : public TensorOperation { + public: + explicit SoftDvppDecodeResizeJpegOperation(std::vector size); + + ~SoftDvppDecodeResizeJpegOperation() = default; + + std::shared_ptr Build() override; + + Status ValidateParams() override; + + private: + std::vector size_; +}; + class SwapRedBlueOperation : public TensorOperation { public: SwapRedBlueOperation(); diff --git a/mindspore/dataset/vision/c_transforms.py b/mindspore/dataset/vision/c_transforms.py index 5047f00e56..5fb743db6b 100644 --- a/mindspore/dataset/vision/c_transforms.py +++ b/mindspore/dataset/vision/c_transforms.py @@ -1260,7 +1260,7 @@ class SoftDvppDecodeRandomCropResizeJpeg(cde.SoftDvppDecodeRandomCropResizeJpegO Tensor operation to decode, random crop and resize JPEG image using the simulation algorithm of Ascend series chip DVPP module. - The usage scenario is consistent with SoftDvppDecodeReiszeJpeg. + The usage scenario is consistent with SoftDvppDecodeResizeJpeg. The input image size should be in range [32*32, 8192*8192]. The zoom-out and zoom-in multiples of the image length and width should in the range [1/32, 16]. Only images with an even resolution can be output. The output of odd resolution is not supported. diff --git a/tests/ut/cpp/dataset/c_api_vision_test.cc b/tests/ut/cpp/dataset/c_api_vision_test.cc index 9c8d4bfe92..d13b3236fa 100644 --- a/tests/ut/cpp/dataset/c_api_vision_test.cc +++ b/tests/ut/cpp/dataset/c_api_vision_test.cc @@ -1640,6 +1640,208 @@ TEST_F(MindDataTestPipeline, TestRandomPosterizeSuccess2) { iter->Stop(); } +TEST_F(MindDataTestPipeline, TestRandomResizeSuccess1) { + MS_LOG(INFO) << "Doing MindDataTestPipeline-TestRandomResizeSuccess1 with single integer input."; + + // Create an ImageFolder Dataset + std::string folder_path = datasets_root_path_ + "/testPK/data/"; + std::shared_ptr ds = ImageFolder(folder_path, true, RandomSampler(false, 5)); + EXPECT_NE(ds, nullptr); + + // Create objects for the tensor ops + std::shared_ptr random_resize = vision::RandomResize({66}); + EXPECT_NE(random_resize, nullptr); + + // Create a Map operation on ds + ds = ds->Map({random_resize}, {"image"}); + EXPECT_NE(ds, nullptr); + + // Create an iterator over the result of the above dataset + // This will trigger the creation of the Execution Tree and launch it. + std::shared_ptr iter = ds->CreateIterator(); + EXPECT_NE(iter, nullptr); + + // Iterate the dataset and get each row + std::unordered_map> row; + iter->GetNextRow(&row); + + uint64_t i = 0; + while (row.size() != 0) { + i++; + auto image = row["image"]; + MS_LOG(INFO) << "Tensor image shape: " << image->shape(); + EXPECT_EQ(image->shape()[0] == 66, true); + iter->GetNextRow(&row); + } + + EXPECT_EQ(i, 5); + + // Manually terminate the pipeline + iter->Stop(); +} + +TEST_F(MindDataTestPipeline, TestRandomResizeSuccess2) { + MS_LOG(INFO) << "Doing MindDataTestPipeline-TestRandomResizeSuccess2 with (height, width) input."; + + // Create an ImageFolder Dataset + std::string folder_path = datasets_root_path_ + "/testPK/data/"; + std::shared_ptr ds = ImageFolder(folder_path, true, RandomSampler(false, 3)); + EXPECT_NE(ds, nullptr); + + // Create a Repeat operation on ds + int32_t repeat_num = 2; + ds = ds->Repeat(repeat_num); + EXPECT_NE(ds, nullptr); + + // Create objects for the tensor ops + std::shared_ptr random_resize = vision::RandomResize({66, 77}); + EXPECT_NE(random_resize, nullptr); + + // Create a Map operation on ds + ds = ds->Map({random_resize}, {"image"}); + EXPECT_NE(ds, nullptr); + + // Create an iterator over the result of the above dataset + // This will trigger the creation of the Execution Tree and launch it. + std::shared_ptr iter = ds->CreateIterator(); + EXPECT_NE(iter, nullptr); + + // Iterate the dataset and get each row + std::unordered_map> row; + iter->GetNextRow(&row); + + uint64_t i = 0; + while (row.size() != 0) { + i++; + auto image = row["image"]; + MS_LOG(INFO) << "Tensor image shape: " << image->shape(); + EXPECT_EQ(image->shape()[0] == 66 && image->shape()[1] == 77, true); + iter->GetNextRow(&row); + } + + EXPECT_EQ(i, 6); + + // Manually terminate the pipeline + iter->Stop(); +} + +TEST_F(MindDataTestPipeline, TestRandomResizeFail) { + MS_LOG(INFO) << "Doing MindDataTestPipeline-TestRandomResizeFail incorrect size."; + + // RandomResize : size must only contain positive integers + std::shared_ptr random_resize1 = vision::RandomResize({-66, 77}); + EXPECT_EQ(random_resize1, nullptr); + + // RandomResize : size must be a vector of one or two values + std::shared_ptr random_resize2 = vision::RandomResize({1, 2, 3}); + EXPECT_EQ(random_resize2, nullptr); + + // RandomResize : size must be a vector of one or two values + std::shared_ptr random_resize3 = vision::RandomResize({}); + EXPECT_EQ(random_resize3, nullptr); +} + +TEST_F(MindDataTestPipeline, TestRandomResizeWithBBoxSuccess1) { + MS_LOG(INFO) << "Doing MindDataTestPipeline-TestRandomResizeWithBBoxSuccess1 with single integer input."; + + // Create an VOC Dataset + std::string folder_path = datasets_root_path_ + "/testVOC2012_2"; + std::shared_ptr ds = VOC(folder_path, "Detection", "train", {}, true, SequentialSampler(0, 3)); + EXPECT_NE(ds, nullptr); + + // Create objects for the tensor ops + std::shared_ptr random_resize = vision::RandomResizeWithBBox({88}); + EXPECT_NE(random_resize, nullptr); + + // Create a Map operation on ds + ds = ds->Map({random_resize}, {"image", "bbox"}); + EXPECT_NE(ds, nullptr); + + // Create an iterator over the result of the above dataset + // This will trigger the creation of the Execution Tree and launch it. + std::shared_ptr iter = ds->CreateIterator(); + EXPECT_NE(iter, nullptr); + + // Iterate the dataset and get each row + std::unordered_map> row; + iter->GetNextRow(&row); + + uint64_t i = 0; + while (row.size() != 0) { + i++; + auto image = row["image"]; + MS_LOG(INFO) << "Tensor image shape: " << image->shape(); + EXPECT_EQ(image->shape()[0] == 88, true); + iter->GetNextRow(&row); + } + + EXPECT_EQ(i, 3); + + // Manually terminate the pipeline + iter->Stop(); +} + +TEST_F(MindDataTestPipeline, TestRandomResizeWithBBoxSuccess2) { + MS_LOG(INFO) << "Doing MindDataTestPipeline-TestRandomResizeWithBBoxSuccess2 with (height, width) input."; + + // Create an VOC Dataset + std::string folder_path = datasets_root_path_ + "/testVOC2012_2"; + std::shared_ptr ds = VOC(folder_path, "Detection", "train", {}, true, SequentialSampler(0, 4)); + EXPECT_NE(ds, nullptr); + + // Create a Repeat operation on ds + int32_t repeat_num = 2; + ds = ds->Repeat(repeat_num); + EXPECT_NE(ds, nullptr); + + // Create objects for the tensor ops + std::shared_ptr random_resize = vision::RandomResizeWithBBox({88, 99}); + EXPECT_NE(random_resize, nullptr); + + // Create a Map operation on ds + ds = ds->Map({random_resize}, {"image", "bbox"}); + EXPECT_NE(ds, nullptr); + + // Create an iterator over the result of the above dataset + // This will trigger the creation of the Execution Tree and launch it. + std::shared_ptr iter = ds->CreateIterator(); + EXPECT_NE(iter, nullptr); + + // Iterate the dataset and get each row + std::unordered_map> row; + iter->GetNextRow(&row); + + uint64_t i = 0; + while (row.size() != 0) { + i++; + auto image = row["image"]; + MS_LOG(INFO) << "Tensor image shape: " << image->shape(); + EXPECT_EQ(image->shape()[0] == 88 && image->shape()[1] == 99, true); + iter->GetNextRow(&row); + } + + EXPECT_EQ(i, 8); + + // Manually terminate the pipeline + iter->Stop(); +} + +TEST_F(MindDataTestPipeline, TestRandomResizeWithBBoxFail) { + MS_LOG(INFO) << "Doing MindDataTestPipeline-TestRandomResizeWithBBoxFail incorrect size."; + + // RandomResizeWithBBox : size must only contain positive integers + std::shared_ptr random_resize_with_bbox1 = vision::RandomResizeWithBBox({-66, 77}); + EXPECT_EQ(random_resize_with_bbox1, nullptr); + + // RandomResizeWithBBox : size must be a vector of one or two values + std::shared_ptr random_resize_with_bbox2 = vision::RandomResizeWithBBox({1, 2, 3}); + EXPECT_EQ(random_resize_with_bbox2, nullptr); + + // RandomResizeWithBBox : size must be a vector of one or two values + std::shared_ptr random_resize_with_bbox3 = vision::RandomResizeWithBBox({}); + EXPECT_EQ(random_resize_with_bbox3, nullptr); +} + TEST_F(MindDataTestPipeline, TestRandomResizedCropSuccess1) { // Testing RandomResizedCrop with default values // Create a Cifar10 Dataset @@ -1864,6 +2066,75 @@ TEST_F(MindDataTestPipeline, TestRandomRotationFail) { EXPECT_EQ(random_rotation_op6, nullptr); } +TEST_F(MindDataTestPipeline, TestRandomSelectSubpolicySuccess) { + MS_LOG(INFO) << "Doing MindDataTestPipeline-TestRandomSelectSubpolicySuccess."; + + // Create an ImageFolder Dataset + std::string folder_path = datasets_root_path_ + "/testPK/data/"; + std::shared_ptr ds = ImageFolder(folder_path, true, RandomSampler(false, 7)); + EXPECT_NE(ds, nullptr); + + // Create objects for the tensor ops + // Valid case: TensorOperation is not null and probability is between (0,1) + std::shared_ptr random_select_subpolicy = vision::RandomSelectSubpolicy( + {{{vision::Invert(), 0.5}, {vision::Equalize(), 0.5}}, {{vision::Resize({15, 15}), 1}}}); + EXPECT_NE(random_select_subpolicy, nullptr); + + // Create a Map operation on ds + ds = ds->Map({random_select_subpolicy}); + EXPECT_NE(ds, nullptr); + + // Create an iterator over the result of the above dataset + // This will trigger the creation of the Execution Tree and launch it. + std::shared_ptr iter = ds->CreateIterator(); + EXPECT_NE(iter, nullptr); + + // Iterate the dataset and get each row + std::unordered_map> row; + iter->GetNextRow(&row); + + uint64_t i = 0; + while (row.size() != 0) { + i++; + auto image = row["image"]; + MS_LOG(INFO) << "Tensor image shape: " << image->shape(); + iter->GetNextRow(&row); + } + + EXPECT_EQ(i, 7); + + // Manually terminate the pipeline + iter->Stop(); +} + +TEST_F(MindDataTestPipeline, TestRandomSelectSubpolicyFail) { + MS_LOG(INFO) << "Doing MindDataTestPipeline-TestRandomSelectSubpolicyFail."; + + // RandomSelectSubpolicy : probability of transform must be between 0.0 and 1.0 + std::shared_ptr random_select_subpolicy1 = vision::RandomSelectSubpolicy( + {{{vision::Invert(), 1.5}, {vision::Equalize(), 0.5}}, {{vision::Resize({15, 15}), 1}}}); + EXPECT_EQ(random_select_subpolicy1, nullptr); + + // RandomSelectSubpolicy: policy must not be empty + std::shared_ptr random_select_subpolicy2 = vision::RandomSelectSubpolicy( + {{{vision::Invert(), 0.5}, {vision::Equalize(), 0.5}}, {{nullptr, 1}}}); + EXPECT_EQ(random_select_subpolicy2, nullptr); + + // RandomSelectSubpolicy: policy must not be empty + std::shared_ptr random_select_subpolicy3 = vision::RandomSelectSubpolicy({}); + EXPECT_EQ(random_select_subpolicy3, nullptr); + + // RandomSelectSubpolicy: policy must not be empty + std::shared_ptr random_select_subpolicy4 = vision::RandomSelectSubpolicy( + {{{vision::Invert(), 0.5}, {vision::Equalize(), 0.5}}, {}}); + EXPECT_EQ(random_select_subpolicy4, nullptr); + + // RandomSelectSubpolicy: policy must not be empty + std::shared_ptr random_select_subpolicy5 = vision::RandomSelectSubpolicy( + {{{}, {vision::Equalize(), 0.5}}, {{vision::Resize({15, 15}), 1}}}); + EXPECT_EQ(random_select_subpolicy5, nullptr); +} + TEST_F(MindDataTestPipeline, TestRandomSharpness) { MS_LOG(INFO) << "Doing MindDataTestPipeline-TestRandomSharpness."; @@ -2297,6 +2568,237 @@ TEST_F(MindDataTestPipeline, TestRescaleFail) { EXPECT_EQ(rescale, nullptr); } +TEST_F(MindDataTestPipeline, TestSoftDvppDecodeRandomCropResizeJpegSuccess1) { + MS_LOG(INFO) << "Doing MindDataTestPipeline-TestSoftDvppDecodeRandomCropResizeJpegSuccess1 with single integer input."; + + // Create an ImageFolder Dataset + std::string folder_path = datasets_root_path_ + "/testPK/data/"; + std::shared_ptr ds = ImageFolder(folder_path, false, RandomSampler(false, 4)); + EXPECT_NE(ds, nullptr); + + // Create objects for the tensor ops + std::shared_ptr soft_dvpp_decode_random_crop_resize_jpeg = + vision::SoftDvppDecodeRandomCropResizeJpeg({500}); + EXPECT_NE(soft_dvpp_decode_random_crop_resize_jpeg, nullptr); + + // Create a Map operation on ds + ds = ds->Map({soft_dvpp_decode_random_crop_resize_jpeg}, {"image"}); + EXPECT_NE(ds, nullptr); + + // Create an iterator over the result of the above dataset + // This will trigger the creation of the Execution Tree and launch it. + std::shared_ptr iter = ds->CreateIterator(); + EXPECT_NE(iter, nullptr); + + // Iterate the dataset and get each row + std::unordered_map> row; + iter->GetNextRow(&row); + + uint64_t i = 0; + while (row.size() != 0) { + i++; + auto image = row["image"]; + MS_LOG(INFO) << "Tensor image shape: " << image->shape(); + EXPECT_EQ(image->shape()[0] == 500 && image->shape()[1] == 500, true); + iter->GetNextRow(&row); + } + + EXPECT_EQ(i, 4); + + // Manually terminate the pipeline + iter->Stop(); +} + +TEST_F(MindDataTestPipeline, TestSoftDvppDecodeRandomCropResizeJpegSuccess2) { + MS_LOG(INFO) << "Doing MindDataTestPipeline-TestSoftDvppDecodeRandomCropResizeJpegSuccess2 with (height, width) input."; + + // Create an ImageFolder Dataset + std::string folder_path = datasets_root_path_ + "/testPK/data/"; + std::shared_ptr ds = ImageFolder(folder_path, false, RandomSampler(false, 6)); + EXPECT_NE(ds, nullptr); + + // Create objects for the tensor ops + std::shared_ptr soft_dvpp_decode_random_crop_resize_jpeg = + vision::SoftDvppDecodeRandomCropResizeJpeg({500, 600}, {0.25, 0.75}, {0.5, 1.25}, 20); + EXPECT_NE(soft_dvpp_decode_random_crop_resize_jpeg, nullptr); + + // Create a Map operation on ds + ds = ds->Map({soft_dvpp_decode_random_crop_resize_jpeg}, {"image"}); + EXPECT_NE(ds, nullptr); + + // Create an iterator over the result of the above dataset + // This will trigger the creation of the Execution Tree and launch it. + std::shared_ptr iter = ds->CreateIterator(); + EXPECT_NE(iter, nullptr); + + // Iterate the dataset and get each row + std::unordered_map> row; + iter->GetNextRow(&row); + + uint64_t i = 0; + while (row.size() != 0) { + i++; + auto image = row["image"]; + MS_LOG(INFO) << "Tensor image shape: " << image->shape(); + EXPECT_EQ(image->shape()[0] == 500 && image->shape()[1] == 600, true); + iter->GetNextRow(&row); + } + + EXPECT_EQ(i, 6); + + // Manually terminate the pipeline + iter->Stop(); +} + +TEST_F(MindDataTestPipeline, TestSoftDvppDecodeRandomCropResizeJpegFail) { + MS_LOG(INFO) << "Doing MindDataTestPipeline-TestSoftDvppDecodeRandomCropResizeJpegFail with incorrect parameters."; + + // SoftDvppDecodeRandomCropResizeJpeg: size must only contain positive integers + auto soft_dvpp_decode_random_crop_resize_jpeg1 = vision::SoftDvppDecodeRandomCropResizeJpeg({-500, 600}); + EXPECT_EQ(soft_dvpp_decode_random_crop_resize_jpeg1, nullptr); + + // SoftDvppDecodeRandomCropResizeJpeg: size must only contain positive integers + auto soft_dvpp_decode_random_crop_resize_jpeg2 = vision::SoftDvppDecodeRandomCropResizeJpeg({-500}); + EXPECT_EQ(soft_dvpp_decode_random_crop_resize_jpeg2, nullptr); + + // SoftDvppDecodeRandomCropResizeJpeg: size must be a vector of one or two values + auto soft_dvpp_decode_random_crop_resize_jpeg3 = vision::SoftDvppDecodeRandomCropResizeJpeg({500, 600, 700}); + EXPECT_EQ(soft_dvpp_decode_random_crop_resize_jpeg3, nullptr); + + // SoftDvppDecodeRandomCropResizeJpeg: scale must be greater than or equal to 0 + auto soft_dvpp_decode_random_crop_resize_jpeg4 = vision::SoftDvppDecodeRandomCropResizeJpeg({500}, {-0.1, 0.9}); + EXPECT_EQ(soft_dvpp_decode_random_crop_resize_jpeg4, nullptr); + + // SoftDvppDecodeRandomCropResizeJpeg: scale must be in the format of (min, max) + auto soft_dvpp_decode_random_crop_resize_jpeg5 = vision::SoftDvppDecodeRandomCropResizeJpeg({500}, {0.6, 0.2}); + EXPECT_EQ(soft_dvpp_decode_random_crop_resize_jpeg5, nullptr); + + // SoftDvppDecodeRandomCropResizeJpeg: scale must be a vector of two values + auto soft_dvpp_decode_random_crop_resize_jpeg6 = vision::SoftDvppDecodeRandomCropResizeJpeg({500}, {0.5, 0.6, 0.7}); + EXPECT_EQ(soft_dvpp_decode_random_crop_resize_jpeg6, nullptr); + + // SoftDvppDecodeRandomCropResizeJpeg: ratio must be greater than or equal to 0 + auto soft_dvpp_decode_random_crop_resize_jpeg7 = + vision::SoftDvppDecodeRandomCropResizeJpeg({500}, {0.5, 0.9}, {-0.2, 0.4}); + EXPECT_EQ(soft_dvpp_decode_random_crop_resize_jpeg7, nullptr); + + // SoftDvppDecodeRandomCropResizeJpeg: ratio must be in the format of (min, max) + auto soft_dvpp_decode_random_crop_resize_jpeg8 = + vision::SoftDvppDecodeRandomCropResizeJpeg({500}, {0.5, 0.9}, {0.4, 0.2}); + EXPECT_EQ(soft_dvpp_decode_random_crop_resize_jpeg8, nullptr); + + // SoftDvppDecodeRandomCropResizeJpeg: ratio must be a vector of two values + auto soft_dvpp_decode_random_crop_resize_jpeg9 = + vision::SoftDvppDecodeRandomCropResizeJpeg({500}, {0.5, 0.9}, {0.1, 0.2, 0.3}); + EXPECT_EQ(soft_dvpp_decode_random_crop_resize_jpeg9, nullptr); + + // SoftDvppDecodeRandomCropResizeJpeg: max_attempts must be greater than or equal to 1 + auto soft_dvpp_decode_random_crop_resize_jpeg10 = + vision::SoftDvppDecodeRandomCropResizeJpeg({500}, {0.5, 0.9}, {0.1, 0.2}, 0); + EXPECT_EQ(soft_dvpp_decode_random_crop_resize_jpeg10, nullptr); +} + +TEST_F(MindDataTestPipeline, TestSoftDvppDecodeResizeJpegSuccess1) { + MS_LOG(INFO) << "Doing MindDataTestPipeline-TestSoftDvppDecodeResizeJpegSuccess1 with single integer input."; + // Create an ImageFolder Dataset + std::string folder_path = datasets_root_path_ + "/testPK/data/"; + std::shared_ptr ds = ImageFolder(folder_path, false, RandomSampler(false, 4)); + EXPECT_NE(ds, nullptr); + + // Create a Repeat operation on ds + int32_t repeat_num = 3; + ds = ds->Repeat(repeat_num); + EXPECT_NE(ds, nullptr); + + // Create SoftDvppDecodeResizeJpeg object with single integer input + std::shared_ptr soft_dvpp_decode_resize_jpeg_op = vision::SoftDvppDecodeResizeJpeg({1134}); + EXPECT_NE(soft_dvpp_decode_resize_jpeg_op, nullptr); + + // Create a Map operation on ds + ds = ds->Map({soft_dvpp_decode_resize_jpeg_op}); + EXPECT_NE(ds, nullptr); + + // Create an iterator over the result of the above dataset + // This will trigger the creation of the Execution Tree and launch it. + std::shared_ptr iter = ds->CreateIterator(); + EXPECT_NE(iter, nullptr); + + // Iterate the dataset and get each row + std::unordered_map> row; + iter->GetNextRow(&row); + + uint64_t i = 0; + while (row.size() != 0) { + i++; + auto image = row["image"]; + MS_LOG(INFO) << "Tensor image shape: " << image->shape(); + iter->GetNextRow(&row); + } + + EXPECT_EQ(i, 12); + + // Manually terminate the pipeline + iter->Stop(); +} + +TEST_F(MindDataTestPipeline, TestSoftDvppDecodeResizeJpegSuccess2) { + MS_LOG(INFO) << "Doing MindDataTestPipeline-TestSoftDvppDecodeResizeJpegSuccess2 with (height, width) input."; + // Create an ImageFolder Dataset + std::string folder_path = datasets_root_path_ + "/testPK/data/"; + std::shared_ptr ds = ImageFolder(folder_path, false, RandomSampler(false, 2)); + EXPECT_NE(ds, nullptr); + + // Create SoftDvppDecodeResizeJpeg object with single integer input + std::shared_ptr soft_dvpp_decode_resize_jpeg_op = vision::SoftDvppDecodeResizeJpeg({100, 200}); + EXPECT_NE(soft_dvpp_decode_resize_jpeg_op, nullptr); + + // Create a Map operation on ds + ds = ds->Map({soft_dvpp_decode_resize_jpeg_op}); + EXPECT_NE(ds, nullptr); + + // Create an iterator over the result of the above dataset + // This will trigger the creation of the Execution Tree and launch it. + std::shared_ptr iter = ds->CreateIterator(); + EXPECT_NE(iter, nullptr); + + // Iterate the dataset and get each row + std::unordered_map> row; + iter->GetNextRow(&row); + + uint64_t i = 0; + while (row.size() != 0) { + i++; + auto image = row["image"]; + MS_LOG(INFO) << "Tensor image shape: " << image->shape(); + iter->GetNextRow(&row); + } + + EXPECT_EQ(i, 2); + + // Manually terminate the pipeline + iter->Stop(); +} + +TEST_F(MindDataTestPipeline, TestSoftDvppDecodeResizeJpegFail) { + MS_LOG(INFO) << "Doing MindDataTestPipeline-TestSoftDvppDecodeResizeJpegFail with incorrect size."; + + // CSoftDvppDecodeResizeJpeg: size must be a vector of one or two values + std::shared_ptr soft_dvpp_decode_resize_jpeg_op1 = vision::SoftDvppDecodeResizeJpeg({}); + EXPECT_EQ(soft_dvpp_decode_resize_jpeg_op1, nullptr); + + // SoftDvppDecodeResizeJpeg: size must be a vector of one or two values + std::shared_ptr soft_dvpp_decode_resize_jpeg_op2 = vision::SoftDvppDecodeResizeJpeg({1, 2, 3}); + EXPECT_EQ(soft_dvpp_decode_resize_jpeg_op2, nullptr); + + // SoftDvppDecodeResizeJpeg: size must only contain positive integers + std::shared_ptr soft_dvpp_decode_resize_jpeg_op3 = vision::SoftDvppDecodeResizeJpeg({20, -20}); + EXPECT_EQ(soft_dvpp_decode_resize_jpeg_op3, nullptr); + + // SoftDvppDecodeResizeJpeg: size must only contain positive integers + std::shared_ptr soft_dvpp_decode_resize_jpeg_op4 = vision::SoftDvppDecodeResizeJpeg({0}); + EXPECT_EQ(soft_dvpp_decode_resize_jpeg_op4, nullptr); +} + TEST_F(MindDataTestPipeline, DISABLED_TestUniformAugmentFail1) { MS_LOG(INFO) << "Doing MindDataTestPipeline-TestUniformAugmentFail1 with invalid zero num_ops parameter.";