Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
magicwindyyd
mindspore
提交
7bdcc319
M
mindspore
项目概览
magicwindyyd
/
mindspore
与 Fork 源项目一致
Fork自
MindSpore / mindspore
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
mindspore
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
7bdcc319
编写于
6月 20, 2020
作者:
M
mindspore-ci-bot
提交者:
Gitee
6月 20, 2020
浏览文件
操作
浏览文件
下载
差异文件
!2325 Addressing comments from PR2314
Merge pull request !2325 from imaaamin/object_ops_pr2
上级
01706d43
edc42c5b
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
99 addition
and
128 deletion
+99
-128
mindspore/ccsrc/dataset/api/python_bindings.cc
mindspore/ccsrc/dataset/api/python_bindings.cc
+3
-3
mindspore/ccsrc/dataset/kernels/image/bounding_box_augment_op.cc
...re/ccsrc/dataset/kernels/image/bounding_box_augment_op.cc
+7
-6
mindspore/ccsrc/dataset/kernels/image/bounding_box_augment_op.h
...ore/ccsrc/dataset/kernels/image/bounding_box_augment_op.h
+8
-6
mindspore/ccsrc/dataset/kernels/image/random_horizontal_flip_bbox_op.cc
...c/dataset/kernels/image/random_horizontal_flip_bbox_op.cc
+6
-7
mindspore/ccsrc/dataset/kernels/tensor_op.h
mindspore/ccsrc/dataset/kernels/tensor_op.h
+4
-0
mindspore/dataset/transforms/vision/c_transforms.py
mindspore/dataset/transforms/vision/c_transforms.py
+7
-4
mindspore/dataset/transforms/vision/validators.py
mindspore/dataset/transforms/vision/validators.py
+2
-2
tests/ut/python/dataset/test_bounding_box_augment.py
tests/ut/python/dataset/test_bounding_box_augment.py
+34
-57
tests/ut/python/dataset/test_random_horizontal_flip_bbox.py
tests/ut/python/dataset/test_random_horizontal_flip_bbox.py
+28
-43
未找到文件。
mindspore/ccsrc/dataset/api/python_bindings.cc
浏览文件 @
7bdcc319
...
...
@@ -353,10 +353,10 @@ void bindTensorOps1(py::module *m) {
.
def
(
py
::
init
<
std
::
vector
<
std
::
shared_ptr
<
TensorOp
>>
,
int32_t
>
(),
py
::
arg
(
"operations"
),
py
::
arg
(
"NumOps"
)
=
UniformAugOp
::
kDefNumOps
);
(
void
)
py
::
class_
<
BoundingBoxAug
Op
,
TensorOp
,
std
::
shared_ptr
<
BoundingBoxAug
Op
>>
(
*
m
,
"BoundingBoxAugOp"
,
"Tensor operation to apply a transformation on a random choice of bounding boxes."
)
(
void
)
py
::
class_
<
BoundingBoxAug
mentOp
,
TensorOp
,
std
::
shared_ptr
<
BoundingBoxAugment
Op
>>
(
*
m
,
"BoundingBoxAug
ment
Op"
,
"Tensor operation to apply a transformation on a random choice of bounding boxes."
)
.
def
(
py
::
init
<
std
::
shared_ptr
<
TensorOp
>
,
float
>
(),
py
::
arg
(
"transform"
),
py
::
arg
(
"ratio"
)
=
BoundingBoxAug
Op
::
d
efRatio
);
py
::
arg
(
"ratio"
)
=
BoundingBoxAug
mentOp
::
kD
efRatio
);
(
void
)
py
::
class_
<
ResizeBilinearOp
,
TensorOp
,
std
::
shared_ptr
<
ResizeBilinearOp
>>
(
*
m
,
"ResizeBilinearOp"
,
...
...
mindspore/ccsrc/dataset/kernels/image/bounding_box_augment_op.cc
浏览文件 @
7bdcc319
...
...
@@ -23,12 +23,14 @@
namespace
mindspore
{
namespace
dataset
{
const
float
BoundingBoxAug
Op
::
d
efRatio
=
0.3
;
const
float
BoundingBoxAug
mentOp
::
kD
efRatio
=
0.3
;
BoundingBoxAugOp
::
BoundingBoxAugOp
(
std
::
shared_ptr
<
TensorOp
>
transform
,
float
ratio
)
:
ratio_
(
ratio
),
transform_
(
std
::
move
(
transform
))
{}
BoundingBoxAugmentOp
::
BoundingBoxAugmentOp
(
std
::
shared_ptr
<
TensorOp
>
transform
,
float
ratio
)
:
ratio_
(
ratio
),
transform_
(
std
::
move
(
transform
))
{
rnd_
.
seed
(
GetSeed
());
}
Status
BoundingBoxAugOp
::
Compute
(
const
TensorRow
&
input
,
TensorRow
*
output
)
{
Status
BoundingBoxAug
ment
Op
::
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
];
...
...
@@ -37,8 +39,7 @@ Status BoundingBoxAugOp::Compute(const TensorRow &input, TensorRow *output) {
std
::
vector
<
uint32_t
>
selected_boxes
;
for
(
uint32_t
i
=
0
;
i
<
num_of_boxes
;
i
++
)
boxes
[
i
]
=
i
;
// sample bboxes according to ratio picked by user
std
::
random_device
rd
;
std
::
sample
(
boxes
.
begin
(),
boxes
.
end
(),
std
::
back_inserter
(
selected_boxes
),
num_to_aug
,
std
::
mt19937
(
rd
()));
std
::
sample
(
boxes
.
begin
(),
boxes
.
end
(),
std
::
back_inserter
(
selected_boxes
),
num_to_aug
,
rnd_
);
std
::
shared_ptr
<
Tensor
>
crop_out
;
std
::
shared_ptr
<
Tensor
>
res_out
;
std
::
shared_ptr
<
CVTensor
>
input_restore
=
CVTensor
::
AsCVTensor
(
input
[
0
]);
...
...
mindspore/ccsrc/dataset/kernels/image/bounding_box_augment_op.h
浏览文件 @
7bdcc319
...
...
@@ -24,33 +24,35 @@
#include "dataset/core/tensor.h"
#include "dataset/kernels/tensor_op.h"
#include "dataset/util/status.h"
#include "dataset/util/random.h"
namespace
mindspore
{
namespace
dataset
{
class
BoundingBoxAugOp
:
public
TensorOp
{
class
BoundingBoxAug
ment
Op
:
public
TensorOp
{
public:
// Default values, also used by python_bindings.cc
static
const
float
d
efRatio
;
static
const
float
kD
efRatio
;
// Constructor for BoundingBoxAugmentOp
// @param std::shared_ptr<TensorOp> transform transform: C++ opration to apply on select bounding boxes
// @param float ratio: ratio of bounding boxes to have the transform applied on
BoundingBoxAugOp
(
std
::
shared_ptr
<
TensorOp
>
transform
,
float
ratio
);
BoundingBoxAug
ment
Op
(
std
::
shared_ptr
<
TensorOp
>
transform
,
float
ratio
);
~
BoundingBoxAugOp
()
override
=
default
;
~
BoundingBoxAug
ment
Op
()
override
=
default
;
// Provide stream operator for displaying it
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
const
BoundingBoxAugOp
&
so
)
{
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
const
BoundingBoxAug
ment
Op
&
so
)
{
so
.
Print
(
out
);
return
out
;
}
void
Print
(
std
::
ostream
&
out
)
const
override
{
out
<<
"BoundingBoxAugOp"
;
}
void
Print
(
std
::
ostream
&
out
)
const
override
{
out
<<
"BoundingBoxAug
ment
Op"
;
}
Status
Compute
(
const
TensorRow
&
input
,
TensorRow
*
output
)
override
;
private:
float
ratio_
;
std
::
mt19937
rnd_
;
std
::
shared_ptr
<
TensorOp
>
transform_
;
};
}
// namespace dataset
...
...
mindspore/ccsrc/dataset/kernels/image/random_horizontal_flip_bbox_op.cc
浏览文件 @
7bdcc319
...
...
@@ -29,20 +29,19 @@ Status RandomHorizontalFlipWithBBoxOp::Compute(const TensorRow &input, TensorRow
BOUNDING_BOX_CHECK
(
input
);
if
(
distribution_
(
rnd_
))
{
// To test bounding boxes algorithm, create random bboxes from image dims
size_t
num
OfBB
oxes
=
input
[
1
]
->
shape
()[
0
];
// set to give number of bboxes
float
img
C
enter
=
(
input
[
0
]
->
shape
()[
1
]
/
2
);
// get the center of the image
size_t
num
_of_b
oxes
=
input
[
1
]
->
shape
()[
0
];
// set to give number of bboxes
float
img
_c
enter
=
(
input
[
0
]
->
shape
()[
1
]
/
2
);
// get the center of the image
for
(
int
i
=
0
;
i
<
num
OfBB
oxes
;
i
++
)
{
for
(
int
i
=
0
;
i
<
num
_of_b
oxes
;
i
++
)
{
uint32_t
b_w
=
0
;
// bounding box width
uint32_t
min_x
=
0
;
// get the required items
input
[
1
]
->
GetItemAt
<
uint32_t
>
(
&
min_x
,
{
i
,
0
});
input
[
1
]
->
GetItemAt
<
uint32_t
>
(
&
b_w
,
{
i
,
2
});
// do the flip
float
diff
=
imgCenter
-
min_x
;
// get distance from min_x to center
uint32_t
refl_min_x
=
diff
+
imgCenter
;
// get reflection of min_x
uint32_t
new_min_x
=
refl_min_x
-
b_w
;
// subtract from the reflected min_x to get the new one
float
diff
=
img_center
-
min_x
;
// get distance from min_x to center
uint32_t
refl_min_x
=
diff
+
img_center
;
// get reflection of min_x
uint32_t
new_min_x
=
refl_min_x
-
b_w
;
// subtract from the reflected min_x to get the new one
input
[
1
]
->
SetItemAt
<
uint32_t
>
({
i
,
0
},
new_min_x
);
}
(
*
output
).
push_back
(
nullptr
);
...
...
mindspore/ccsrc/dataset/kernels/tensor_op.h
浏览文件 @
7bdcc319
...
...
@@ -45,6 +45,10 @@
#define BOUNDING_BOX_CHECK(input) \
do { \
if (input[1]->shape().Size() < 2) { \
return Status(StatusCode::kBoundingBoxInvalidShape, __LINE__, __FILE__, \
"Bounding boxes shape should have at least two dims"); \
} \
uint32_t num_of_features = input[1]->shape()[1]; \
if (num_of_features < 4) { \
return Status(StatusCode::kBoundingBoxInvalidShape, __LINE__, __FILE__, \
...
...
mindspore/dataset/transforms/vision/c_transforms.py
浏览文件 @
7bdcc319
...
...
@@ -254,13 +254,16 @@ class RandomVerticalFlipWithBBox(cde.RandomVerticalFlipWithBBoxOp):
super
().
__init__
(
prob
)
class
BoundingBoxAug
(
cde
.
BoundingBoxAug
Op
):
class
BoundingBoxAug
ment
(
cde
.
BoundingBoxAugment
Op
):
"""
Flip the input image vertically, randomly with a given probability.
Apply a given image transform on a random selection of bounding box regions
of a given image.
Args:
transform: C++ operation (python OPs are not accepted).
ratio (float): Ratio of bounding boxes to apply augmentation on. Range: [0,1] (default=1).
transform: C++ transformation function to be applied on random selection
of bounding box regions of a given image.
ratio (float, optional): Ratio of bounding boxes to apply augmentation on.
Range: [0,1] (default=0.3).
"""
@
check_bounding_box_augment_cpp
def
__init__
(
self
,
transform
,
ratio
=
0.3
):
...
...
mindspore/dataset/transforms/vision/validators.py
浏览文件 @
7bdcc319
...
...
@@ -862,13 +862,13 @@ def check_bounding_box_augment_cpp(method):
transform
=
kwargs
.
get
(
"transform"
)
if
"ratio"
in
kwargs
:
ratio
=
kwargs
.
get
(
"ratio"
)
if
not
isinstance
(
ratio
,
float
)
and
not
isinstance
(
ratio
,
int
):
raise
ValueError
(
"Ratio should be an int or float."
)
if
ratio
is
not
None
:
check_value
(
ratio
,
[
0.
,
1.
])
kwargs
[
"ratio"
]
=
ratio
else
:
ratio
=
0.3
if
not
isinstance
(
ratio
,
float
)
and
not
isinstance
(
ratio
,
int
):
raise
ValueError
(
"Ratio should be an int or float."
)
if
not
isinstance
(
transform
,
TensorOp
):
raise
ValueError
(
"Transform can only be a C++ operation."
)
kwargs
[
"transform"
]
=
transform
...
...
tests/ut/python/dataset/test_bounding_box_augment.py
浏览文件 @
7bdcc319
...
...
@@ -16,7 +16,7 @@
Testing the bounding box augment op in DE
"""
from
enum
import
Enum
from
mindspore
import
log
as
logger
import
mindspore.
log
as
logger
import
mindspore.dataset
as
ds
import
mindspore.dataset.transforms.vision.c_transforms
as
c_vision
import
matplotlib.pyplot
as
plt
...
...
@@ -39,59 +39,36 @@ class BoxType(Enum):
WrongShape
=
5
class
AddBadAnnotation
:
# pylint: disable=too-few-public-methods
def
add_bad_annotation
(
img
,
bboxes
,
box_type
):
"""
Used to add erroneous bounding boxes to object detection pipelines.
Usage:
>>> # Adds a box that covers the whole image. Good for testing edge cases
>>> de = de.map(input_columns=["image", "annotation"],
>>> output_columns=["image", "annotation"],
>>> operations=AddBadAnnotation(BoxType.OnEdge))
Used to generate erroneous bounding box examples on given img.
:param img: image where the bounding boxes are.
:param bboxes: in [x_min, y_min, w, h, label, truncate, difficult] format
:param box_type: type of bad box
:return: bboxes with bad examples added
"""
height
=
img
.
shape
[
0
]
width
=
img
.
shape
[
1
]
if
box_type
==
BoxType
.
WidthOverflow
:
# use box that overflows on width
return
img
,
np
.
array
([[
0
,
0
,
width
+
1
,
height
,
0
,
0
,
0
]]).
astype
(
np
.
uint32
)
def
__init__
(
self
,
box_type
):
self
.
box_type
=
box_type
def
__call__
(
self
,
img
,
bboxes
):
"""
Used to generate erroneous bounding box examples on given img.
:param img: image where the bounding boxes are.
:param bboxes: in [x_min, y_min, w, h, label, truncate, difficult] format
:return: bboxes with bad examples added
"""
height
=
img
.
shape
[
0
]
width
=
img
.
shape
[
1
]
if
self
.
box_type
==
BoxType
.
WidthOverflow
:
# use box that overflows on width
return
img
,
np
.
array
([[
0
,
0
,
width
+
1
,
height
,
0
,
0
,
0
]]).
astype
(
np
.
uint32
)
if
self
.
box_type
==
BoxType
.
HeightOverflow
:
# use box that overflows on height
return
img
,
np
.
array
([[
0
,
0
,
width
,
height
+
1
,
0
,
0
,
0
]]).
astype
(
np
.
uint32
)
if
self
.
box_type
==
BoxType
.
NegativeXY
:
# use box with negative xy
return
img
,
np
.
array
([[
-
10
,
-
10
,
width
,
height
,
0
,
0
,
0
]]).
astype
(
np
.
uint32
)
if
self
.
box_type
==
BoxType
.
OnEdge
:
# use box that covers the whole image
return
img
,
np
.
array
([[
0
,
0
,
width
,
height
,
0
,
0
,
0
]]).
astype
(
np
.
uint32
)
if
self
.
box_type
==
BoxType
.
WrongShape
:
# use box that covers the whole image
return
img
,
np
.
array
([[
0
,
0
,
width
-
1
]]).
astype
(
np
.
uint32
)
return
img
,
bboxes
def
h_flip
(
image
):
"""
Apply the random_horizontal
"""
if
box_type
==
BoxType
.
HeightOverflow
:
# use box that overflows on height
return
img
,
np
.
array
([[
0
,
0
,
width
,
height
+
1
,
0
,
0
,
0
]]).
astype
(
np
.
uint32
)
if
box_type
==
BoxType
.
NegativeXY
:
# use box with negative xy
return
img
,
np
.
array
([[
-
10
,
-
10
,
width
,
height
,
0
,
0
,
0
]]).
astype
(
np
.
uint32
)
if
box_type
==
BoxType
.
OnEdge
:
# use box that covers the whole image
return
img
,
np
.
array
([[
0
,
0
,
width
,
height
,
0
,
0
,
0
]]).
astype
(
np
.
uint32
)
# with the seed provided in this test case, it will always flip.
# that's why we flip here too
image
=
image
[:,
::
-
1
,
:]
return
im
age
if
box_type
==
BoxType
.
WrongShape
:
# use box that covers the whole image
return
img
,
np
.
array
([[
0
,
0
,
width
-
1
]]).
astype
(
np
.
uint32
)
return
im
g
,
bboxes
def
check_bad_box
(
data
,
box_type
,
expected_error
):
...
...
@@ -102,8 +79,8 @@ def check_bad_box(data, box_type, expected_error):
:return: None
"""
try
:
test_op
=
c_vision
.
BoundingBoxAug
(
c_vision
.
RandomHorizontalFlip
(
1
),
1
)
# DEFINE TEST OP HERE -- (PROB 1 IN CASE OF RANDOM)
test_op
=
c_vision
.
BoundingBoxAug
ment
(
c_vision
.
RandomHorizontalFlip
(
1
),
1
)
# DEFINE TEST OP HERE -- (PROB 1 IN CASE OF RANDOM)
data
=
data
.
map
(
input_columns
=
[
"annotation"
],
output_columns
=
[
"annotation"
],
operations
=
fix_annotate
)
...
...
@@ -111,7 +88,7 @@ def check_bad_box(data, box_type, expected_error):
data
=
data
.
map
(
input_columns
=
[
"image"
,
"annotation"
],
output_columns
=
[
"image"
,
"annotation"
],
columns_order
=
[
"image"
,
"annotation"
],
operations
=
AddBadAnnotation
(
box_type
))
# Add column for "annotation"
operations
=
lambda
img
,
bboxes
:
add_bad_annotation
(
img
,
bboxes
,
box_type
))
# map to apply ops
data
=
data
.
map
(
input_columns
=
[
"image"
,
"annotation"
],
output_columns
=
[
"image"
,
"annotation"
],
...
...
@@ -187,7 +164,7 @@ def test_bounding_box_augment_with_rotation_op(plot=False):
data_voc1
=
ds
.
VOCDataset
(
DATA_DIR
,
task
=
"Detection"
,
mode
=
"train"
,
decode
=
True
,
shuffle
=
False
)
data_voc2
=
ds
.
VOCDataset
(
DATA_DIR
,
task
=
"Detection"
,
mode
=
"train"
,
decode
=
True
,
shuffle
=
False
)
test_op
=
c_vision
.
BoundingBoxAug
(
c_vision
.
RandomRotation
(
90
),
1
)
test_op
=
c_vision
.
BoundingBoxAug
ment
(
c_vision
.
RandomRotation
(
90
),
1
)
# DEFINE TEST OP HERE -- (PROB 1 IN CASE OF RANDOM)
# maps to fix annotations to minddata standard
...
...
@@ -216,7 +193,7 @@ def test_bounding_box_augment_with_crop_op(plot=False):
data_voc1
=
ds
.
VOCDataset
(
DATA_DIR
,
task
=
"Detection"
,
mode
=
"train"
,
decode
=
True
,
shuffle
=
False
)
data_voc2
=
ds
.
VOCDataset
(
DATA_DIR
,
task
=
"Detection"
,
mode
=
"train"
,
decode
=
True
,
shuffle
=
False
)
test_op
=
c_vision
.
BoundingBoxAug
(
c_vision
.
RandomCrop
(
90
),
1
)
test_op
=
c_vision
.
BoundingBoxAug
ment
(
c_vision
.
RandomCrop
(
90
),
1
)
# maps to fix annotations to minddata standard
data_voc1
=
data_voc1
.
map
(
input_columns
=
[
"annotation"
],
...
...
@@ -244,7 +221,7 @@ def test_bounding_box_augment_valid_ratio_c(plot=False):
data_voc1
=
ds
.
VOCDataset
(
DATA_DIR
,
task
=
"Detection"
,
mode
=
"train"
,
decode
=
True
,
shuffle
=
False
)
data_voc2
=
ds
.
VOCDataset
(
DATA_DIR
,
task
=
"Detection"
,
mode
=
"train"
,
decode
=
True
,
shuffle
=
False
)
test_op
=
c_vision
.
BoundingBoxAug
(
c_vision
.
RandomHorizontalFlip
(
1
),
0.9
)
test_op
=
c_vision
.
BoundingBoxAug
ment
(
c_vision
.
RandomHorizontalFlip
(
1
),
0.9
)
# DEFINE TEST OP HERE -- (PROB 1 IN CASE OF RANDOM)
# maps to fix annotations to minddata standard
...
...
@@ -274,7 +251,7 @@ def test_bounding_box_augment_invalid_ratio_c():
try
:
# ratio range is from 0 - 1
test_op
=
c_vision
.
BoundingBoxAug
(
c_vision
.
RandomHorizontalFlip
(
1
),
1.5
)
test_op
=
c_vision
.
BoundingBoxAug
ment
(
c_vision
.
RandomHorizontalFlip
(
1
),
1.5
)
# maps to fix annotations to minddata standard
data_voc1
=
data_voc1
.
map
(
input_columns
=
[
"annotation"
],
output_columns
=
[
"annotation"
],
...
...
tests/ut/python/dataset/test_random_horizontal_flip_bbox.py
浏览文件 @
7bdcc319
...
...
@@ -16,12 +16,12 @@
Testing the random horizontal flip with bounding boxes op in DE
"""
from
enum
import
Enum
from
mindspore
import
log
as
logger
import
mindspore.dataset
as
ds
import
mindspore.dataset.transforms.vision.c_transforms
as
c_vision
import
matplotlib.pyplot
as
plt
import
matplotlib.patches
as
patches
import
numpy
as
np
import
mindspore.log
as
logger
import
mindspore.dataset
as
ds
import
mindspore.dataset.transforms.vision.c_transforms
as
c_vision
GENERATE_GOLDEN
=
False
...
...
@@ -38,57 +38,42 @@ class BoxType(Enum):
OnEdge
=
4
WrongShape
=
5
class
AddBadAnnotation
:
# pylint: disable=too-few-public-methods
def
add_bad_annotation
(
img
,
bboxes
,
box_type
):
"""
Used to add erroneous bounding boxes to object detection pipelines.
Usage:
>>> # Adds a box that covers the whole image. Good for testing edge cases
>>> de = de.map(input_columns=["image", "annotation"],
>>> output_columns=["image", "annotation"],
>>> operations=AddBadAnnotation(BoxType.OnEdge))
Used to generate erroneous bounding box examples on given img.
:param img: image where the bounding boxes are.
:param bboxes: in [x_min, y_min, w, h, label, truncate, difficult] format
:param box_type: type of bad box
:return: bboxes with bad examples added
"""
height
=
img
.
shape
[
0
]
width
=
img
.
shape
[
1
]
if
box_type
==
BoxType
.
WidthOverflow
:
# use box that overflows on width
return
img
,
np
.
array
([[
0
,
0
,
width
+
1
,
height
,
0
,
0
,
0
]]).
astype
(
np
.
uint32
)
def
__init__
(
self
,
box_type
):
self
.
box_type
=
box_type
def
__call__
(
self
,
img
,
bboxes
):
"""
Used to generate erroneous bounding box examples on given img.
:param img: image where the bounding boxes are.
:param bboxes: in [x_min, y_min, w, h, label, truncate, difficult] format
:return: bboxes with bad examples added
"""
height
=
img
.
shape
[
0
]
width
=
img
.
shape
[
1
]
if
self
.
box_type
==
BoxType
.
WidthOverflow
:
# use box that overflows on width
return
img
,
np
.
array
([[
0
,
0
,
width
+
1
,
height
,
0
,
0
,
0
]]).
astype
(
np
.
uint32
)
if
box_type
==
BoxType
.
HeightOverflow
:
# use box that overflows on height
return
img
,
np
.
array
([[
0
,
0
,
width
,
height
+
1
,
0
,
0
,
0
]]).
astype
(
np
.
uint32
)
if
self
.
box_type
==
BoxType
.
HeightOverflow
:
# use box that overflows on height
return
img
,
np
.
array
([[
0
,
0
,
width
,
height
+
1
,
0
,
0
,
0
]]).
astype
(
np
.
uint32
)
if
box_type
==
BoxType
.
NegativeXY
:
# use box with negative xy
return
img
,
np
.
array
([[
-
10
,
-
10
,
width
,
height
,
0
,
0
,
0
]]).
astype
(
np
.
uint32
)
if
self
.
box_type
==
BoxType
.
NegativeXY
:
# use box with negative xy
return
img
,
np
.
array
([[
-
10
,
-
1
0
,
width
,
height
,
0
,
0
,
0
]]).
astype
(
np
.
uint32
)
if
box_type
==
BoxType
.
OnEdge
:
# use box that covers the whole image
return
img
,
np
.
array
([[
0
,
0
,
width
,
height
,
0
,
0
,
0
]]).
astype
(
np
.
uint32
)
if
self
.
box_type
==
BoxType
.
OnEdge
:
# use box that covers the whole image
return
img
,
np
.
array
([[
0
,
0
,
width
,
height
,
0
,
0
,
0
]]).
astype
(
np
.
uint32
)
if
self
.
box_type
==
BoxType
.
WrongShape
:
# use box that covers the whole image
return
img
,
np
.
array
([[
0
,
0
,
width
-
1
]]).
astype
(
np
.
uint32
)
return
img
,
bboxes
if
box_type
==
BoxType
.
WrongShape
:
# use box that covers the whole image
return
img
,
np
.
array
([[
0
,
0
,
width
-
1
]]).
astype
(
np
.
uint32
)
return
img
,
bboxes
def
h_flip
(
image
):
"""
Apply the random_horizontal
"""
# with the seed provided in this test case, it will always flip.
# that's why we flip here too
image
=
image
[:,
::
-
1
,
:]
return
image
...
...
@@ -111,7 +96,7 @@ def check_bad_box(data, box_type, expected_error):
data
=
data
.
map
(
input_columns
=
[
"image"
,
"annotation"
],
output_columns
=
[
"image"
,
"annotation"
],
columns_order
=
[
"image"
,
"annotation"
],
operations
=
AddBadAnnotation
(
box_type
))
# Add column for "annotation"
operations
=
lambda
img
,
bboxes
:
add_bad_annotation
(
img
,
bboxes
,
box_type
))
# map to apply ops
data
=
data
.
map
(
input_columns
=
[
"image"
,
"annotation"
],
output_columns
=
[
"image"
,
"annotation"
],
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录