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