dataset: C++ API Vision support for Ops with TensorTransform op input

plus UTs
pull/12612/head
Cathy Wong 4 years ago
parent f1c7aeaa6b
commit 2f1f0c438d

@ -39,7 +39,7 @@ namespace dataset {
// Transform operations for computer vision.
namespace vision {
#ifndef ENABLE_ANDROID
// FUNCTIONS TO CREATE VISION TRANSFORM OPERATIONS
// CONSTRUCTORS FOR API CLASSES TO CREATE VISION TENSOR TRANSFORM OPERATIONS
// (In alphabetical order)
Affine::Affine(float_t degrees, const std::vector<float> &translation, float scale, const std::vector<float> &shear,
@ -63,16 +63,23 @@ std::shared_ptr<TensorOperation> AutoContrast::Parse() {
}
// BoundingBoxAugment Transform Operation.
BoundingBoxAugment::BoundingBoxAugment(std::shared_ptr<TensorTransform> transform, float ratio) {
// Convert transform from TensorTransform to TensorOperation
transform_ = transform->Parse();
ratio_ = ratio;
BoundingBoxAugment::BoundingBoxAugment(TensorTransform *transform, float ratio) : ratio_(ratio) {
transform_ = transform ? transform->Parse() : nullptr;
}
BoundingBoxAugment::BoundingBoxAugment(const std::shared_ptr<TensorTransform> &transform, float ratio) : ratio_(ratio) {
transform_ = transform ? transform->Parse() : nullptr;
}
BoundingBoxAugment::BoundingBoxAugment(const std::reference_wrapper<TensorTransform> transform, float ratio)
: ratio_(ratio) {
transform_ = transform.get().Parse();
}
std::shared_ptr<TensorOperation> BoundingBoxAugment::Parse() {
return std::make_shared<BoundingBoxAugmentOperation>(transform_, ratio_);
}
#endif
#endif // not ENABLE_ANDROID
// CenterCrop Transform Operation.
CenterCrop::CenterCrop(std::vector<int32_t> size) : size_(size) {}
@ -86,7 +93,7 @@ std::shared_ptr<TensorOperation> CenterCrop::Parse(const MapTargetDevice &env) {
usize_.reserve(size_.size());
std::transform(size_.begin(), size_.end(), std::back_inserter(usize_), [](int32_t i) { return (uint32_t)i; });
return std::make_shared<DvppCropJpegOperation>(usize_);
#endif
#endif // ENABLE_ACL
}
return std::make_shared<CenterCropOperation>(size_);
}
@ -109,6 +116,7 @@ std::shared_ptr<TensorOperation> CutMixBatch::Parse() {
CutOut::CutOut(int32_t length, int32_t num_patches) : length_(length), num_patches_(num_patches) {}
std::shared_ptr<TensorOperation> CutOut::Parse() { return std::make_shared<CutOutOperation>(length_, num_patches_); }
#endif // not ENABLE_ANDROID
// Decode Transform Operation.
Decode::Decode(bool rgb) : rgb_(rgb) {}
@ -118,13 +126,11 @@ std::shared_ptr<TensorOperation> Decode::Parse(const MapTargetDevice &env) {
if (env == MapTargetDevice::kAscend310) {
#ifdef ENABLE_ACL
return std::make_shared<DvppDecodeJpegOperation>();
#endif
#endif // ENABLE_ACL
}
return std::make_shared<DecodeOperation>(rgb_);
}
#endif
#ifdef ENABLE_ACL
// DvppDecodeResize Transform Operation.
DvppDecodeResizeJpeg::DvppDecodeResizeJpeg(std::vector<uint32_t> resize) : resize_(resize) {}
@ -157,7 +163,7 @@ std::shared_ptr<TensorOperation> DvppDecodePng::Parse() { return std::make_share
std::shared_ptr<TensorOperation> DvppDecodePng::Parse(const MapTargetDevice &env) {
return std::make_shared<DvppDecodePngOperation>();
}
#endif
#endif // ENABLE_ACL
#ifndef ENABLE_ANDROID
// Equalize Transform Operation.
@ -178,7 +184,7 @@ std::shared_ptr<TensorOperation> Invert::Parse() { return std::make_shared<Inver
MixUpBatch::MixUpBatch(float alpha) : alpha_(alpha) {}
std::shared_ptr<TensorOperation> MixUpBatch::Parse() { return std::make_shared<MixUpBatchOperation>(alpha_); }
#endif
#endif // not ENABLE_ANDROID
// Normalize Transform Operation.
Normalize::Normalize(std::vector<float> mean, std::vector<float> std) : mean_(mean), std_(std) {}
@ -333,10 +339,49 @@ std::shared_ptr<TensorOperation> RandomRotation::Parse() {
}
// RandomSelectSubpolicy Transform Operation.
// FIXME - Provide TensorTransform support for policy
RandomSelectSubpolicy::RandomSelectSubpolicy(std::vector<std::vector<std::pair<TensorTransform *, double>>> policy) {
for (int32_t i = 0; i < policy.size(); i++) {
std::vector<std::pair<std::shared_ptr<TensorOperation>, double>> subpolicy;
for (int32_t j = 0; j < policy[i].size(); j++) {
TensorTransform *op = policy[i][j].first;
std::shared_ptr<TensorOperation> operation = (op ? op->Parse() : nullptr);
double prob = policy[i][j].second;
subpolicy.emplace_back(std::move(std::make_pair(operation, prob)));
}
policy_.emplace_back(subpolicy);
}
}
RandomSelectSubpolicy::RandomSelectSubpolicy(
std::vector<std::vector<std::pair<std::shared_ptr<TensorTransform>, double>>> policy) {
for (int32_t i = 0; i < policy.size(); i++) {
std::vector<std::pair<std::shared_ptr<TensorOperation>, double>> subpolicy;
for (int32_t j = 0; j < policy[i].size(); j++) {
std::shared_ptr<TensorTransform> op = policy[i][j].first;
std::shared_ptr<TensorOperation> operation = (op ? op->Parse() : nullptr);
double prob = policy[i][j].second;
subpolicy.emplace_back(std::move(std::make_pair(operation, prob)));
}
policy_.emplace_back(subpolicy);
}
}
RandomSelectSubpolicy::RandomSelectSubpolicy(
std::vector<std::vector<std::pair<std::shared_ptr<TensorOperation>, double>>> policy)
: policy_(policy) {}
std::vector<std::vector<std::pair<std::reference_wrapper<TensorTransform>, double>>> policy) {
for (int32_t i = 0; i < policy.size(); i++) {
std::vector<std::pair<std::shared_ptr<TensorOperation>, double>> subpolicy;
for (int32_t j = 0; j < policy[i].size(); j++) {
TensorTransform &op = policy[i][j].first;
std::shared_ptr<TensorOperation> operation = op.Parse();
double prob = policy[i][j].second;
subpolicy.emplace_back(std::move(std::make_pair(operation, prob)));
}
policy_.emplace_back(subpolicy);
}
}
std::shared_ptr<TensorOperation> RandomSelectSubpolicy::Parse() {
return std::make_shared<RandomSelectSubpolicyOperation>(policy_);
@ -374,8 +419,8 @@ std::shared_ptr<TensorOperation> RandomVerticalFlipWithBBox::Parse() {
Rescale::Rescale(float rescale, float shift) : rescale_(rescale), shift_(shift) {}
std::shared_ptr<TensorOperation> Rescale::Parse() { return std::make_shared<RescaleOperation>(rescale_, shift_); }
#endif // not ENABLE_ANDROID
#endif
// Resize Transform Operation.
Resize::Resize(std::vector<int32_t> size, InterpolationMode interpolation)
: size_(size), interpolation_(interpolation) {}
@ -389,7 +434,7 @@ std::shared_ptr<TensorOperation> Resize::Parse(const MapTargetDevice &env) {
usize_.reserve(size_.size());
std::transform(size_.begin(), size_.end(), std::back_inserter(usize_), [](int32_t i) { return (uint32_t)i; });
return std::make_shared<DvppResizeJpegOperation>(usize_);
#endif
#endif // ENABLE_ACL
}
return std::make_shared<ResizeOperation>(size_, interpolation_);
}
@ -399,7 +444,7 @@ std::shared_ptr<TensorOperation> Resize::Parse(const MapTargetDevice &env) {
Rotate::Rotate() {}
std::shared_ptr<TensorOperation> Rotate::Parse() { return std::make_shared<RotateOperation>(); }
#endif
#endif // ENABLE_ANDROID
#ifndef ENABLE_ANDROID
// ResizeWithBBox Transform Operation.
@ -442,18 +487,29 @@ SwapRedBlue::SwapRedBlue() {}
std::shared_ptr<TensorOperation> SwapRedBlue::Parse() { return std::make_shared<SwapRedBlueOperation>(); }
// UniformAug Transform Operation.
UniformAugment::UniformAugment(std::vector<std::shared_ptr<TensorTransform>> transforms, int32_t num_ops) {
// Convert ops from TensorTransform to TensorOperation
UniformAugment::UniformAugment(const std::vector<TensorTransform *> &transforms, int32_t num_ops) : num_ops_(num_ops) {
(void)std::transform(
transforms.begin(), transforms.end(), std::back_inserter(transforms_),
[](std::shared_ptr<TensorTransform> operation) -> std::shared_ptr<TensorOperation> { return operation->Parse(); });
num_ops_ = num_ops;
[](TensorTransform *op) -> std::shared_ptr<TensorOperation> { return op ? op->Parse() : nullptr; });
}
UniformAugment::UniformAugment(const std::vector<std::shared_ptr<TensorTransform>> &transforms, int32_t num_ops)
: num_ops_(num_ops) {
(void)std::transform(
transforms.begin(), transforms.end(), std::back_inserter(transforms_),
[](std::shared_ptr<TensorTransform> op) -> std::shared_ptr<TensorOperation> { return op ? op->Parse() : nullptr; });
}
UniformAugment::UniformAugment(const std::vector<std::reference_wrapper<TensorTransform>> &transforms, int32_t num_ops)
: num_ops_(num_ops) {
(void)std::transform(transforms.begin(), transforms.end(), std::back_inserter(transforms_),
[](TensorTransform &op) -> std::shared_ptr<TensorOperation> { return op.Parse(); });
}
std::shared_ptr<TensorOperation> UniformAugment::Parse() {
return std::make_shared<UniformAugOperation>(transforms_, num_ops_);
}
#endif
#endif // not ENABLE_ANDROID
} // namespace vision
} // namespace dataset

@ -61,9 +61,19 @@ class AutoContrast : public TensorTransform {
class BoundingBoxAugment : public TensorTransform {
public:
/// \brief Constructor.
/// \param[in] transform A TensorTransform transform.
/// \param[in] transform Raw pointer to a TensorTransform operation.
/// \param[in] ratio Ratio of bounding boxes to apply augmentation on. Range: [0, 1] (default=0.3).
explicit BoundingBoxAugment(std::shared_ptr<TensorTransform> transform, float ratio = 0.3);
explicit BoundingBoxAugment(TensorTransform *transform, float ratio = 0.3);
/// \brief Constructor.
/// \param[in] transform Smart pointer to a TensorTransform operation.
/// \param[in] ratio Ratio of bounding boxes to apply augmentation on. Range: [0, 1] (default=0.3).
explicit BoundingBoxAugment(const std::shared_ptr<TensorTransform> &transform, float ratio = 0.3);
/// \brief Constructor.
/// \param[in] transform Object pointer to a TensorTransform operation.
/// \param[in] ratio Ratio of bounding boxes to apply augmentation on. Range: [0, 1] (default=0.3).
explicit BoundingBoxAugment(const std::reference_wrapper<TensorTransform> transform, float ratio = 0.3);
/// \brief Destructor.
~BoundingBoxAugment() = default;
@ -620,16 +630,22 @@ class RandomRotation : public TensorTransform {
/// \brief RandomSelectSubpolicy TensorTransform.
/// \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 TensorTransform 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
/// Once a sub-policy is selected, each op within the sub-policy with be applied in sequence according to its
/// probability.
class RandomSelectSubpolicy : public TensorTransform {
public:
/// \brief Constructor.
/// \param[in] policy Vector of sub-policies to choose from.
/// \param[in] policy Vector of sub-policies to choose from, in which the TensorTransform objects are raw pointers
explicit RandomSelectSubpolicy(std::vector<std::vector<std::pair<TensorTransform *, double>>> policy);
// FIXME - Provide TensorTransform support for policy
explicit RandomSelectSubpolicy(std::vector<std::vector<std::pair<std::shared_ptr<TensorOperation>, double>>> policy);
// RandomSelectSubpolicy(std::vector<std::vector<std::pair<std::shared_ptr<TensorTransform>, double>>> policy);
/// \brief Constructor.
/// \param[in] policy Vector of sub-policies to choose from, in which the TensorTransform objects are shared pointers
explicit RandomSelectSubpolicy(std::vector<std::vector<std::pair<std::shared_ptr<TensorTransform>, double>>> policy);
/// \brief Constructor.
/// \param[in] policy Vector of sub-policies to choose from, in which the TensorTransform objects are object pointers
explicit RandomSelectSubpolicy(
std::vector<std::vector<std::pair<std::reference_wrapper<TensorTransform>, double>>> policy);
/// \brief Destructor.
~RandomSelectSubpolicy() = default;
@ -871,9 +887,19 @@ class SwapRedBlue : public TensorTransform {
class UniformAugment : public TensorTransform {
public:
/// \brief Constructor.
/// \param[in] transforms A vector of TensorTransform transforms.
/// \param[in] transforms Raw pointer to vector of TensorTransform operations.
/// \param[in] num_ops An integer representing the number of OPs to be selected and applied.
explicit UniformAugment(const std::vector<TensorTransform *> &transforms, int32_t num_ops = 2);
/// \brief Constructor.
/// \param[in] transforms Smart pointer to vector of TensorTransform operations.
/// \param[in] num_ops An integer representing the number of OPs to be selected and applied.
explicit UniformAugment(const std::vector<std::shared_ptr<TensorTransform>> &transforms, int32_t num_ops = 2);
/// \brief Constructor.
/// \param[in] transforms Object pointer to vector of TensorTransform operations.
/// \param[in] num_ops An integer representing the number of OPs to be selected and applied.
explicit UniformAugment(std::vector<std::shared_ptr<TensorTransform>> transforms, int32_t num_ops = 2);
explicit UniformAugment(const std::vector<std::reference_wrapper<TensorTransform>> &transforms, int32_t num_ops = 2);
/// \brief Destructor.
~UniformAugment() = default;

@ -43,12 +43,14 @@ Status ValidateScalar(const std::string &op_name, const std::string &scalar_name
const std::vector<T> &range, bool left_open_interval = false, bool right_open_interval = false) {
if (range.empty() || range.size() > 2) {
std::string err_msg = "Range check expecting size 1 or 2, but got: " + std::to_string(range.size());
MS_LOG(ERROR) << err_msg;
return Status(StatusCode::kMDSyntaxError, __LINE__, __FILE__, err_msg);
}
if ((left_open_interval && scalar <= range[0]) || (!left_open_interval && scalar < range[0])) {
std::string interval_description = left_open_interval ? " greater than " : " greater than or equal to ";
std::string err_msg = op_name + ":" + scalar_name + " must be" + interval_description + std::to_string(range[0]) +
", got: " + std::to_string(scalar);
MS_LOG(ERROR) << err_msg;
return Status(StatusCode::kMDSyntaxError, __LINE__, __FILE__, err_msg);
}
if (range.size() == 2) {
@ -58,6 +60,7 @@ Status ValidateScalar(const std::string &op_name, const std::string &scalar_name
std::string err_msg = op_name + ":" + scalar_name + " is out of range " + left_bracket +
std::to_string(range[0]) + ", " + std::to_string(range[1]) + right_bracket +
", got: " + std::to_string(scalar);
MS_LOG(ERROR) << err_msg;
return Status(StatusCode::kMDSyntaxError, __LINE__, __FILE__, err_msg);
}
}

@ -76,6 +76,7 @@ SET(DE_UT_SRCS
ir_callback_test.cc
ir_tensor_op_fusion_pass_test.cc
ir_tree_adapter_test.cc
ir_vision_test.cc
jieba_tokenizer_op_test.cc
main_test.cc
map_op_test.cc

@ -31,7 +31,7 @@ TEST_F(MindDataTestPipeline, TestAffineAPI) {
// Create an ImageFolder Dataset
std::string folder_path = datasets_root_path_ + "/testPK/data/";
std::shared_ptr<Dataset> ds = ImageFolder(folder_path, true, RandomSampler(false, 5));
std::shared_ptr<Dataset> ds = ImageFolder(folder_path, true, std::make_shared<RandomSampler>(false, 5));
// Create a Repeat operation on ds
int32_t repeat_num = 3;
@ -74,7 +74,7 @@ TEST_F(MindDataTestPipeline, TestAffineAPIFail) {
// Create an ImageFolder Dataset
std::string folder_path = datasets_root_path_ + "/testPK/data/";
std::shared_ptr<Dataset> ds = ImageFolder(folder_path, true, RandomSampler(false, 5));
std::shared_ptr<Dataset> ds = ImageFolder(folder_path, true, std::make_shared<RandomSampler>(false, 5));
// Create a Repeat operation on ds
int32_t repeat_num = 3;

@ -26,20 +26,20 @@ class MindDataTestPipeline : public UT::DatasetOpTesting {
// Tests for vision C++ API BoundingBoxAugment TensorTransform Operation
TEST_F(MindDataTestPipeline, TestBoundingBoxAugmentSuccess) {
MS_LOG(INFO) << "Doing MindDataTestPipeline-TestBoundingBoxAugmentSuccess.";
TEST_F(MindDataTestPipeline, TestBoundingBoxAugmentSuccess1Shr) {
MS_LOG(INFO) << "Doing MindDataTestPipeline-TestBoundingBoxAugmentSuccess1Shr.";
// Create an VOC Dataset
std::string folder_path = datasets_root_path_ + "/testVOC2012_2";
std::shared_ptr<Dataset> ds = VOC(folder_path, "Detection", "train", {}, true, std::make_shared<SequentialSampler>(0, 3));
EXPECT_NE(ds, nullptr);
/* FIXME - Resolve BoundingBoxAugment to properly handle TensorTransform input
// Create objects for the tensor ops
std::shared_ptr<TensorTransform> bound_box_augment = std::make_shared<vision::BoundingBoxAugment>(vision::RandomRotation({90.0}), 1.0);
EXPECT_NE(bound_box_augment, nullptr);
// Use shared pointers
std::shared_ptr<TensorTransform> random_rotation_op(new vision::RandomRotation({90.0}));
std::shared_ptr<TensorTransform> bound_box_augment_op(new vision::BoundingBoxAugment({random_rotation_op}, 1.0));
// Create a Map operation on ds
ds = ds->Map({bound_box_augment}, {"image", "bbox"}, {"image", "bbox"}, {"image", "bbox"});
ds = ds->Map({bound_box_augment_op}, {"image", "bbox"}, {"image", "bbox"}, {"image", "bbox"});
EXPECT_NE(ds, nullptr);
// Create an iterator over the result of the above dataset
@ -62,22 +62,174 @@ TEST_F(MindDataTestPipeline, TestBoundingBoxAugmentSuccess) {
EXPECT_EQ(i, 3);
// Manually terminate the pipeline
iter->Stop();
*/
}
TEST_F(MindDataTestPipeline, TestBoundingBoxAugmentFail) {
MS_LOG(INFO) << "Doing MindDataTestPipeline-TestBoundingBoxAugmentFail with invalid params.";
// FIXME: For error tests, need to check for failure from CreateIterator execution
/*
// Testing invalid ratio < 0.0
std::shared_ptr<TensorTransform> bound_box_augment = std::make_shared<vision::BoundingBoxAugment>(vision::RandomRotation({90.0}), -1.0);
EXPECT_EQ(bound_box_augment, nullptr);
// Testing invalid ratio > 1.0
std::shared_ptr<TensorTransform> bound_box_augment1 = std::make_shared<vision::BoundingBoxAugment>(vision::RandomRotation({90.0}), 2.0);
EXPECT_EQ(bound_box_augment1, nullptr);
// Testing invalid transform
std::shared_ptr<TensorTransform> bound_box_augment2 = std::make_shared<vision::BoundingBoxAugment>(nullptr, 0.5);
EXPECT_EQ(bound_box_augment2, nullptr);
*/
TEST_F(MindDataTestPipeline, TestBoundingBoxAugmentSuccess2Auto) {
MS_LOG(INFO) << "Doing MindDataTestPipeline-TestBoundingBoxAugmentSuccess2Auto.";
// Create an VOC Dataset
std::string folder_path = datasets_root_path_ + "/testVOC2012_2";
std::shared_ptr<Dataset> ds = VOC(folder_path, "Detection", "train", {}, true, std::make_shared<SequentialSampler>(0, 3));
EXPECT_NE(ds, nullptr);
// Create objects for the tensor ops
// Use auto for raw pointers
auto random_rotation_op(new vision::RandomRotation({90.0}));
auto bound_box_augment_op(new vision::BoundingBoxAugment({random_rotation_op}, 1.0));
// Create a Map operation on ds
ds = ds->Map({bound_box_augment_op}, {"image", "bbox"}, {"image", "bbox"}, {"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<Iterator> iter = ds->CreateIterator();
EXPECT_NE(iter, nullptr);
// Iterate the dataset and get each row
std::unordered_map<std::string, mindspore::MSTensor> 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, 3);
// Manually terminate the pipeline
iter->Stop();
}
TEST_F(MindDataTestPipeline, TestBoundingBoxAugmentSuccess3Obj) {
MS_LOG(INFO) << "Doing MindDataTestPipeline-TestBoundingBoxAugmentSuccess3Obj.";
// Create an VOC Dataset
std::string folder_path = datasets_root_path_ + "/testVOC2012_2";
std::shared_ptr<Dataset> ds = VOC(folder_path, "Detection", "train", {}, true, std::make_shared<SequentialSampler>(0, 3));
EXPECT_NE(ds, nullptr);
// Create objects for the tensor ops
// Use object references
vision::RandomRotation random_rotation_op = vision::RandomRotation({90.0});
vision::BoundingBoxAugment bound_box_augment_op = vision::BoundingBoxAugment({random_rotation_op}, 1.0);
// Create a Map operation on ds
ds = ds->Map({bound_box_augment_op}, {"image", "bbox"}, {"image", "bbox"}, {"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<Iterator> iter = ds->CreateIterator();
EXPECT_NE(iter, nullptr);
// Iterate the dataset and get each row
std::unordered_map<std::string, mindspore::MSTensor> 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, 3);
// Manually terminate the pipeline
iter->Stop();
}
TEST_F(MindDataTestPipeline, TestBoundingBoxAugmentFail1) {
MS_LOG(INFO) << "Doing MindDataTestPipeline-TestBoundingBoxAugmentFail1 with invalid ratio parameter.";
// Create an VOC Dataset
std::string folder_path = datasets_root_path_ + "/testVOC2012_2";
std::shared_ptr<Dataset> ds = VOC(folder_path, "Detection", "train", {}, true, std::make_shared<SequentialSampler>(0, 3));
EXPECT_NE(ds, nullptr);
// Create objects for the tensor ops
std::shared_ptr<TensorTransform> random_rotation_op(new vision::RandomRotation({90.0}));
// Create BoundingBoxAugment op with invalid ratio < 0.0
std::shared_ptr<TensorTransform> bound_box_augment_op(new vision::BoundingBoxAugment({random_rotation_op}, -1.0));
// Create a Map operation on ds
ds = ds->Map({bound_box_augment_op}, {"image", "bbox"}, {"image", "bbox"}, {"image", "bbox"});
EXPECT_NE(ds, nullptr);
// Create an iterator over the result of the above dataset
std::shared_ptr<Iterator> iter = ds->CreateIterator();
// Expect failure: Invalid BoundingBoxAugment input
EXPECT_EQ(iter, nullptr);
}
TEST_F(MindDataTestPipeline, TestBoundingBoxAugmentFail2) {
MS_LOG(INFO) << "Doing MindDataTestPipeline-TestBoundingBoxAugmentFail2 with invalid ratio parameter.";
// Create an VOC Dataset
std::string folder_path = datasets_root_path_ + "/testVOC2012_2";
std::shared_ptr<Dataset> ds = VOC(folder_path, "Detection", "train", {}, true, std::make_shared<SequentialSampler>(0, 3));
EXPECT_NE(ds, nullptr);
// Create objects for the tensor ops
std::shared_ptr<TensorTransform> random_rotation_op(new vision::RandomRotation({90.0}));
// Create BoundingBoxAugment op with invalid ratio > 1.0
std::shared_ptr<TensorTransform> bound_box_augment_op(new vision::BoundingBoxAugment({random_rotation_op}, 2.0));
// Create a Map operation on ds
ds = ds->Map({bound_box_augment_op}, {"image", "bbox"}, {"image", "bbox"}, {"image", "bbox"});
EXPECT_NE(ds, nullptr);
// Create an iterator over the result of the above dataset
std::shared_ptr<Iterator> iter = ds->CreateIterator();
// Expect failure: Invalid BoundingBoxAugment input
EXPECT_EQ(iter, nullptr);
}
TEST_F(MindDataTestPipeline, TestBoundingBoxAugmentFail3) {
MS_LOG(INFO) << "Doing MindDataTestPipeline-TestBoundingBoxAugmentFail3 with invalid transform.";
// Create an VOC Dataset
std::string folder_path = datasets_root_path_ + "/testVOC2012_2";
std::shared_ptr<Dataset> ds = VOC(folder_path, "Detection", "train", {}, true, std::make_shared<SequentialSampler>(0, 3));
EXPECT_NE(ds, nullptr);
// Create BoundingBoxAugment op with invalid nullptr transform
std::shared_ptr<TensorTransform> bound_box_augment_op(new vision::BoundingBoxAugment(nullptr, 0.5));
// Create a Map operation on ds
ds = ds->Map({bound_box_augment_op}, {"image", "bbox"}, {"image", "bbox"}, {"image", "bbox"});
EXPECT_NE(ds, nullptr);
// Create an iterator over the result of the above dataset
std::shared_ptr<Iterator> iter = ds->CreateIterator();
// Expect failure: Invalid BoundingBoxAugment input
EXPECT_EQ(iter, nullptr);
}
TEST_F(MindDataTestPipeline, TestBoundingBoxAugmentFail4) {
MS_LOG(INFO) << "Doing MindDataTestPipeline-TestBoundingBoxAugmentFail4 with invalid transform input.";
// Create an VOC Dataset
std::string folder_path = datasets_root_path_ + "/testVOC2012_2";
std::shared_ptr<Dataset> ds = VOC(folder_path, "Detection", "train", {}, true, std::make_shared<SequentialSampler>(0, 3));
EXPECT_NE(ds, nullptr);
// Create objects for the tensor ops
// RandomRotation has invalid input, first column value of degrees is greater than the second column value
std::shared_ptr<TensorTransform> random_rotation_op(new vision::RandomRotation({50.0, -50.0}));
// Create BoundingBoxAugment op with invalid transform
std::shared_ptr<TensorTransform> bound_box_augment_op(new vision::BoundingBoxAugment({random_rotation_op}, 0.25));
// Create a Map operation on ds
ds = ds->Map({bound_box_augment_op}, {"image", "bbox"}, {"image", "bbox"}, {"image", "bbox"});
EXPECT_NE(ds, nullptr);
// Create an iterator over the result of the above dataset
std::shared_ptr<Iterator> iter = ds->CreateIterator();
// Expect failure: Invalid BoundingBoxAugment input
EXPECT_EQ(iter, nullptr);
}

File diff suppressed because it is too large Load Diff

@ -41,6 +41,24 @@ using mindspore::StatusCode;
} \
} while (false)
#define ASSERT_ERROR(_s) \
do { \
Status __rc = (_s); \
if (__rc.IsOk()) { \
MS_LOG(ERROR) << __rc.ToString() << "."; \
ASSERT_TRUE(false); \
} \
} while (false)
#define EXPECT_ERROR(_s) \
do { \
Status __rc = (_s); \
if (__rc.IsOk()) { \
MS_LOG(ERROR) << __rc.ToString() << "."; \
EXPECT_TRUE(false); \
} \
} while (false)
namespace UT {
class Common : public testing::Test {
public:

@ -0,0 +1,95 @@
/**
* Copyright 2021 Huawei Technologies Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <memory>
#include <string>
#include "common/common.h"
#include "minddata/dataset/include/datasets.h"
#include "minddata/dataset/include/transforms.h"
#include "minddata/dataset/include/vision.h"
#include "minddata/dataset/kernels/ir/vision/vision_ir.h"
using namespace mindspore::dataset;
class MindDataTestIRVision : public UT::DatasetOpTesting {
public:
MindDataTestIRVision() = default;
};
TEST_F(MindDataTestIRVision, TestAutoContrastIRFail1) {
MS_LOG(INFO) << "Doing MindDataTestIRVision-TestAutoContrastIRFail1.";
// Testing invalid cutoff < 0
std::shared_ptr<TensorOperation> auto_contrast1(new vision::AutoContrastOperation(-1.0,{}));
ASSERT_NE(auto_contrast1, nullptr);
Status rc1 = auto_contrast1->ValidateParams();
EXPECT_ERROR(rc1);
// Testing invalid cutoff > 100
std::shared_ptr<TensorOperation> auto_contrast2(new vision::AutoContrastOperation(110.0, {10, 20}));
ASSERT_NE(auto_contrast2, nullptr);
Status rc2 = auto_contrast2->ValidateParams();
EXPECT_ERROR(rc2);
}
TEST_F(MindDataTestIRVision, TestNormalizeFail) {
MS_LOG(INFO) << "Doing MindDataTestIRVision-TestNormalizeFail with invalid parameters.";
// std value at 0.0
std::shared_ptr<TensorOperation> normalize1(new vision::NormalizeOperation({121.0, 115.0, 100.0}, {0.0, 68.0, 71.0}));
ASSERT_NE(normalize1, nullptr);
Status rc1 = normalize1->ValidateParams();
EXPECT_ERROR(rc1);
// mean out of range
std::shared_ptr<TensorOperation> normalize2(new vision::NormalizeOperation({121.0, 0.0, 100.0}, {256.0, 68.0, 71.0}));
ASSERT_NE(normalize2, nullptr);
Status rc2 = normalize2->ValidateParams();
EXPECT_ERROR(rc2);
// mean out of range
std::shared_ptr<TensorOperation> normalize3(new vision::NormalizeOperation({256.0, 0.0, 100.0}, {70.0, 68.0, 71.0}));
ASSERT_NE(normalize3, nullptr);
Status rc3 = normalize3->ValidateParams();
EXPECT_ERROR(rc3);
// mean out of range
std::shared_ptr<TensorOperation> normalize4(new vision::NormalizeOperation({-1.0, 0.0, 100.0}, {70.0, 68.0, 71.0}));
ASSERT_NE(normalize4, nullptr);
Status rc4 = normalize4->ValidateParams();
EXPECT_ERROR(rc4);
// normalize with 2 values (not 3 values) for mean
std::shared_ptr<TensorOperation> normalize5(new vision::NormalizeOperation({121.0, 115.0}, {70.0, 68.0, 71.0}));
ASSERT_NE(normalize5, nullptr);
Status rc5 = normalize5->ValidateParams();
EXPECT_ERROR(rc5);
// normalize with 2 values (not 3 values) for standard deviation
std::shared_ptr<TensorOperation> normalize6(new vision::NormalizeOperation({121.0, 115.0, 100.0}, {68.0, 71.0}));
ASSERT_NE(normalize6, nullptr);
Status rc6 = normalize6->ValidateParams();
EXPECT_ERROR(rc6);
}
Loading…
Cancel
Save