From 87b108f4e06abde5f1cd065948eea2278de2763d Mon Sep 17 00:00:00 2001 From: shenwei41 Date: Tue, 13 Oct 2020 11:02:48 +0800 Subject: [PATCH] C++ api add Rescale --- .../ccsrc/minddata/dataset/api/vision.cc | 27 ++++++ .../ccsrc/minddata/dataset/include/vision.h | 23 +++++ tests/ut/cpp/dataset/c_api_vision_test.cc | 90 +++++++++++++++++++ 3 files changed, 140 insertions(+) diff --git a/mindspore/ccsrc/minddata/dataset/api/vision.cc b/mindspore/ccsrc/minddata/dataset/api/vision.cc index dda6ff7454..eba3bc3089 100644 --- a/mindspore/ccsrc/minddata/dataset/api/vision.cc +++ b/mindspore/ccsrc/minddata/dataset/api/vision.cc @@ -39,6 +39,7 @@ #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" +#include "minddata/dataset/kernels/image/rescale_op.h" #include "minddata/dataset/kernels/image/resize_op.h" #include "minddata/dataset/kernels/image/rgba_to_bgr_op.h" #include "minddata/dataset/kernels/image/rgba_to_rgb_op.h" @@ -277,6 +278,16 @@ std::shared_ptr RandomVerticalFlip(float prob) { return op; } +// 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; +} + // Function to create ResizeOperation. std::shared_ptr Resize(std::vector size, InterpolationMode interpolation) { auto op = std::make_shared(size, interpolation); @@ -977,6 +988,22 @@ std::shared_ptr RandomVerticalFlipOperation::Build() { return tensor_op; } +// RescaleOperation +RescaleOperation::RescaleOperation(float rescale, float shift) : rescale_(rescale), shift_(shift) {} + +bool RescaleOperation::ValidateParams() { + if (rescale_ < 0) { + MS_LOG(ERROR) << "Rescale: rescale must be greater than or equal to 0, got: rescale = " << rescale_; + return false; + } + return true; +} + +std::shared_ptr RescaleOperation::Build() { + std::shared_ptr tensor_op = std::make_shared(rescale_, shift_); + return tensor_op; +} + // ResizeOperation ResizeOperation::ResizeOperation(std::vector size, InterpolationMode interpolation) : size_(size), interpolation_(interpolation) {} diff --git a/mindspore/ccsrc/minddata/dataset/include/vision.h b/mindspore/ccsrc/minddata/dataset/include/vision.h index 46c9d6bdba..409fc4e218 100644 --- a/mindspore/ccsrc/minddata/dataset/include/vision.h +++ b/mindspore/ccsrc/minddata/dataset/include/vision.h @@ -50,6 +50,7 @@ class RandomRotationOperation; class RandomSharpnessOperation; class RandomSolarizeOperation; class RandomVerticalFlipOperation; +class RescaleOperation; class ResizeOperation; class RgbaToBgrOperation; class RgbaToRgbOperation; @@ -257,6 +258,13 @@ std::shared_ptr RandomSolarize(std::vector thr /// \return Shared pointer to the current TensorOperation. std::shared_ptr RandomVerticalFlip(float prob = 0.5); +/// \brief Function to create a RescaleOperation TensorOperation. +/// \notes Tensor operation to rescale the input image. +/// \param[in] rescale Rescale factor. +/// \param[in] shift Shift factor. +/// \return Shared pointer to the current TensorOperation. +std::shared_ptr Rescale(float rescale, float shift); + /// \brief Function to create a Resize TensorOperation. /// \notes Resize the input image to the given size. /// \param[in] size - a vector representing the output size of the resized image. @@ -606,6 +614,21 @@ class RandomVerticalFlipOperation : public TensorOperation { float probability_; }; +class RescaleOperation : public TensorOperation { + public: + explicit RescaleOperation(float rescale, float shift); + + ~RescaleOperation() = default; + + std::shared_ptr Build() override; + + bool ValidateParams() override; + + private: + float rescale_; + float shift_; +}; + class ResizeOperation : public TensorOperation { public: explicit ResizeOperation(std::vector size, diff --git a/tests/ut/cpp/dataset/c_api_vision_test.cc b/tests/ut/cpp/dataset/c_api_vision_test.cc index ba9a275ece..db5d9e078c 100644 --- a/tests/ut/cpp/dataset/c_api_vision_test.cc +++ b/tests/ut/cpp/dataset/c_api_vision_test.cc @@ -1427,3 +1427,93 @@ TEST_F(MindDataTestPipeline, TestRandomCropDecodeResizeFail) { mindspore::dataset::InterpolationMode::kLinear, 0); EXPECT_EQ(random_crop_decode_resize_6, nullptr); } + +TEST_F(MindDataTestPipeline, TestRescaleSucess1) { + MS_LOG(INFO) << "Doing MindDataTestPipeline-TestRescaleSucess1."; + // Create an ImageFolder Dataset + std::string folder_path = datasets_root_path_ + "/testPK/data/"; + std::shared_ptr ds = ImageFolder(folder_path, true, SequentialSampler(0, 1)); + 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); + + auto image = row["image"]; + + // Create objects for the tensor ops + std::shared_ptr rescale = mindspore::dataset::api::vision::Rescale(1.0, 0.0); + EXPECT_NE(rescale, nullptr); + + // Convert to the same type + std::shared_ptr type_cast = transforms::TypeCast("uint8"); + EXPECT_NE(type_cast, nullptr); + + ds = ds->Map({rescale, type_cast}, {"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 iter1 = ds->CreateIterator(); + EXPECT_NE(iter1, nullptr); + + // Iterate the dataset and get each row1 + std::unordered_map> row1; + iter1->GetNextRow(&row1); + + auto image1 = row1["image"]; + + EXPECT_EQ(*image, *image1); + + // Manually terminate the pipeline + iter1->Stop(); +} + +TEST_F(MindDataTestPipeline, TestRescaleSucess2) { + MS_LOG(INFO) << "Doing MindDataTestPipeline-TestRescaleSucess2 with different params."; + // Create an ImageFolder Dataset + std::string folder_path = datasets_root_path_ + "/testPK/data/"; + std::shared_ptr ds = ImageFolder(folder_path, true, RandomSampler(false, 1)); + EXPECT_NE(ds, nullptr); + + // Create objects for the tensor ops + std::shared_ptr rescale = mindspore::dataset::api::vision::Rescale(1.0 / 255, 1.0); + EXPECT_NE(rescale, nullptr); + + ds = ds->Map({rescale}, {"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(); + iter->GetNextRow(&row); + } + + EXPECT_EQ(i, 1); + + // Manually terminate the pipeline + iter->Stop(); +} + +TEST_F(MindDataTestPipeline, TestRescaleFail) { + MS_LOG(INFO) << "Doing MindDataTestPipeline-TestRescaleSucess3 with invalid params."; + // incorrect negative rescale parameter + std::shared_ptr rescale = mindspore::dataset::api::vision::Rescale(-1.0, 0.0); + EXPECT_EQ(rescale, nullptr); +} \ No newline at end of file