forked from mindspore-Ecosystem/mindspore
Add c++ api of randomresizecropwithbbox
This commit is contained in:
parent
2d89e7f306
commit
4132228c10
|
@ -47,6 +47,7 @@
|
|||
#include "minddata/dataset/kernels/image/random_crop_op.h"
|
||||
#include "minddata/dataset/kernels/image/random_crop_decode_resize_op.h"
|
||||
#include "minddata/dataset/kernels/image/random_crop_with_bbox_op.h"
|
||||
#include "minddata/dataset/kernels/image/random_crop_and_resize_with_bbox_op.h"
|
||||
#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"
|
||||
|
@ -283,6 +284,17 @@ std::shared_ptr<RandomResizedCropOperation> RandomResizedCrop(std::vector<int32_
|
|||
return op->ValidateParams() ? op : nullptr;
|
||||
}
|
||||
|
||||
// Function to create RandomResizedCropOperation.
|
||||
std::shared_ptr<RandomResizedCropWithBBoxOperation> RandomResizedCropWithBBox(std::vector<int32_t> size,
|
||||
std::vector<float> scale,
|
||||
std::vector<float> ratio,
|
||||
InterpolationMode interpolation,
|
||||
int32_t max_attempts) {
|
||||
auto op = std::make_shared<RandomResizedCropWithBBoxOperation>(size, scale, ratio, interpolation, max_attempts);
|
||||
// Input validation
|
||||
return op->ValidateParams() ? op : nullptr;
|
||||
}
|
||||
|
||||
// Function to create RandomRotationOperation.
|
||||
std::shared_ptr<RandomRotationOperation> RandomRotation(std::vector<float> degrees, InterpolationMode resample,
|
||||
bool expand, std::vector<float> center,
|
||||
|
@ -1441,6 +1453,85 @@ std::shared_ptr<TensorOp> RandomResizedCropOperation::Build() {
|
|||
return tensor_op;
|
||||
}
|
||||
|
||||
// RandomResizedCropWithBBoxOperation
|
||||
RandomResizedCropWithBBoxOperation::RandomResizedCropWithBBoxOperation(std::vector<int32_t> size,
|
||||
std::vector<float> scale,
|
||||
std::vector<float> ratio,
|
||||
InterpolationMode interpolation,
|
||||
int32_t max_attempts)
|
||||
: size_(size), scale_(scale), ratio_(ratio), interpolation_(interpolation), max_attempts_(max_attempts) {}
|
||||
|
||||
Status RandomResizedCropWithBBoxOperation::ValidateParams() {
|
||||
// size
|
||||
if (size_.size() != 2 && size_.size() != 1) {
|
||||
std::string err_msg =
|
||||
"RandomResizedCropWithBBox: 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 = "RandomResizedCropWithBBox: size must only contain positive integers.";
|
||||
MS_LOG(ERROR) << "RandomResizedCropWithBBox: size must only contain positive integers, got: " << size_;
|
||||
RETURN_STATUS_SYNTAX_ERROR(err_msg);
|
||||
}
|
||||
// scale
|
||||
if (scale_.size() != 2) {
|
||||
std::string err_msg =
|
||||
"RandomResizedCropWithBBox: 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 = "RandomResizedCropWithBBox: scale must be greater than or equal to 0.";
|
||||
MS_LOG(ERROR) << "RandomResizedCropWithBBox: 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 = "RandomResizedCropWithBBox: scale must have a size of two in the format of (min, max).";
|
||||
MS_LOG(ERROR) << "RandomResizedCropWithBBox: scale must have a size of two in the format of (min, max), but got: "
|
||||
<< scale_;
|
||||
RETURN_STATUS_SYNTAX_ERROR(err_msg);
|
||||
}
|
||||
// ratio
|
||||
if (ratio_.size() != 2) {
|
||||
std::string err_msg =
|
||||
"RandomResizedCropWithBBox: 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 = "RandomResizedCropWithBBox: ratio must be greater than or equal to 0.";
|
||||
MS_LOG(ERROR) << "RandomResizedCropWithBBox: 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 = "RandomResizedCropWithBBox: ratio must have a size of two in the format of (min, max).";
|
||||
MS_LOG(ERROR) << "RandomResizedCropWithBBox: ratio must have a size of two 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 = "RandomResizedCropWithBBox: 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<TensorOp> RandomResizedCropWithBBoxOperation::Build() {
|
||||
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<RandomCropAndResizeWithBBoxOp> tensor_op = std::make_shared<RandomCropAndResizeWithBBoxOp>(
|
||||
height, width, scale_[0], scale_[1], ratio_[0], ratio_[1], interpolation_, max_attempts_);
|
||||
return tensor_op;
|
||||
}
|
||||
|
||||
// Function to create RandomRotationOperation.
|
||||
RandomRotationOperation::RandomRotationOperation(std::vector<float> degrees, InterpolationMode interpolation_mode,
|
||||
bool expand, std::vector<float> center,
|
||||
|
|
|
@ -64,6 +64,7 @@ class RandomPosterizeOperation;
|
|||
class RandomResizeOperation;
|
||||
class RandomResizeWithBBoxOperation;
|
||||
class RandomResizedCropOperation;
|
||||
class RandomResizedCropWithBBoxOperation;
|
||||
class RandomRotationOperation;
|
||||
class RandomSelectSubpolicyOperation;
|
||||
class RandomSharpnessOperation;
|
||||
|
@ -343,6 +344,23 @@ std::shared_ptr<RandomResizedCropOperation> RandomResizedCrop(
|
|||
std::vector<int32_t> size, std::vector<float> scale = {0.08, 1.0}, std::vector<float> ratio = {3. / 4., 4. / 3.},
|
||||
InterpolationMode interpolation = InterpolationMode::kLinear, int32_t max_attempts = 10);
|
||||
|
||||
/// \brief Function to create a RandomResizedCropWithBBox 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.
|
||||
/// If size is a single value, a square crop of size (size, size) is returned.
|
||||
/// If size has 2 values, it should be (height, width).
|
||||
/// \param[in] scale Range [min, max) of respective size of the original
|
||||
/// size to be cropped (default=(0.08, 1.0))
|
||||
/// \param[in] ratio Range [min, max) of aspect ratio to be cropped
|
||||
/// (default=(3. / 4., 4. / 3.)).
|
||||
/// \param[in] interpolation Image interpolation mode (default=InterpolationMode::kLinear)
|
||||
/// \param[in] max_attempts The maximum number of attempts to propose a valid
|
||||
/// crop_area (default=10). If exceeded, fall back to use center_crop instead.
|
||||
/// \return Shared pointer to the current TensorOperation.
|
||||
std::shared_ptr<RandomResizedCropWithBBoxOperation> RandomResizedCropWithBBox(
|
||||
std::vector<int32_t> size, std::vector<float> scale = {0.08, 1.0}, std::vector<float> ratio = {3. / 4., 4. / 3.},
|
||||
InterpolationMode interpolation = InterpolationMode::kLinear, int32_t max_attempts = 10);
|
||||
|
||||
/// \brief Function to create a RandomRotation TensorOp
|
||||
/// \notes Rotates the image according to parameters
|
||||
/// \param[in] degrees A float vector of size 2, representing the starting and ending degree
|
||||
|
@ -863,6 +881,27 @@ class RandomResizedCropOperation : public TensorOperation {
|
|||
int32_t max_attempts_;
|
||||
};
|
||||
|
||||
class RandomResizedCropWithBBoxOperation : public TensorOperation {
|
||||
public:
|
||||
explicit RandomResizedCropWithBBoxOperation(std::vector<int32_t> size, std::vector<float> scale = {0.08, 1.0},
|
||||
std::vector<float> ratio = {3. / 4., 4. / 3.},
|
||||
InterpolationMode interpolation = InterpolationMode::kNearestNeighbour,
|
||||
int32_t max_attempts = 10);
|
||||
|
||||
~RandomResizedCropWithBBoxOperation() = default;
|
||||
|
||||
std::shared_ptr<TensorOp> Build() override;
|
||||
|
||||
Status ValidateParams() override;
|
||||
|
||||
private:
|
||||
std::vector<int32_t> size_;
|
||||
std::vector<float> scale_;
|
||||
std::vector<float> ratio_;
|
||||
InterpolationMode interpolation_;
|
||||
int32_t max_attempts_;
|
||||
};
|
||||
|
||||
class RandomRotationOperation : public TensorOperation {
|
||||
public:
|
||||
RandomRotationOperation(std::vector<float> degrees, InterpolationMode interpolation_mode, bool expand,
|
||||
|
|
|
@ -1969,6 +1969,133 @@ TEST_F(MindDataTestPipeline, TestRandomResizedCropFail4) {
|
|||
EXPECT_EQ(random_resized_crop, nullptr);
|
||||
}
|
||||
|
||||
TEST_F(MindDataTestPipeline, TestRandomResizedCropWithBBoxSuccess1) {
|
||||
// Testing RandomResizedCropWithBBox with default values
|
||||
// Create an VOC Dataset
|
||||
std::string folder_path = datasets_root_path_ + "/testVOC2012_2";
|
||||
std::shared_ptr<Dataset> ds = VOC(folder_path, "Detection", "train", {}, true, SequentialSampler(0, 4));
|
||||
EXPECT_NE(ds, nullptr);
|
||||
|
||||
// Create objects for the tensor ops
|
||||
std::shared_ptr<TensorOperation> random_resized_crop = vision::RandomResizedCropWithBBox({5});
|
||||
EXPECT_NE(random_resized_crop, nullptr);
|
||||
|
||||
// Create a Map operation on ds
|
||||
ds = ds->Map({random_resized_crop}, {"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, std::shared_ptr<Tensor>> 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] == 5 && image->shape()[1] == 5, true);
|
||||
iter->GetNextRow(&row);
|
||||
}
|
||||
|
||||
EXPECT_EQ(i, 4);
|
||||
|
||||
// Manually terminate the pipeline
|
||||
iter->Stop();
|
||||
}
|
||||
|
||||
TEST_F(MindDataTestPipeline, TestRandomResizedCropWithBBoxSuccess2) {
|
||||
// Testing RandomResizedCropWithBBox with non-default values
|
||||
// Create an VOC Dataset
|
||||
std::string folder_path = datasets_root_path_ + "/testVOC2012_2";
|
||||
std::shared_ptr<Dataset> ds = VOC(folder_path, "Detection", "train", {}, true, SequentialSampler(0, 4));
|
||||
EXPECT_NE(ds, nullptr);
|
||||
|
||||
// Create objects for the tensor ops
|
||||
std::shared_ptr<TensorOperation> random_resized_crop = vision::RandomResizedCropWithBBox(
|
||||
{5, 10}, {0.25, 0.75}, {0.5, 1.25}, mindspore::dataset::InterpolationMode::kArea, 20);
|
||||
EXPECT_NE(random_resized_crop, nullptr);
|
||||
|
||||
// Create a Map operation on ds
|
||||
ds = ds->Map({random_resized_crop}, {"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, std::shared_ptr<Tensor>> 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] == 5 && image->shape()[1] == 10, true);
|
||||
iter->GetNextRow(&row);
|
||||
}
|
||||
|
||||
EXPECT_EQ(i, 4);
|
||||
|
||||
// Manually terminate the pipeline
|
||||
iter->Stop();
|
||||
}
|
||||
|
||||
TEST_F(MindDataTestPipeline, TestRandomResizedCropWithBBoxFail1) {
|
||||
// This should fail because size has negative value
|
||||
// Create a Cifar10 Dataset
|
||||
std::string folder_path = datasets_root_path_ + "/testCifar10Data/";
|
||||
std::shared_ptr<Dataset> ds = Cifar10(folder_path, "all", RandomSampler(false, 10));
|
||||
EXPECT_NE(ds, nullptr);
|
||||
|
||||
// Create objects for the tensor ops
|
||||
std::shared_ptr<TensorOperation> random_resized_crop = vision::RandomResizedCropWithBBox({5, -10});
|
||||
EXPECT_EQ(random_resized_crop, nullptr);
|
||||
}
|
||||
|
||||
TEST_F(MindDataTestPipeline, TestRandomResizedCropWithBBoxFail2) {
|
||||
// This should fail because scale isn't in {min, max} format
|
||||
// Create a Cifar10 Dataset
|
||||
std::string folder_path = datasets_root_path_ + "/testCifar10Data/";
|
||||
std::shared_ptr<Dataset> ds = Cifar10(folder_path, "all", RandomSampler(false, 10));
|
||||
EXPECT_NE(ds, nullptr);
|
||||
|
||||
// Create objects for the tensor ops
|
||||
std::shared_ptr<TensorOperation> random_resized_crop = vision::RandomResizedCropWithBBox({5, 10}, {4, 3});
|
||||
EXPECT_EQ(random_resized_crop, nullptr);
|
||||
}
|
||||
|
||||
TEST_F(MindDataTestPipeline, TestRandomResizedCropWithBBoxFail3) {
|
||||
// This should fail because ratio isn't in {min, max} format
|
||||
// Create a Cifar10 Dataset
|
||||
std::string folder_path = datasets_root_path_ + "/testCifar10Data/";
|
||||
std::shared_ptr<Dataset> ds = Cifar10(folder_path, "all", RandomSampler(false, 10));
|
||||
EXPECT_NE(ds, nullptr);
|
||||
|
||||
// Create objects for the tensor ops
|
||||
std::shared_ptr<TensorOperation> random_resized_crop = vision::RandomResizedCropWithBBox({5, 10}, {4, 5}, {7, 6});
|
||||
EXPECT_EQ(random_resized_crop, nullptr);
|
||||
}
|
||||
|
||||
TEST_F(MindDataTestPipeline, TestRandomResizedCropWithBBoxFail4) {
|
||||
// This should fail because scale has a size of more than 2
|
||||
// Create a Cifar10 Dataset
|
||||
std::string folder_path = datasets_root_path_ + "/testCifar10Data/";
|
||||
std::shared_ptr<Dataset> ds = Cifar10(folder_path, "all", RandomSampler(false, 10));
|
||||
EXPECT_NE(ds, nullptr);
|
||||
|
||||
// Create objects for the tensor ops
|
||||
std::shared_ptr<TensorOperation> random_resized_crop = vision::RandomResizedCropWithBBox({5, 10, 20}, {4, 5}, {7, 6});
|
||||
EXPECT_EQ(random_resized_crop, nullptr);
|
||||
}
|
||||
|
||||
TEST_F(MindDataTestPipeline, TestRandomRotation) {
|
||||
MS_LOG(INFO) << "Doing MindDataTestPipeline-TestRandomRotation.";
|
||||
|
||||
|
@ -2116,8 +2243,8 @@ TEST_F(MindDataTestPipeline, TestRandomSelectSubpolicyFail) {
|
|||
EXPECT_EQ(random_select_subpolicy1, nullptr);
|
||||
|
||||
// RandomSelectSubpolicy: policy must not be empty
|
||||
std::shared_ptr<TensorOperation> random_select_subpolicy2 = vision::RandomSelectSubpolicy(
|
||||
{{{vision::Invert(), 0.5}, {vision::Equalize(), 0.5}}, {{nullptr, 1}}});
|
||||
std::shared_ptr<TensorOperation> 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
|
||||
|
@ -2125,13 +2252,13 @@ TEST_F(MindDataTestPipeline, TestRandomSelectSubpolicyFail) {
|
|||
EXPECT_EQ(random_select_subpolicy3, nullptr);
|
||||
|
||||
// RandomSelectSubpolicy: policy must not be empty
|
||||
std::shared_ptr<TensorOperation> random_select_subpolicy4 = vision::RandomSelectSubpolicy(
|
||||
{{{vision::Invert(), 0.5}, {vision::Equalize(), 0.5}}, {}});
|
||||
std::shared_ptr<TensorOperation> 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<TensorOperation> random_select_subpolicy5 = vision::RandomSelectSubpolicy(
|
||||
{{{}, {vision::Equalize(), 0.5}}, {{vision::Resize({15, 15}), 1}}});
|
||||
std::shared_ptr<TensorOperation> random_select_subpolicy5 =
|
||||
vision::RandomSelectSubpolicy({{{}, {vision::Equalize(), 0.5}}, {{vision::Resize({15, 15}), 1}}});
|
||||
EXPECT_EQ(random_select_subpolicy5, nullptr);
|
||||
}
|
||||
|
||||
|
@ -2569,7 +2696,8 @@ TEST_F(MindDataTestPipeline, TestRescaleFail) {
|
|||
}
|
||||
|
||||
TEST_F(MindDataTestPipeline, TestSoftDvppDecodeRandomCropResizeJpegSuccess1) {
|
||||
MS_LOG(INFO) << "Doing MindDataTestPipeline-TestSoftDvppDecodeRandomCropResizeJpegSuccess1 with single integer input.";
|
||||
MS_LOG(INFO)
|
||||
<< "Doing MindDataTestPipeline-TestSoftDvppDecodeRandomCropResizeJpegSuccess1 with single integer input.";
|
||||
|
||||
// Create an ImageFolder Dataset
|
||||
std::string folder_path = datasets_root_path_ + "/testPK/data/";
|
||||
|
@ -2610,7 +2738,8 @@ TEST_F(MindDataTestPipeline, TestSoftDvppDecodeRandomCropResizeJpegSuccess1) {
|
|||
}
|
||||
|
||||
TEST_F(MindDataTestPipeline, TestSoftDvppDecodeRandomCropResizeJpegSuccess2) {
|
||||
MS_LOG(INFO) << "Doing MindDataTestPipeline-TestSoftDvppDecodeRandomCropResizeJpegSuccess2 with (height, width) input.";
|
||||
MS_LOG(INFO)
|
||||
<< "Doing MindDataTestPipeline-TestSoftDvppDecodeRandomCropResizeJpegSuccess2 with (height, width) input.";
|
||||
|
||||
// Create an ImageFolder Dataset
|
||||
std::string folder_path = datasets_root_path_ + "/testPK/data/";
|
||||
|
|
Loading…
Reference in New Issue