From 56da3b0ae16e627f0d8931e7a2e65d091fa28dad Mon Sep 17 00:00:00 2001 From: islam_amin Date: Mon, 13 Jul 2020 11:39:09 -0400 Subject: [PATCH] Fixing ratio bug with BoundingBoxAugment --- .../kernels/image/bounding_box_augment_op.cc | 61 +++++++++--------- .../kernels/image/bounding_box_augment_op.h | 1 + .../bounding_box_augment_crop_c_result.npz | Bin 1654 -> 1654 bytes ...nding_box_augment_valid_ratio_c_result.npz | Bin 1654 -> 1654 bytes .../dataset/test_bounding_box_augment.py | 4 +- 5 files changed, 32 insertions(+), 34 deletions(-) diff --git a/mindspore/ccsrc/dataset/kernels/image/bounding_box_augment_op.cc b/mindspore/ccsrc/dataset/kernels/image/bounding_box_augment_op.cc index a1c29c5307f..8f738b6e784 100644 --- a/mindspore/ccsrc/dataset/kernels/image/bounding_box_augment_op.cc +++ b/mindspore/ccsrc/dataset/kernels/image/bounding_box_augment_op.cc @@ -26,7 +26,7 @@ namespace dataset { const float BoundingBoxAugmentOp::kDefRatio = 0.3; BoundingBoxAugmentOp::BoundingBoxAugmentOp(std::shared_ptr transform, float ratio) - : ratio_(ratio), transform_(std::move(transform)) { + : ratio_(ratio), uniform_(0, 1), transform_(std::move(transform)) { rnd_.seed(GetSeed()); } @@ -34,41 +34,38 @@ Status BoundingBoxAugmentOp::Compute(const TensorRow &input, TensorRow *output) IO_CHECK_VECTOR(input, output); BOUNDING_BOX_CHECK(input); // check if bounding boxes are valid uint32_t num_of_boxes = input[1]->shape()[0]; - uint32_t num_to_aug = num_of_boxes * ratio_; // cast to int - std::vector boxes(num_of_boxes); - std::vector selected_boxes; - for (uint32_t i = 0; i < num_of_boxes; i++) boxes[i] = i; - // sample bboxes according to ratio picked by user - std::sample(boxes.begin(), boxes.end(), std::back_inserter(selected_boxes), num_to_aug, rnd_); std::shared_ptr crop_out; std::shared_ptr res_out; std::shared_ptr input_restore = CVTensor::AsCVTensor(input[0]); - for (uint32_t i = 0; i < num_to_aug; i++) { - float min_x = 0; - float min_y = 0; - float b_w = 0; - float b_h = 0; - // get the required items - RETURN_IF_NOT_OK(input[1]->GetItemAt(&min_x, {selected_boxes[i], 0})); - RETURN_IF_NOT_OK(input[1]->GetItemAt(&min_y, {selected_boxes[i], 1})); - RETURN_IF_NOT_OK(input[1]->GetItemAt(&b_w, {selected_boxes[i], 2})); - RETURN_IF_NOT_OK(input[1]->GetItemAt(&b_h, {selected_boxes[i], 3})); - RETURN_IF_NOT_OK(Crop(input_restore, &crop_out, static_cast(min_x), static_cast(min_y), - static_cast(b_w), static_cast(b_h))); - // transform the cropped bbox region - RETURN_IF_NOT_OK(transform_->Compute(crop_out, &res_out)); - // place the transformed region back in the restored input - std::shared_ptr res_img = CVTensor::AsCVTensor(res_out); - // check if transformed crop is out of bounds of the box - if (res_img->mat().cols > b_w || res_img->mat().rows > b_h || res_img->mat().cols < b_w || - res_img->mat().rows < b_h) { - // if so, resize to fit in the box - std::shared_ptr resize_op = - std::make_shared(static_cast(b_h), static_cast(b_w)); - RETURN_IF_NOT_OK(resize_op->Compute(std::static_pointer_cast(res_img), &res_out)); - res_img = CVTensor::AsCVTensor(res_out); + for (uint32_t i = 0; i < num_of_boxes; i++) { + // using a uniform distribution to ensure op happens with probability ratio_ + if (uniform_(rnd_) < ratio_) { + float min_x = 0; + float min_y = 0; + float b_w = 0; + float b_h = 0; + // get the required items + RETURN_IF_NOT_OK(input[1]->GetItemAt(&min_x, {i, 0})); + RETURN_IF_NOT_OK(input[1]->GetItemAt(&min_y, {i, 1})); + RETURN_IF_NOT_OK(input[1]->GetItemAt(&b_w, {i, 2})); + RETURN_IF_NOT_OK(input[1]->GetItemAt(&b_h, {i, 3})); + RETURN_IF_NOT_OK(Crop(input_restore, &crop_out, static_cast(min_x), static_cast(min_y), + static_cast(b_w), static_cast(b_h))); + // transform the cropped bbox region + RETURN_IF_NOT_OK(transform_->Compute(crop_out, &res_out)); + // place the transformed region back in the restored input + std::shared_ptr res_img = CVTensor::AsCVTensor(res_out); + // check if transformed crop is out of bounds of the box + if (res_img->mat().cols > b_w || res_img->mat().rows > b_h || res_img->mat().cols < b_w || + res_img->mat().rows < b_h) { + // if so, resize to fit in the box + std::shared_ptr resize_op = + std::make_shared(static_cast(b_h), static_cast(b_w)); + RETURN_IF_NOT_OK(resize_op->Compute(std::static_pointer_cast(res_img), &res_out)); + res_img = CVTensor::AsCVTensor(res_out); + } + res_img->mat().copyTo(input_restore->mat()(cv::Rect(min_x, min_y, res_img->mat().cols, res_img->mat().rows))); } - res_img->mat().copyTo(input_restore->mat()(cv::Rect(min_x, min_y, res_img->mat().cols, res_img->mat().rows))); } (*output).push_back(std::move(std::static_pointer_cast(input_restore))); (*output).push_back(input[1]); diff --git a/mindspore/ccsrc/dataset/kernels/image/bounding_box_augment_op.h b/mindspore/ccsrc/dataset/kernels/image/bounding_box_augment_op.h index 6c106f75dc6..0b0ed425062 100644 --- a/mindspore/ccsrc/dataset/kernels/image/bounding_box_augment_op.h +++ b/mindspore/ccsrc/dataset/kernels/image/bounding_box_augment_op.h @@ -53,6 +53,7 @@ class BoundingBoxAugmentOp : public TensorOp { private: float ratio_; std::mt19937 rnd_; + std::uniform_real_distribution uniform_; std::shared_ptr transform_; }; } // namespace dataset diff --git a/tests/ut/data/dataset/golden/bounding_box_augment_crop_c_result.npz b/tests/ut/data/dataset/golden/bounding_box_augment_crop_c_result.npz index ce9abea5165033e04266f5c72655ebc9c9a8bcc6..14ddc166e26c0f6966aec4270124a8d826991dbb 100644 GIT binary patch delta 268 zcmeyy^NmL+z?+#xgaHB+8BCnqVmAscU=&!C7M>tea<{X;dAHX(g=<9 zC$9Rr?Djk@y9=vT|D;Jy{sk1&U2J+^bA{ttZAZ2JFZ2_dC+jh*2t53?);B>fBUZ}u za?pldOTs570R>mbFDv|;v*ePx;L!tCJDdMao(2>weJ6I&d}YSw*{Wu_MMtj*Z9c`E N&%^@q@MK#yO8~nio**CUKKExOyQ0S`n zFY5d!}>cr8k84s)|f`3scaD+-=GiAhCZe{tw9=T$Fe>q&X3 z%Xxn@nS2bWGBnCvuOy5Tthwom3pC;=us|eHvne-+9U&5p7pli2(e(dhaNkGA~ zR~6e%&$iL12)S_bw!n{dlcxa%*T_G6S0Qw)i7ij~S56gE>*iC;`AjSz7f-fjvjhNS C{Y@GG delta 205 zcmeyy^NmL+z?+#xgaHB+8GcvoP}nH6fKlM2$@CfL-mOXyZ(bt2!t99s