First Commit - New Infrastructure - Python UT tests + Common Aug Files

fix accidental change overwrite

fix 2

updated inits from 0 to 0.0 for float

improvd python ut comments

updated macro
pull/2920/head
Danish Farid 5 years ago
parent faa1084bd8
commit 78c370f72a

@ -740,22 +740,16 @@ Status UpdateBBoxesForCrop(std::shared_ptr<Tensor> *bboxList, size_t *bboxCount,
int CB_Ymax) { int CB_Ymax) {
// PASS LIST, COUNT OF BOUNDING BOXES // PASS LIST, COUNT OF BOUNDING BOXES
// Also PAss X/Y Min/Max of image cropped region - normally obtained from 'GetCropBox' functions // Also PAss X/Y Min/Max of image cropped region - normally obtained from 'GetCropBox' functions
uint32_t bb_Xmin_t, bb_Ymin_t, bb_Xmax_t, bb_Ymax_t; float bb_Xmin = 0.0, bb_Ymin = 0.0, bb_Xmax = 0.0, bb_Ymax = 0.0;
std::vector<int> correct_ind; std::vector<int> correct_ind;
std::vector<uint32_t> copyVals; std::vector<float> copyVals;
dsize_t bboxDim = (*bboxList)->shape()[1]; dsize_t bboxDim = (*bboxList)->shape()[1];
bool retFlag = false; // true unless overlap found bool retFlag = false; // true unless overlap found
for (int i = 0; i < *bboxCount; i++) { for (int i = 0; i < *bboxCount; i++) {
int bb_Xmin, bb_Xmax, bb_Ymin, bb_Ymax; RETURN_IF_NOT_OK((*bboxList)->GetItemAt<float>(&bb_Xmin, {i, 0}));
RETURN_IF_NOT_OK((*bboxList)->GetUnsignedIntAt(&bb_Xmin_t, {i, 0})); RETURN_IF_NOT_OK((*bboxList)->GetItemAt<float>(&bb_Ymin, {i, 1}));
RETURN_IF_NOT_OK((*bboxList)->GetUnsignedIntAt(&bb_Ymin_t, {i, 1})); RETURN_IF_NOT_OK((*bboxList)->GetItemAt<float>(&bb_Xmax, {i, 2}));
RETURN_IF_NOT_OK((*bboxList)->GetUnsignedIntAt(&bb_Xmax_t, {i, 2})); RETURN_IF_NOT_OK((*bboxList)->GetItemAt<float>(&bb_Ymax, {i, 3}));
RETURN_IF_NOT_OK((*bboxList)->GetUnsignedIntAt(&bb_Ymax_t, {i, 3}));
bb_Xmin = bb_Xmin_t;
bb_Ymin = bb_Ymin_t;
bb_Xmax = bb_Xmax_t;
bb_Ymax = bb_Ymax_t;
bb_Xmax = bb_Xmin + bb_Xmax; bb_Xmax = bb_Xmin + bb_Xmax;
bb_Ymax = bb_Ymin + bb_Ymax; bb_Ymax = bb_Ymin + bb_Ymax;
// check for image / BB overlap // check for image / BB overlap
@ -766,23 +760,23 @@ Status UpdateBBoxesForCrop(std::shared_ptr<Tensor> *bboxList, size_t *bboxCount,
correct_ind.push_back(i); correct_ind.push_back(i);
// adjust BBox corners by bringing into new CropBox if beyond // adjust BBox corners by bringing into new CropBox if beyond
// Also reseting/adjusting for boxes to lie within CropBox instead of Image - subtract CropBox Xmin/YMin // Also reseting/adjusting for boxes to lie within CropBox instead of Image - subtract CropBox Xmin/YMin
bb_Xmin = bb_Xmin - (std::min(0, (bb_Xmin - CB_Xmin)) + CB_Xmin); bb_Xmin = bb_Xmin - (std::min(static_cast<float>(0.0), (bb_Xmin - CB_Xmin)) + CB_Xmin);
bb_Xmax = bb_Xmax - (std::max(0, (bb_Xmax - CB_Xmax)) + CB_Xmin); bb_Xmax = bb_Xmax - (std::max(static_cast<float>(0.0), (bb_Xmax - CB_Xmax)) + CB_Xmin);
bb_Ymin = bb_Ymin - (std::min(0, (bb_Ymin - CB_Ymin)) + CB_Ymin); bb_Ymin = bb_Ymin - (std::min(static_cast<float>(0.0), (bb_Ymin - CB_Ymin)) + CB_Ymin);
bb_Ymax = bb_Ymax - (std::max(0, (bb_Ymax - CB_Ymax)) + CB_Ymin); bb_Ymax = bb_Ymax - (std::max(static_cast<float>(0.0), (bb_Ymax - CB_Ymax)) + CB_Ymin);
// reset min values and calculate width/height from Box corners // reset min values and calculate width/height from Box corners
RETURN_IF_NOT_OK((*bboxList)->SetItemAt({i, 0}, static_cast<uint32_t>(bb_Xmin))); RETURN_IF_NOT_OK((*bboxList)->SetItemAt({i, 0}, bb_Xmin));
RETURN_IF_NOT_OK((*bboxList)->SetItemAt({i, 1}, static_cast<uint32_t>(bb_Ymin))); RETURN_IF_NOT_OK((*bboxList)->SetItemAt({i, 1}, bb_Ymin));
RETURN_IF_NOT_OK((*bboxList)->SetItemAt({i, 2}, static_cast<uint32_t>(bb_Xmax - bb_Xmin))); RETURN_IF_NOT_OK((*bboxList)->SetItemAt({i, 2}, bb_Xmax - bb_Xmin));
RETURN_IF_NOT_OK((*bboxList)->SetItemAt({i, 3}, static_cast<uint32_t>(bb_Ymax - bb_Ymin))); RETURN_IF_NOT_OK((*bboxList)->SetItemAt({i, 3}, bb_Ymax - bb_Ymin));
} }
// create new tensor and copy over bboxes still valid to the image // create new tensor and copy over bboxes still valid to the image
// bboxes outside of new cropped region are ignored - empty tensor returned in case of none // bboxes outside of new cropped region are ignored - empty tensor returned in case of none
*bboxCount = correct_ind.size(); *bboxCount = correct_ind.size();
uint32_t temp; float temp = 0.0;
for (auto slice : correct_ind) { // for every index in the loop for (auto slice : correct_ind) { // for every index in the loop
for (int ix = 0; ix < bboxDim; ix++) { for (int ix = 0; ix < bboxDim; ix++) {
RETURN_IF_NOT_OK((*bboxList)->GetUnsignedIntAt(&temp, {slice, ix})); RETURN_IF_NOT_OK((*bboxList)->GetItemAt<float>(&temp, {slice, ix}));
copyVals.push_back(temp); copyVals.push_back(temp);
} }
} }
@ -794,11 +788,11 @@ Status UpdateBBoxesForCrop(std::shared_ptr<Tensor> *bboxList, size_t *bboxCount,
Status PadBBoxes(const std::shared_ptr<Tensor> *bboxList, const size_t &bboxCount, int32_t pad_top, int32_t pad_left) { Status PadBBoxes(const std::shared_ptr<Tensor> *bboxList, const size_t &bboxCount, int32_t pad_top, int32_t pad_left) {
for (int i = 0; i < bboxCount; i++) { for (int i = 0; i < bboxCount; i++) {
uint32_t xMin, yMin; float xMin = 0.0, yMin = 0.0;
RETURN_IF_NOT_OK((*bboxList)->GetUnsignedIntAt(&xMin, {i, 0})); RETURN_IF_NOT_OK((*bboxList)->GetItemAt<float>(&xMin, {i, 0}));
RETURN_IF_NOT_OK((*bboxList)->GetUnsignedIntAt(&yMin, {i, 1})); RETURN_IF_NOT_OK((*bboxList)->GetItemAt<float>(&yMin, {i, 1}));
xMin += static_cast<uint32_t>(pad_left); // should not be negative xMin += pad_left;
yMin += static_cast<uint32_t>(pad_top); yMin += pad_top;
RETURN_IF_NOT_OK((*bboxList)->SetItemAt({i, 0}, xMin)); RETURN_IF_NOT_OK((*bboxList)->SetItemAt({i, 0}, xMin));
RETURN_IF_NOT_OK((*bboxList)->SetItemAt({i, 1}, yMin)); RETURN_IF_NOT_OK((*bboxList)->SetItemAt({i, 1}, yMin));
} }
@ -807,16 +801,16 @@ Status PadBBoxes(const std::shared_ptr<Tensor> *bboxList, const size_t &bboxCoun
Status UpdateBBoxesForResize(const std::shared_ptr<Tensor> &bboxList, const size_t &bboxCount, int32_t target_width_, Status UpdateBBoxesForResize(const std::shared_ptr<Tensor> &bboxList, const size_t &bboxCount, int32_t target_width_,
int32_t target_height_, int orig_width, int orig_height) { int32_t target_height_, int orig_width, int orig_height) {
uint32_t bb_Xmin, bb_Ymin, bb_Xwidth, bb_Ywidth; float bb_Xmin = 0, bb_Ymin = 0, bb_Xwidth = 0, bb_Ywidth = 0;
// cast to float to preseve fractional // cast to float to preserve fractional
double W_aspRatio = (target_width_ * 1.0) / (orig_width * 1.0); float W_aspRatio = (target_width_ * 1.0) / (orig_width * 1.0);
double H_aspRatio = (target_height_ * 1.0) / (orig_height * 1.0); float H_aspRatio = (target_height_ * 1.0) / (orig_height * 1.0);
for (int i = 0; i < bboxCount; i++) { for (int i = 0; i < bboxCount; i++) {
// for each bounding box // for each bounding box
RETURN_IF_NOT_OK(bboxList->GetUnsignedIntAt(&bb_Xmin, {i, 0})); RETURN_IF_NOT_OK(bboxList->GetItemAt<float>(&bb_Xmin, {i, 0}));
RETURN_IF_NOT_OK(bboxList->GetUnsignedIntAt(&bb_Ymin, {i, 1})); RETURN_IF_NOT_OK(bboxList->GetItemAt<float>(&bb_Ymin, {i, 1}));
RETURN_IF_NOT_OK(bboxList->GetUnsignedIntAt(&bb_Xwidth, {i, 2})); RETURN_IF_NOT_OK(bboxList->GetItemAt<float>(&bb_Xwidth, {i, 2}));
RETURN_IF_NOT_OK(bboxList->GetUnsignedIntAt(&bb_Ywidth, {i, 3})); RETURN_IF_NOT_OK(bboxList->GetItemAt<float>(&bb_Ywidth, {i, 3}));
// update positions and widths // update positions and widths
bb_Xmin = bb_Xmin * W_aspRatio; bb_Xmin = bb_Xmin * W_aspRatio;
bb_Ymin = bb_Ymin * H_aspRatio; bb_Ymin = bb_Ymin * H_aspRatio;

@ -34,14 +34,13 @@ Status RandomVerticalFlipWithBBoxOp::Compute(const TensorRow &input, TensorRow *
// one time allocation -> updated in the loop // one time allocation -> updated in the loop
// type defined based on VOC test dataset // type defined based on VOC test dataset
for (int i = 0; i < boxCount; i++) { for (int i = 0; i < boxCount; i++) {
uint32_t boxCorner_y = 0; float boxCorner_y = 0.0, boxHeight = 0.0;
uint32_t boxHeight = 0; float newBoxCorner_y = 0.0;
uint32_t newBoxCorner_y = 0; RETURN_IF_NOT_OK(input[1]->GetItemAt<float>(&boxCorner_y, {i, 1})); // get min y of bbox
RETURN_IF_NOT_OK(input[1]->GetUnsignedIntAt(&boxCorner_y, {i, 1})); // get min y of bbox RETURN_IF_NOT_OK(input[1]->GetItemAt<float>(&boxHeight, {i, 3})); // get height of bbox
RETURN_IF_NOT_OK(input[1]->GetUnsignedIntAt(&boxHeight, {i, 3})); // get height of bbox
// subtract (curCorner + height) from (max) for new Corner position // subtract (curCorner + height) from (max) for new Corner position
newBoxCorner_y = (imHeight - 1) - ((boxCorner_y + boxHeight) - 1); newBoxCorner_y = (imHeight - 1.0) - ((boxCorner_y + boxHeight) - 1.0);
RETURN_IF_NOT_OK(input[1]->SetItemAt({i, 1}, newBoxCorner_y)); RETURN_IF_NOT_OK(input[1]->SetItemAt({i, 1}, newBoxCorner_y));
} }

@ -62,14 +62,16 @@
uint32_t img_h = input[0]->shape()[0]; \ uint32_t img_h = input[0]->shape()[0]; \
uint32_t img_w = input[0]->shape()[1]; \ uint32_t img_w = input[0]->shape()[1]; \
for (uint32_t i = 0; i < num_of_boxes; i++) { \ for (uint32_t i = 0; i < num_of_boxes; i++) { \
uint32_t min_x = 0; \ float min_x = 0.0, min_y = 0.0, b_w = 0.0, b_h = 0.0; \
uint32_t min_y = 0; \ bool passing_data_fetch = true; \
uint32_t b_w = 0; \ passing_data_fetch &= input[1]->GetItemAt<float>(&min_x, {i, 0}).IsOk(); \
uint32_t b_h = 0; \ passing_data_fetch &= input[1]->GetItemAt<float>(&min_y, {i, 1}).IsOk(); \
input[1]->GetItemAt<uint32_t>(&min_x, {i, 0}); \ passing_data_fetch &= input[1]->GetItemAt<float>(&b_w, {i, 2}).IsOk(); \
input[1]->GetItemAt<uint32_t>(&min_y, {i, 1}); \ passing_data_fetch &= input[1]->GetItemAt<float>(&b_h, {i, 3}).IsOk(); \
input[1]->GetItemAt<uint32_t>(&b_w, {i, 2}); \ if (!passing_data_fetch) { \
input[1]->GetItemAt<uint32_t>(&b_h, {i, 3}); \ return Status(StatusCode::kUnexpectedError, __LINE__, __FILE__, \
"Fetching BBox values failed in BOUNDING_BOX_CHECK."); \
} \
if ((min_x + b_w > img_w) || (min_y + b_h > img_h)) { \ if ((min_x + b_w > img_w) || (min_y + b_h > img_h)) { \
return Status(StatusCode::kBoundingBoxOutOfBounds, __LINE__, __FILE__, \ return Status(StatusCode::kBoundingBoxOutOfBounds, __LINE__, __FILE__, \
"At least one of the bounding boxes is out of bounds of the image."); \ "At least one of the bounding boxes is out of bounds of the image."); \

@ -118,14 +118,11 @@ void BBoxOpCommon::SaveImagesWithAnnotations(BBoxOpCommon::FileType type, const
bool passing_data_fetch = true; bool passing_data_fetch = true;
// For each bounding box draw on the image. // For each bounding box draw on the image.
for (uint32_t i = 0; i < num_of_boxes; i++) { for (uint32_t i = 0; i < num_of_boxes; i++) {
uint32_t x = 0; float x = 0.0, y = 0.0, w = 0.0, h = 0.0;
uint32_t y = 0; passing_data_fetch &= row[1]->GetItemAt<float>(&x, {i, 0}).IsOk();
uint32_t w = 0; passing_data_fetch &= row[1]->GetItemAt<float>(&y, {i, 1}).IsOk();
uint32_t h = 0; passing_data_fetch &= row[1]->GetItemAt<float>(&w, {i, 2}).IsOk();
passing_data_fetch &= row[1]->GetUnsignedIntAt(&x, {i, 0}).IsOk(); passing_data_fetch &= row[1]->GetItemAt<float>(&h, {i, 3}).IsOk();
passing_data_fetch &= row[1]->GetUnsignedIntAt(&y, {i, 1}).IsOk();
passing_data_fetch &= row[1]->GetUnsignedIntAt(&w, {i, 2}).IsOk();
passing_data_fetch &= row[1]->GetUnsignedIntAt(&h, {i, 3}).IsOk();
if (!passing_data_fetch) { if (!passing_data_fetch) {
MS_LOG(ERROR) << "Fetching bbox coordinates failed in SaveImagesWithAnnotations."; MS_LOG(ERROR) << "Fetching bbox coordinates failed in SaveImagesWithAnnotations.";
EXPECT_TRUE(passing_data_fetch); EXPECT_TRUE(passing_data_fetch);
@ -193,24 +190,24 @@ bool BBoxOpCommon::LoadAnnotationFile(const std::string &path, std::shared_ptr<T
MS_LOG(ERROR) << "No object find in " + path; MS_LOG(ERROR) << "No object find in " + path;
return false; return false;
} }
std::vector<uint32_t> return_value_list; std::vector<float> return_value_list;
dsize_t bbox_count = 0; // keep track of number of bboxes in file dsize_t bbox_count = 0; // keep track of number of bboxes in file
dsize_t bbox_val_count = 4; // creating bboxes of size 4 to test function dsize_t bbox_val_count = 4; // creating bboxes of size 4 to test function
// FILE OK TO READ // FILE OK TO READ
while (object != nullptr) { while (object != nullptr) {
bbox_count += 1; bbox_count += 1;
std::string label_name; std::string label_name;
uint32_t xmin = 0, ymin = 0, xmax = 0, ymax = 0; float xmin = 0.0, ymin = 0.0, xmax = 0.0, ymax = 0.0;
XMLElement *bbox_node = object->FirstChildElement("bndbox"); XMLElement *bbox_node = object->FirstChildElement("bndbox");
if (bbox_node != nullptr) { if (bbox_node != nullptr) {
XMLElement *xmin_node = bbox_node->FirstChildElement("xmin"); XMLElement *xmin_node = bbox_node->FirstChildElement("xmin");
if (xmin_node != nullptr) xmin = xmin_node->UnsignedText(); if (xmin_node != nullptr) xmin = xmin_node->FloatText();
XMLElement *ymin_node = bbox_node->FirstChildElement("ymin"); XMLElement *ymin_node = bbox_node->FirstChildElement("ymin");
if (ymin_node != nullptr) ymin = ymin_node->UnsignedText(); if (ymin_node != nullptr) ymin = ymin_node->FloatText();
XMLElement *xmax_node = bbox_node->FirstChildElement("xmax"); XMLElement *xmax_node = bbox_node->FirstChildElement("xmax");
if (xmax_node != nullptr) xmax = xmax_node->UnsignedText(); if (xmax_node != nullptr) xmax = xmax_node->FloatText();
XMLElement *ymax_node = bbox_node->FirstChildElement("ymax"); XMLElement *ymax_node = bbox_node->FirstChildElement("ymax");
if (ymax_node != nullptr) ymax = ymax_node->UnsignedText(); if (ymax_node != nullptr) ymax = ymax_node->FloatText();
} else { } else {
MS_LOG(ERROR) << "bndbox dismatch in " + path; MS_LOG(ERROR) << "bndbox dismatch in " + path;
return false; return false;

@ -0,0 +1,214 @@
# Copyright 2020 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.
# ==============================================================================
"""
Testing RandomCropAndResizeWithBBox op in DE
"""
import numpy as np
import mindspore.dataset as ds
import mindspore.dataset.transforms.vision.c_transforms as c_vision
from mindspore import log as logger
from util import visualize_with_bounding_boxes, InvalidBBoxType, check_bad_bbox, \
config_get_set_seed, config_get_set_num_parallel_workers, save_and_check_md5
GENERATE_GOLDEN = False
# Updated VOC dataset with correct annotations - DATA_DIR
DATA_DIR_VOC = "../data/dataset/testVOC2012_2"
# COCO dataset - DATA_DIR, ANNOTATION_DIR
DATA_DIR_COCO = ["../data/dataset/testCOCO/train/", "../data/dataset/testCOCO/annotations/train.json"]
def test_random_resized_crop_with_bbox_op_c(plot_vis=False):
"""
Prints images and bboxes side by side with and without RandomResizedCropWithBBox Op applied,
tests with MD5 check, expected to pass
"""
logger.info("test_random_resized_crop_with_bbox_op_c")
original_seed = config_get_set_seed(23415)
original_num_parallel_workers = config_get_set_num_parallel_workers(1)
# Load dataset
dataVoc1 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
dataVoc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
test_op = c_vision.RandomResizedCropWithBBox((256, 512), (0.5, 0.5), (0.5, 0.5))
# map to apply ops
dataVoc2 = dataVoc2.map(input_columns=["image", "annotation"],
output_columns=["image", "annotation"],
columns_order=["image", "annotation"],
operations=[test_op])
filename = "random_resized_crop_with_bbox_01_c_result.npz"
save_and_check_md5(dataVoc2, filename, generate_golden=GENERATE_GOLDEN)
unaugSamp, augSamp = [], []
for unAug, Aug in zip(dataVoc1.create_dict_iterator(), dataVoc2.create_dict_iterator()):
unaugSamp.append(unAug)
augSamp.append(Aug)
if plot_vis:
visualize_with_bounding_boxes(unaugSamp, augSamp)
# Restore config setting
ds.config.set_seed(original_seed)
ds.config.set_num_parallel_workers(original_num_parallel_workers)
def test_random_resized_crop_with_bbox_op_coco_c(plot_vis=False):
"""
Prints images and bboxes side by side with and without RandomResizedCropWithBBox Op applied,
Testing with Coco dataset
"""
logger.info("test_random_resized_crop_with_bbox_op_coco_c")
# load dataset
dataCoco1 = ds.CocoDataset(DATA_DIR_COCO[0], annotation_file=DATA_DIR_COCO[1], task="Detection",
decode=True, shuffle=False)
dataCoco2 = ds.CocoDataset(DATA_DIR_COCO[0], annotation_file=DATA_DIR_COCO[1], task="Detection",
decode=True, shuffle=False)
test_op = c_vision.RandomResizedCropWithBBox((512, 512), (0.5, 1), (0.5, 1))
dataCoco2 = dataCoco2.map(input_columns=["image", "bbox"],
output_columns=["image", "bbox"],
columns_order=["image", "bbox"],
operations=[test_op])
unaugSamp, augSamp = [], []
for unAug, Aug in zip(dataCoco1.create_dict_iterator(), dataCoco2.create_dict_iterator()):
unaugSamp.append(unAug)
augSamp.append(Aug)
if plot_vis:
visualize_with_bounding_boxes(unaugSamp, augSamp, "bbox")
def test_random_resized_crop_with_bbox_op_edge_c(plot_vis=False):
"""
Prints images and bboxes side by side with and without RandomResizedCropWithBBox Op applied,
tests on dynamically generated edge case, expected to pass
"""
logger.info("test_random_resized_crop_with_bbox_op_edge_c")
# Load dataset
dataVoc1 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
dataVoc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
test_op = c_vision.RandomResizedCropWithBBox((256, 512), (0.5, 0.5), (0.5, 0.5))
# maps to convert data into valid edge case data
dataVoc1 = dataVoc1.map(input_columns=["image", "annotation"],
output_columns=["image", "annotation"],
columns_order=["image", "annotation"],
operations=[lambda img, bboxes: (img, np.array([[0, 0, img.shape[1], img.shape[0]]]).astype(bboxes.dtype))])
# Test Op added to list of Operations here
dataVoc2 = dataVoc2.map(input_columns=["image", "annotation"],
output_columns=["image", "annotation"],
columns_order=["image", "annotation"],
operations=[lambda img, bboxes: (img, np.array([[0, 0, img.shape[1], img.shape[0]]]).astype(bboxes.dtype)), test_op])
unaugSamp, augSamp = [], []
for unAug, Aug in zip(dataVoc1.create_dict_iterator(), dataVoc2.create_dict_iterator()):
unaugSamp.append(unAug)
augSamp.append(Aug)
if plot_vis:
visualize_with_bounding_boxes(unaugSamp, augSamp)
def test_random_resized_crop_with_bbox_op_invalid_c():
"""
Tests RandomResizedCropWithBBox on invalid constructor parameters, expected to raise ValueError
"""
logger.info("test_random_resized_crop_with_bbox_op_invalid_c")
# Load dataset, only Augmented Dataset as test will raise ValueError
dataVoc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
try:
# If input range of scale is not in the order of (min, max), ValueError will be raised.
test_op = c_vision.RandomResizedCropWithBBox((256, 512), (1, 0.5), (0.5, 0.5))
# map to apply ops
dataVoc2 = dataVoc2.map(input_columns=["image", "annotation"],
output_columns=["image", "annotation"],
columns_order=["image", "annotation"],
operations=[test_op])
for _ in dataVoc2.create_dict_iterator():
break
except ValueError as err:
logger.info("Got an exception in DE: {}".format(str(err)))
assert "Input range is not valid" in str(err)
def test_random_resized_crop_with_bbox_op_invalid2_c():
"""
Tests RandomResizedCropWithBBox Op on invalid constructor parameters, expected to raise ValueError
"""
logger.info("test_random_resized_crop_with_bbox_op_invalid2_c")
# Load dataset # only loading the to AugDataset as test will fail on this
dataVoc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
try:
# If input range of ratio is not in the order of (min, max), ValueError will be raised.
test_op = c_vision.RandomResizedCropWithBBox((256, 512), (1, 1), (1, 0.5))
# map to apply ops
dataVoc2 = dataVoc2.map(input_columns=["image", "annotation"],
output_columns=["image", "annotation"],
columns_order=["image", "annotation"],
operations=[test_op])
for _ in dataVoc2.create_dict_iterator():
break
except ValueError as err:
logger.info("Got an exception in DE: {}".format(str(err)))
assert "Input range is not valid" in str(err)
def test_random_resized_crop_with_bbox_op_bad_c():
"""
Test RandomCropWithBBox op with invalid bounding boxes, expected to catch multiple errors.
"""
logger.info("test_random_resized_crop_with_bbox_op_bad_c")
test_op = c_vision.RandomResizedCropWithBBox((256, 512), (0.5, 0.5), (0.5, 0.5))
data_voc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
check_bad_bbox(data_voc2, test_op, InvalidBBoxType.WidthOverflow, "bounding boxes is out of bounds of the image")
data_voc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
check_bad_bbox(data_voc2, test_op, InvalidBBoxType.HeightOverflow, "bounding boxes is out of bounds of the image")
data_voc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
check_bad_bbox(data_voc2, test_op, InvalidBBoxType.NegativeXY, "min_x")
data_voc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
check_bad_bbox(data_voc2, test_op, InvalidBBoxType.WrongShape, "4 features")
if __name__ == "__main__":
test_random_resized_crop_with_bbox_op_c(plot_vis=True)
test_random_resized_crop_with_bbox_op_coco_c(plot_vis=True)
test_random_resized_crop_with_bbox_op_edge_c(plot_vis=True)
test_random_resized_crop_with_bbox_op_invalid_c()
test_random_resized_crop_with_bbox_op_invalid2_c()
test_random_resized_crop_with_bbox_op_bad_c()

@ -0,0 +1,249 @@
# Copyright 2020 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.
# ==============================================================================
"""
Testing RandomCropWithBBox op in DE
"""
import numpy as np
import mindspore.dataset as ds
import mindspore.dataset.transforms.vision.c_transforms as c_vision
import mindspore.dataset.transforms.vision.utils as mode
from mindspore import log as logger
from util import visualize_with_bounding_boxes, InvalidBBoxType, check_bad_bbox, \
config_get_set_seed, config_get_set_num_parallel_workers, save_and_check_md5
GENERATE_GOLDEN = False
# Updated VOC dataset with correct annotations - DATA_DIR
DATA_DIR_VOC = "../data/dataset/testVOC2012_2"
# COCO dataset - DATA_DIR, ANNOTATION_DIR
DATA_DIR_COCO = ["../data/dataset/testCOCO/train/", "../data/dataset/testCOCO/annotations/train.json"]
def test_random_crop_with_bbox_op_c(plot_vis=False):
"""
Prints images and bboxes side by side with and without RandomCropWithBBox Op applied
"""
logger.info("test_random_crop_with_bbox_op_c")
# Load dataset
dataVoc1 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
dataVoc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
# define test OP with values to match existing Op UT
test_op = c_vision.RandomCropWithBBox([512, 512], [200, 200, 200, 200])
# map to apply ops
dataVoc2 = dataVoc2.map(input_columns=["image", "annotation"],
output_columns=["image", "annotation"],
columns_order=["image", "annotation"],
operations=[test_op]) # Add column for "annotation"
unaugSamp, augSamp = [], []
for unAug, Aug in zip(dataVoc1.create_dict_iterator(), dataVoc2.create_dict_iterator()):
unaugSamp.append(unAug)
augSamp.append(Aug)
if plot_vis:
visualize_with_bounding_boxes(unaugSamp, augSamp)
def test_random_crop_with_bbox_op_coco_c(plot_vis=False):
"""
Prints images and bboxes side by side with and without RandomCropWithBBox Op applied,
Testing with Coco dataset
"""
logger.info("test_random_crop_with_bbox_op_coco_c")
# load dataset
dataCoco1 = ds.CocoDataset(DATA_DIR_COCO[0], annotation_file=DATA_DIR_COCO[1], task="Detection",
decode=True, shuffle=False)
dataCoco2 = ds.CocoDataset(DATA_DIR_COCO[0], annotation_file=DATA_DIR_COCO[1], task="Detection",
decode=True, shuffle=False)
test_op = c_vision.RandomCropWithBBox([512, 512], [200, 200, 200, 200])
dataCoco2 = dataCoco2.map(input_columns=["image", "bbox"],
output_columns=["image", "bbox"],
columns_order=["image", "bbox"],
operations=[test_op])
unaugSamp, augSamp = [], []
for unAug, Aug in zip(dataCoco1.create_dict_iterator(), dataCoco2.create_dict_iterator()):
unaugSamp.append(unAug)
augSamp.append(Aug)
if plot_vis:
visualize_with_bounding_boxes(unaugSamp, augSamp, "bbox")
def test_random_crop_with_bbox_op2_c(plot_vis=False):
"""
Prints images and bboxes side by side with and without RandomCropWithBBox Op applied,
with md5 check, expected to pass
"""
logger.info("test_random_crop_with_bbox_op2_c")
original_seed = config_get_set_seed(593447)
original_num_parallel_workers = config_get_set_num_parallel_workers(1)
# Load dataset
dataVoc1 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
dataVoc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
# define test OP with values to match existing Op unit - test
test_op = c_vision.RandomCropWithBBox(512, [200, 200, 200, 200], fill_value=(255, 255, 255))
# map to apply ops
dataVoc2 = dataVoc2.map(input_columns=["image", "annotation"],
output_columns=["image", "annotation"],
columns_order=["image", "annotation"],
operations=[test_op])
filename = "random_crop_with_bbox_01_c_result.npz"
save_and_check_md5(dataVoc2, filename, generate_golden=GENERATE_GOLDEN)
unaugSamp, augSamp = [], []
for unAug, Aug in zip(dataVoc1.create_dict_iterator(), dataVoc2.create_dict_iterator()):
unaugSamp.append(unAug)
augSamp.append(Aug)
if plot_vis:
visualize_with_bounding_boxes(unaugSamp, augSamp)
# Restore config setting
ds.config.set_seed(original_seed)
ds.config.set_num_parallel_workers(original_num_parallel_workers)
def test_random_crop_with_bbox_op3_c(plot_vis=False):
"""
Prints images and bboxes side by side with and without RandomCropWithBBox Op applied,
with Padding Mode explicitly passed
"""
logger.info("test_random_crop_with_bbox_op3_c")
# Load dataset
dataVoc1 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
dataVoc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
# define test OP with values to match existing Op unit - test
test_op = c_vision.RandomCropWithBBox(512, [200, 200, 200, 200], padding_mode=mode.Border.EDGE)
# map to apply ops
dataVoc2 = dataVoc2.map(input_columns=["image", "annotation"],
output_columns=["image", "annotation"],
columns_order=["image", "annotation"],
operations=[test_op])
unaugSamp, augSamp = [], []
for unAug, Aug in zip(dataVoc1.create_dict_iterator(), dataVoc2.create_dict_iterator()):
unaugSamp.append(unAug)
augSamp.append(Aug)
if plot_vis:
visualize_with_bounding_boxes(unaugSamp, augSamp)
def test_random_crop_with_bbox_op_edge_c(plot_vis=False):
"""
Prints images and bboxes side by side with and without RandomCropWithBBox Op applied,
applied on dynamically generated edge case, expected to pass
"""
logger.info("test_random_crop_with_bbox_op_edge_c")
# Load dataset
dataVoc1 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
dataVoc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
# define test OP with values to match existing Op unit - test
test_op = c_vision.RandomCropWithBBox(512, [200, 200, 200, 200], padding_mode=mode.Border.EDGE)
# maps to convert data into valid edge case data
dataVoc1 = dataVoc1.map(input_columns=["image", "annotation"],
output_columns=["image", "annotation"],
columns_order=["image", "annotation"],
operations=[lambda img, bboxes: (img, np.array([[0, 0, img.shape[1], img.shape[0]]]).astype(bboxes.dtype))])
# Test Op added to list of Operations here
dataVoc2 = dataVoc2.map(input_columns=["image", "annotation"],
output_columns=["image", "annotation"],
columns_order=["image", "annotation"],
operations=[lambda img, bboxes: (img, np.array([[0, 0, img.shape[1], img.shape[0]]]).astype(bboxes.dtype)), test_op])
unaugSamp, augSamp = [], []
for unAug, Aug in zip(dataVoc1.create_dict_iterator(), dataVoc2.create_dict_iterator()):
unaugSamp.append(unAug)
augSamp.append(Aug)
if plot_vis:
visualize_with_bounding_boxes(unaugSamp, augSamp)
def test_random_crop_with_bbox_op_invalid_c():
"""
Test RandomCropWithBBox Op on invalid constructor parameters, expected to raise ValueError
"""
logger.info("test_random_crop_with_bbox_op_invalid_c")
# Load dataset
dataVoc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
try:
# define test OP with values to match existing Op unit - test
test_op = c_vision.RandomCropWithBBox([512, 512, 375])
# map to apply ops
dataVoc2 = dataVoc2.map(input_columns=["image", "annotation"],
output_columns=["image", "annotation"],
columns_order=["image", "annotation"],
operations=[test_op]) # Add column for "annotation"
for _ in dataVoc2.create_dict_iterator():
break
except TypeError as err:
logger.info("Got an exception in DE: {}".format(str(err)))
assert "Size should be a single integer" in str(err)
def test_random_crop_with_bbox_op_bad_c():
"""
Tests RandomCropWithBBox Op with invalid bounding boxes, expected to catch multiple errors.
"""
logger.info("test_random_crop_with_bbox_op_bad_c")
test_op = c_vision.RandomCropWithBBox([512, 512], [200, 200, 200, 200])
data_voc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
check_bad_bbox(data_voc2, test_op, InvalidBBoxType.WidthOverflow, "bounding boxes is out of bounds of the image")
data_voc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
check_bad_bbox(data_voc2, test_op, InvalidBBoxType.HeightOverflow, "bounding boxes is out of bounds of the image")
data_voc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
check_bad_bbox(data_voc2, test_op, InvalidBBoxType.NegativeXY, "min_x")
data_voc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
check_bad_bbox(data_voc2, test_op, InvalidBBoxType.WrongShape, "4 features")
if __name__ == "__main__":
test_random_crop_with_bbox_op_c(plot_vis=True)
test_random_crop_with_bbox_op_coco_c(plot_vis=True)
test_random_crop_with_bbox_op2_c(plot_vis=True)
test_random_crop_with_bbox_op3_c(plot_vis=True)
test_random_crop_with_bbox_op_edge_c(plot_vis=True)
test_random_crop_with_bbox_op_invalid_c()
test_random_crop_with_bbox_op_bad_c()

@ -0,0 +1,220 @@
# Copyright 2020 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.
# ==============================================================================
"""
Testing RandomVerticalFlipWithBBox op in DE
"""
import numpy as np
import mindspore.dataset as ds
import mindspore.dataset.transforms.vision.c_transforms as c_vision
from mindspore import log as logger
from util import visualize_with_bounding_boxes, InvalidBBoxType, check_bad_bbox, \
config_get_set_seed, config_get_set_num_parallel_workers, save_and_check_md5
GENERATE_GOLDEN = False
# Updated VOC dataset with correct annotations - DATA_DIR
DATA_DIR_VOC = "../data/dataset/testVOC2012_2"
# COCO dataset - DATA_DIR, ANNOTATION_DIR
DATA_DIR_COCO = ["../data/dataset/testCOCO/train/", "../data/dataset/testCOCO/annotations/train.json"]
def test_random_vertical_flip_with_bbox_op_c(plot_vis=False):
"""
Prints images and bboxes side by side with and without RandomVerticalFlipWithBBox Op applied
"""
logger.info("test_random_vertical_flip_with_bbox_op_c")
# Load dataset
dataVoc1 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train",
decode=True, shuffle=False)
dataVoc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train",
decode=True, shuffle=False)
test_op = c_vision.RandomVerticalFlipWithBBox(1)
# map to apply ops
dataVoc2 = dataVoc2.map(input_columns=["image", "annotation"],
output_columns=["image", "annotation"],
columns_order=["image", "annotation"],
operations=[test_op])
unaugSamp, augSamp = [], []
for unAug, Aug in zip(dataVoc1.create_dict_iterator(), dataVoc2.create_dict_iterator()):
unaugSamp.append(unAug)
augSamp.append(Aug)
if plot_vis:
visualize_with_bounding_boxes(unaugSamp, augSamp)
def test_random_vertical_flip_with_bbox_op_coco_c(plot_vis=False):
"""
Prints images and bboxes side by side with and without RandomVerticalFlipWithBBox Op applied,
Testing with Coco dataset
"""
logger.info("test_random_vertical_flip_with_bbox_op_coco_c")
# load dataset
dataCoco1 = ds.CocoDataset(DATA_DIR_COCO[0], annotation_file=DATA_DIR_COCO[1], task="Detection",
decode=True, shuffle=False)
dataCoco2 = ds.CocoDataset(DATA_DIR_COCO[0], annotation_file=DATA_DIR_COCO[1], task="Detection",
decode=True, shuffle=False)
test_op = c_vision.RandomVerticalFlipWithBBox(1)
dataCoco2 = dataCoco2.map(input_columns=["image", "bbox"],
output_columns=["image", "bbox"],
columns_order=["image", "bbox"],
operations=[test_op])
test_op = c_vision.RandomVerticalFlipWithBBox(1)
unaugSamp, augSamp = [], []
for unAug, Aug in zip(dataCoco1.create_dict_iterator(), dataCoco2.create_dict_iterator()):
unaugSamp.append(unAug)
augSamp.append(Aug)
if plot_vis:
visualize_with_bounding_boxes(unaugSamp, augSamp, "bbox")
def test_random_vertical_flip_with_bbox_op_rand_c(plot_vis=False):
"""
Prints images and bboxes side by side with and without RandomVerticalFlipWithBBox Op applied,
tests with MD5 check, expected to pass
"""
logger.info("test_random_vertical_flip_with_bbox_op_rand_c")
original_seed = config_get_set_seed(29847)
original_num_parallel_workers = config_get_set_num_parallel_workers(1)
# Load dataset
dataVoc1 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train",
decode=True, shuffle=False)
dataVoc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train",
decode=True, shuffle=False)
test_op = c_vision.RandomVerticalFlipWithBBox(0.8)
# map to apply ops
dataVoc2 = dataVoc2.map(input_columns=["image", "annotation"],
output_columns=["image", "annotation"],
columns_order=["image", "annotation"],
operations=[test_op])
filename = "random_vertical_flip_with_bbox_01_c_result.npz"
save_and_check_md5(dataVoc2, filename, generate_golden=GENERATE_GOLDEN)
unaugSamp, augSamp = [], []
for unAug, Aug in zip(dataVoc1.create_dict_iterator(), dataVoc2.create_dict_iterator()):
unaugSamp.append(unAug)
augSamp.append(Aug)
if plot_vis:
visualize_with_bounding_boxes(unaugSamp, augSamp)
# Restore config setting
ds.config.set_seed(original_seed)
ds.config.set_num_parallel_workers(original_num_parallel_workers)
def test_random_vertical_flip_with_bbox_op_edge_c(plot_vis=False):
"""
Prints images and bboxes side by side with and without RandomVerticalFlipWithBBox Op applied,
applied on dynamically generated edge case, expected to pass
"""
logger.info("test_random_vertical_flip_with_bbox_op_edge_c")
dataVoc1 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train",
decode=True, shuffle=False)
dataVoc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train",
decode=True, shuffle=False)
test_op = c_vision.RandomVerticalFlipWithBBox(1)
# maps to convert data into valid edge case data
dataVoc1 = dataVoc1.map(input_columns=["image", "annotation"],
output_columns=["image", "annotation"],
columns_order=["image", "annotation"],
operations=[lambda img, bboxes: (img, np.array([[0, 0, img.shape[1], img.shape[0]]]).astype(bboxes.dtype))])
# Test Op added to list of Operations here
dataVoc2 = dataVoc2.map(input_columns=["image", "annotation"],
output_columns=["image", "annotation"],
columns_order=["image", "annotation"],
operations=[lambda img, bboxes: (img, np.array([[0, 0, img.shape[1], img.shape[0]]]).astype(bboxes.dtype)), test_op])
unaugSamp, augSamp = [], []
for unAug, Aug in zip(dataVoc1.create_dict_iterator(), dataVoc2.create_dict_iterator()):
unaugSamp.append(unAug)
augSamp.append(Aug)
if plot_vis:
visualize_with_bounding_boxes(unaugSamp, augSamp)
def test_random_vertical_flip_with_bbox_op_invalid_c():
"""
Test RandomVerticalFlipWithBBox Op on invalid constructor parameters, expected to raise ValueError
"""
logger.info("test_random_vertical_flip_with_bbox_op_invalid_c")
dataVoc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train",
decode=True, shuffle=False)
try:
test_op = c_vision.RandomVerticalFlipWithBBox(2)
# map to apply ops
dataVoc2 = dataVoc2.map(input_columns=["image", "annotation"],
output_columns=["image", "annotation"],
columns_order=["image", "annotation"],
operations=[test_op])
for _ in dataVoc2.create_dict_iterator():
break
except ValueError as err:
logger.info("Got an exception in DE: {}".format(str(err)))
assert "Input is not" in str(err)
def test_random_vertical_flip_with_bbox_op_bad_c():
"""
Tests RandomVerticalFlipWithBBox Op with invalid bounding boxes, expected to catch multiple errors
"""
logger.info("test_random_vertical_flip_with_bbox_op_bad_c")
test_op = c_vision.RandomVerticalFlipWithBBox(1)
data_voc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
check_bad_bbox(data_voc2, test_op, InvalidBBoxType.WidthOverflow, "bounding boxes is out of bounds of the image")
data_voc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
check_bad_bbox(data_voc2, test_op, InvalidBBoxType.HeightOverflow, "bounding boxes is out of bounds of the image")
data_voc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
check_bad_bbox(data_voc2, test_op, InvalidBBoxType.NegativeXY, "min_x")
data_voc2 = ds.VOCDataset(DATA_DIR_VOC, task="Detection", mode="train", decode=True, shuffle=False)
check_bad_bbox(data_voc2, test_op, InvalidBBoxType.WrongShape, "4 features")
if __name__ == "__main__":
test_random_vertical_flip_with_bbox_op_c(plot_vis=True)
test_random_vertical_flip_with_bbox_op_coco_c(plot_vis=True)
test_random_vertical_flip_with_bbox_op_rand_c(plot_vis=True)
test_random_vertical_flip_with_bbox_op_edge_c(plot_vis=True)
test_random_vertical_flip_with_bbox_op_invalid_c()
test_random_vertical_flip_with_bbox_op_bad_c()

@ -288,12 +288,13 @@ def config_get_set_num_parallel_workers(num_parallel_workers_new):
return num_parallel_workers_original return num_parallel_workers_original
def visualize_with_bounding_boxes(orig, aug, plot_rows=3): def visualize_with_bounding_boxes(orig, aug, annot_name="annotation", plot_rows=3):
""" """
Take a list of un-augmented and augmented images with "annotation" bounding boxes Take a list of un-augmented and augmented images with "annotation" bounding boxes
Plot images to compare test correct BBox augment functionality Plot images to compare test correct BBox augment functionality
:param orig: list of original images and bboxes (without aug) :param orig: list of original images and bboxes (without aug)
:param aug: list of augmented images and bboxes :param aug: list of augmented images and bboxes
:param annot_name: the dict key for bboxes in data, e.g "bbox" (COCO) / "annotation" (VOC)
:param plot_rows: number of rows on plot (rows = samples on one plot) :param plot_rows: number of rows on plot (rows = samples on one plot)
:return: None :return: None
""" """
@ -301,9 +302,10 @@ def visualize_with_bounding_boxes(orig, aug, plot_rows=3):
def add_bounding_boxes(ax, bboxes): def add_bounding_boxes(ax, bboxes):
for bbox in bboxes: for bbox in bboxes:
rect = patches.Rectangle((bbox[0], bbox[1]), rect = patches.Rectangle((bbox[0], bbox[1]),
bbox[2], bbox[3], bbox[2]*0.997, bbox[3]*0.997,
linewidth=1, edgecolor='r', facecolor='none') linewidth=1.80, edgecolor='r', facecolor='none')
# Add the patch to the Axes # Add the patch to the Axes
# Params to Rectangle slightly modified to prevent drawing overflow
ax.add_patch(rect) ax.add_patch(rect)
# Quick check to confirm correct input parameters # Quick check to confirm correct input parameters
@ -337,15 +339,15 @@ def visualize_with_bounding_boxes(orig, aug, plot_rows=3):
(axA, axB) = (axs[x, 0], axs[x, 1]) if (curPlot > 1) else (axs[0], axs[1]) # select plotting axes based on number of image rows on plot - else case when 1 row (axA, axB) = (axs[x, 0], axs[x, 1]) if (curPlot > 1) else (axs[0], axs[1]) # select plotting axes based on number of image rows on plot - else case when 1 row
axA.imshow(dataA["image"]) axA.imshow(dataA["image"])
add_bounding_boxes(axA, dataA["annotation"]) add_bounding_boxes(axA, dataA[annot_name])
axA.title.set_text("Original" + str(cur_ix+1)) axA.title.set_text("Original" + str(cur_ix+1))
axB.imshow(dataB["image"]) axB.imshow(dataB["image"])
add_bounding_boxes(axB, dataB["annotation"]) add_bounding_boxes(axB, dataB[annot_name])
axB.title.set_text("Augmented" + str(cur_ix+1)) axB.title.set_text("Augmented" + str(cur_ix+1))
logger.info("Original **\n{} : {}".format(str(cur_ix+1), dataA["annotation"])) logger.info("Original **\n{} : {}".format(str(cur_ix+1), dataA[annot_name]))
logger.info("Augmented **\n{} : {}\n".format(str(cur_ix+1), dataB["annotation"])) logger.info("Augmented **\n{} : {}\n".format(str(cur_ix+1), dataB[annot_name]))
plt.show() plt.show()
@ -381,19 +383,19 @@ def check_bad_bbox(data, test_op, invalid_bbox_type, expected_error):
width = img.shape[1] width = img.shape[1]
if invalid_bbox_type_ == InvalidBBoxType.WidthOverflow: if invalid_bbox_type_ == InvalidBBoxType.WidthOverflow:
# use box that overflows on width # use box that overflows on width
return img, np.array([[0, 0, width + 1, height, 0, 0, 0]]).astype(np.uint32) return img, np.array([[0, 0, width + 1, height, 0, 0, 0]]).astype(np.float32)
if invalid_bbox_type_ == InvalidBBoxType.HeightOverflow: if invalid_bbox_type_ == InvalidBBoxType.HeightOverflow:
# use box that overflows on height # use box that overflows on height
return img, np.array([[0, 0, width, height + 1, 0, 0, 0]]).astype(np.uint32) return img, np.array([[0, 0, width, height + 1, 0, 0, 0]]).astype(np.float32)
if invalid_bbox_type_ == InvalidBBoxType.NegativeXY: if invalid_bbox_type_ == InvalidBBoxType.NegativeXY:
# use box with negative xy # use box with negative xy
return img, np.array([[-10, -10, width, height, 0, 0, 0]]).astype(np.uint32) return img, np.array([[-10, -10, width, height, 0, 0, 0]]).astype(np.float32)
if invalid_bbox_type_ == InvalidBBoxType.WrongShape: if invalid_bbox_type_ == InvalidBBoxType.WrongShape:
# use box that has incorrect shape # use box that has incorrect shape
return img, np.array([[0, 0, width - 1]]).astype(np.uint32) return img, np.array([[0, 0, width - 1]]).astype(np.float32)
return img, bboxes return img, bboxes
try: try:

Loading…
Cancel
Save