Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
mmdetection3d
Commits
c9b69f5a
Commit
c9b69f5a
authored
May 20, 2022
by
ZwwWayne
Committed by
ChaimZhu
Jul 20, 2022
Browse files
Clean unit tests
parent
a34823dc
Changes
50
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
22 additions
and
1388 deletions
+22
-1388
tests/test_models/test_heads/test_pointnet2_decode_head.py
tests/test_models/test_heads/test_pointnet2_decode_head.py
+0
-83
tests/test_models/test_heads/test_roi_extractors.py
tests/test_models/test_heads/test_roi_extractors.py
+0
-56
tests/test_models/test_heads/test_semantic_heads.py
tests/test_models/test_heads/test_semantic_heads.py
+0
-82
tests/test_models/test_losses.py
tests/test_models/test_losses.py
+22
-1
tests/test_models/test_segmentors.py
tests/test_models/test_segmentors.py
+0
-352
tests/test_models/test_voxel_encoders/test_voxel_encoders.py
tests/test_models/test_voxel_encoders/test_voxel_encoders.py
+0
-0
tests/test_models/test_voxel_encoders/test_voxel_generator.py
...s/test_models/test_voxel_encoders/test_voxel_generator.py
+0
-0
tests/test_runtime/test_apis.py
tests/test_runtime/test_apis.py
+0
-362
tests/test_runtime/test_config.py
tests/test_runtime/test_config.py
+0
-302
tests/test_utils/test_assigners.py
tests/test_utils/test_assigners.py
+0
-150
No files found.
tests/test_models/test_heads/test_pointnet2_decode_head.py
deleted
100644 → 0
View file @
a34823dc
# Copyright (c) OpenMMLab. All rights reserved.
import
numpy
as
np
import
pytest
import
torch
from
mmcv.cnn.bricks
import
ConvModule
from
mmdet3d.models.builder
import
build_head
def
test_pn2_decode_head_loss
():
if
not
torch
.
cuda
.
is_available
():
pytest
.
skip
(
'test requires GPU and torch+cuda'
)
pn2_decode_head_cfg
=
dict
(
type
=
'PointNet2Head'
,
fp_channels
=
((
768
,
256
,
256
),
(
384
,
256
,
256
),
(
320
,
256
,
128
),
(
128
,
128
,
128
,
128
)),
channels
=
128
,
num_classes
=
20
,
dropout_ratio
=
0.5
,
conv_cfg
=
dict
(
type
=
'Conv1d'
),
norm_cfg
=
dict
(
type
=
'BN1d'
),
act_cfg
=
dict
(
type
=
'ReLU'
),
loss_decode
=
dict
(
type
=
'CrossEntropyLoss'
,
use_sigmoid
=
False
,
class_weight
=
None
,
loss_weight
=
1.0
),
ignore_index
=
20
)
self
=
build_head
(
pn2_decode_head_cfg
)
self
.
cuda
()
assert
isinstance
(
self
.
conv_seg
,
torch
.
nn
.
Conv1d
)
assert
self
.
conv_seg
.
in_channels
==
128
assert
self
.
conv_seg
.
out_channels
==
20
assert
self
.
conv_seg
.
kernel_size
==
(
1
,
)
assert
isinstance
(
self
.
pre_seg_conv
,
ConvModule
)
assert
isinstance
(
self
.
pre_seg_conv
.
conv
,
torch
.
nn
.
Conv1d
)
assert
self
.
pre_seg_conv
.
conv
.
in_channels
==
128
assert
self
.
pre_seg_conv
.
conv
.
out_channels
==
128
assert
self
.
pre_seg_conv
.
conv
.
kernel_size
==
(
1
,
)
assert
isinstance
(
self
.
pre_seg_conv
.
bn
,
torch
.
nn
.
BatchNorm1d
)
assert
self
.
pre_seg_conv
.
bn
.
num_features
==
128
assert
isinstance
(
self
.
pre_seg_conv
.
activate
,
torch
.
nn
.
ReLU
)
# test forward
sa_xyz
=
[
torch
.
rand
(
2
,
4096
,
3
).
float
().
cuda
(),
torch
.
rand
(
2
,
1024
,
3
).
float
().
cuda
(),
torch
.
rand
(
2
,
256
,
3
).
float
().
cuda
(),
torch
.
rand
(
2
,
64
,
3
).
float
().
cuda
(),
torch
.
rand
(
2
,
16
,
3
).
float
().
cuda
(),
]
sa_features
=
[
torch
.
rand
(
2
,
6
,
4096
).
float
().
cuda
(),
torch
.
rand
(
2
,
64
,
1024
).
float
().
cuda
(),
torch
.
rand
(
2
,
128
,
256
).
float
().
cuda
(),
torch
.
rand
(
2
,
256
,
64
).
float
().
cuda
(),
torch
.
rand
(
2
,
512
,
16
).
float
().
cuda
(),
]
input_dict
=
dict
(
sa_xyz
=
sa_xyz
,
sa_features
=
sa_features
)
seg_logits
=
self
(
input_dict
)
assert
seg_logits
.
shape
==
torch
.
Size
([
2
,
20
,
4096
])
# test loss
pts_semantic_mask
=
torch
.
randint
(
0
,
20
,
(
2
,
4096
)).
long
().
cuda
()
losses
=
self
.
losses
(
seg_logits
,
pts_semantic_mask
)
assert
losses
[
'loss_sem_seg'
].
item
()
>
0
# test loss with ignore_index
ignore_index_mask
=
torch
.
ones_like
(
pts_semantic_mask
)
*
20
losses
=
self
.
losses
(
seg_logits
,
ignore_index_mask
)
assert
losses
[
'loss_sem_seg'
].
item
()
==
0
# test loss with class_weight
pn2_decode_head_cfg
[
'loss_decode'
]
=
dict
(
type
=
'CrossEntropyLoss'
,
use_sigmoid
=
False
,
class_weight
=
np
.
random
.
rand
(
20
),
loss_weight
=
1.0
)
self
=
build_head
(
pn2_decode_head_cfg
)
self
.
cuda
()
losses
=
self
.
losses
(
seg_logits
,
pts_semantic_mask
)
assert
losses
[
'loss_sem_seg'
].
item
()
>
0
tests/test_models/test_heads/test_roi_extractors.py
deleted
100644 → 0
View file @
a34823dc
# Copyright (c) OpenMMLab. All rights reserved.
import
numpy
as
np
import
pytest
import
torch
from
mmdet3d.models.roi_heads.roi_extractors
import
(
Single3DRoIAwareExtractor
,
Single3DRoIPointExtractor
)
def
test_single_roiaware_extractor
():
if
not
torch
.
cuda
.
is_available
():
pytest
.
skip
(
'test requires GPU and torch+cuda'
)
roi_layer_cfg
=
dict
(
type
=
'RoIAwarePool3d'
,
out_size
=
4
,
max_pts_per_voxel
=
128
,
mode
=
'max'
)
self
=
Single3DRoIAwareExtractor
(
roi_layer
=
roi_layer_cfg
)
feats
=
torch
.
tensor
(
[[
1
,
2
,
3.3
],
[
1.2
,
2.5
,
3.0
],
[
0.8
,
2.1
,
3.5
],
[
1.6
,
2.6
,
3.6
],
[
0.8
,
1.2
,
3.9
],
[
-
9.2
,
21.0
,
18.2
],
[
3.8
,
7.9
,
6.3
],
[
4.7
,
3.5
,
-
12.2
],
[
3.8
,
7.6
,
-
2
],
[
-
10.6
,
-
12.9
,
-
20
],
[
-
16
,
-
18
,
9
],
[
-
21.3
,
-
52
,
-
5
],
[
0
,
0
,
0
],
[
6
,
7
,
8
],
[
-
2
,
-
3
,
-
4
]],
dtype
=
torch
.
float32
).
cuda
()
coordinate
=
feats
.
clone
()
batch_inds
=
torch
.
zeros
(
feats
.
shape
[
0
]).
cuda
()
rois
=
torch
.
tensor
([[
0
,
1.0
,
2.0
,
3.0
,
5.0
,
4.0
,
6.0
,
-
0.3
-
np
.
pi
/
2
],
[
0
,
-
10.0
,
23.0
,
16.0
,
20
,
10
,
20
,
-
0.5
-
np
.
pi
/
2
]],
dtype
=
torch
.
float32
).
cuda
()
# test forward
pooled_feats
=
self
(
feats
,
coordinate
,
batch_inds
,
rois
)
assert
pooled_feats
.
shape
==
torch
.
Size
([
2
,
4
,
4
,
4
,
3
])
assert
torch
.
allclose
(
pooled_feats
.
sum
(),
torch
.
tensor
(
51.100
).
cuda
(),
1e-3
)
def
test_single_roipoint_extractor
():
if
not
torch
.
cuda
.
is_available
():
pytest
.
skip
(
'test requires GPU and torch+cuda'
)
roi_layer_cfg
=
dict
(
type
=
'RoIPointPool3d'
,
num_sampled_points
=
512
)
self
=
Single3DRoIPointExtractor
(
roi_layer
=
roi_layer_cfg
)
feats
=
torch
.
tensor
(
[[
1
,
2
,
3.3
],
[
1.2
,
2.5
,
3.0
],
[
0.8
,
2.1
,
3.5
],
[
1.6
,
2.6
,
3.6
],
[
0.8
,
1.2
,
3.9
],
[
-
9.2
,
21.0
,
18.2
],
[
3.8
,
7.9
,
6.3
],
[
4.7
,
3.5
,
-
12.2
],
[
3.8
,
7.6
,
-
2
],
[
-
10.6
,
-
12.9
,
-
20
],
[
-
16
,
-
18
,
9
],
[
-
21.3
,
-
52
,
-
5
],
[
0
,
0
,
0
],
[
6
,
7
,
8
],
[
-
2
,
-
3
,
-
4
]],
dtype
=
torch
.
float32
).
unsqueeze
(
0
).
cuda
()
points
=
feats
.
clone
()
batch_inds
=
feats
.
shape
[
0
]
rois
=
torch
.
tensor
([[
0
,
1.0
,
2.0
,
3.0
,
4.0
,
5.0
,
6.0
,
0.3
],
[
0
,
-
10.0
,
23.0
,
16.0
,
10
,
20
,
20
,
0.5
]],
dtype
=
torch
.
float32
).
cuda
()
pooled_feats
=
self
(
feats
,
points
,
batch_inds
,
rois
)
assert
pooled_feats
.
shape
==
torch
.
Size
([
2
,
512
,
6
])
tests/test_models/test_heads/test_semantic_heads.py
deleted
100644 → 0
View file @
a34823dc
# Copyright (c) OpenMMLab. All rights reserved.
import
pytest
import
torch
from
mmdet3d.core.bbox
import
LiDARInstance3DBoxes
def
test_PointwiseSemanticHead
():
# PointwiseSemanticHead only support gpu version currently.
if
not
torch
.
cuda
.
is_available
():
pytest
.
skip
(
'test requires GPU and torch+cuda'
)
from
mmdet3d.models.builder
import
build_head
head_cfg
=
dict
(
type
=
'PointwiseSemanticHead'
,
in_channels
=
8
,
extra_width
=
0.2
,
seg_score_thr
=
0.3
,
num_classes
=
3
,
loss_seg
=
dict
(
type
=
'FocalLoss'
,
use_sigmoid
=
True
,
reduction
=
'sum'
,
gamma
=
2.0
,
alpha
=
0.25
,
loss_weight
=
1.0
),
loss_part
=
dict
(
type
=
'CrossEntropyLoss'
,
use_sigmoid
=
True
,
loss_weight
=
1.0
))
self
=
build_head
(
head_cfg
)
self
.
cuda
()
# test forward
voxel_features
=
torch
.
rand
([
4
,
8
],
dtype
=
torch
.
float32
).
cuda
()
feats_dict
=
self
.
forward
(
voxel_features
)
assert
feats_dict
[
'seg_preds'
].
shape
==
torch
.
Size
(
[
voxel_features
.
shape
[
0
],
1
])
assert
feats_dict
[
'part_preds'
].
shape
==
torch
.
Size
(
[
voxel_features
.
shape
[
0
],
3
])
assert
feats_dict
[
'part_feats'
].
shape
==
torch
.
Size
(
[
voxel_features
.
shape
[
0
],
4
])
voxel_centers
=
torch
.
tensor
(
[[
6.56126
,
0.9648336
,
-
1.7339306
],
[
6.8162713
,
-
2.480431
,
-
1.3616394
],
[
11.643568
,
-
4.744306
,
-
1.3580885
],
[
23.482342
,
6.5036807
,
0.5806964
]
],
dtype
=
torch
.
float32
).
cuda
()
# n, point_features
coordinates
=
torch
.
tensor
(
[[
0
,
12
,
819
,
131
],
[
0
,
16
,
750
,
136
],
[
1
,
16
,
705
,
232
],
[
1
,
35
,
930
,
469
]],
dtype
=
torch
.
int32
).
cuda
()
# n, 4(batch, ind_x, ind_y, ind_z)
voxel_dict
=
dict
(
voxel_centers
=
voxel_centers
,
coors
=
coordinates
)
gt_bboxes
=
[
LiDARInstance3DBoxes
(
torch
.
tensor
(
[[
6.4118
,
-
3.4305
,
-
1.7291
,
1.7033
,
3.4693
,
1.6197
,
0.9091
]],
dtype
=
torch
.
float32
).
cuda
()),
LiDARInstance3DBoxes
(
torch
.
tensor
(
[[
16.9107
,
9.7925
,
-
1.9201
,
1.6097
,
3.2786
,
1.5307
,
2.4056
]],
dtype
=
torch
.
float32
).
cuda
())
]
# batch size is 2 in the unit test
gt_labels
=
list
(
torch
.
tensor
([[
0
],
[
1
]],
dtype
=
torch
.
int64
).
cuda
())
# test get_targets
target_dict
=
self
.
get_targets
(
voxel_dict
,
gt_bboxes
,
gt_labels
)
assert
target_dict
[
'seg_targets'
].
shape
==
torch
.
Size
(
[
voxel_features
.
shape
[
0
]])
assert
torch
.
allclose
(
target_dict
[
'seg_targets'
],
target_dict
[
'seg_targets'
].
new_tensor
([
3
,
-
1
,
3
,
3
]))
assert
target_dict
[
'part_targets'
].
shape
==
torch
.
Size
(
[
voxel_features
.
shape
[
0
],
3
])
assert
target_dict
[
'part_targets'
].
sum
()
==
0
# test loss
loss_dict
=
self
.
loss
(
feats_dict
,
target_dict
)
assert
loss_dict
[
'loss_seg'
]
>
0
assert
loss_dict
[
'loss_part'
]
==
0
# no points in gt_boxes
total_loss
=
loss_dict
[
'loss_seg'
]
+
loss_dict
[
'loss_part'
]
total_loss
.
backward
()
tests/test_m
etric
s/test_losses.py
→
tests/test_m
odel
s/test_losses.py
View file @
c9b69f5a
# Copyright (c) OpenMMLab. All rights reserved.
import
random
import
numpy
as
np
import
pytest
import
torch
from
torch
import
nn
as
nn
...
...
@@ -6,6 +9,25 @@ from torch import nn as nn
from
mmdet3d.models.builder
import
build_loss
def
set_random_seed
(
seed
,
deterministic
=
False
):
"""Set random seed.
Args:
seed (int): Seed to be used.
deterministic (bool): Whether to set the deterministic option for
CUDNN backend, i.e., set `torch.backends.cudnn.deterministic`
to True and `torch.backends.cudnn.benchmark` to False.
Default: False.
"""
random
.
seed
(
seed
)
np
.
random
.
seed
(
seed
)
torch
.
manual_seed
(
seed
)
torch
.
cuda
.
manual_seed_all
(
seed
)
if
deterministic
:
torch
.
backends
.
cudnn
.
deterministic
=
True
torch
.
backends
.
cudnn
.
benchmark
=
False
def
test_chamfer_disrance
():
from
mmdet3d.models.losses
import
ChamferDistance
,
chamfer_distance
...
...
@@ -78,7 +100,6 @@ def test_chamfer_disrance():
def
test_paconv_regularization_loss
():
from
mmdet3d.models.losses
import
PAConvRegularizationLoss
from
mmdet3d.ops
import
PAConv
,
PAConvCUDA
from
mmdet.apis
import
set_random_seed
class
ToyModel
(
nn
.
Module
):
...
...
tests/test_models/test_segmentors.py
deleted
100644 → 0
View file @
a34823dc
# Copyright (c) OpenMMLab. All rights reserved.
import
copy
from
os.path
import
dirname
,
exists
,
join
import
numpy
as
np
import
pytest
import
torch
from
mmdet3d.models.builder
import
build_segmentor
from
mmdet.apis
import
set_random_seed
def
_get_config_directory
():
"""Find the predefined detector config directory."""
try
:
# Assume we are running in the source mmdetection3d repo
repo_dpath
=
dirname
(
dirname
(
dirname
(
__file__
)))
except
NameError
:
# For IPython development when this __file__ is not defined
import
mmdet3d
repo_dpath
=
dirname
(
dirname
(
mmdet3d
.
__file__
))
config_dpath
=
join
(
repo_dpath
,
'configs'
)
if
not
exists
(
config_dpath
):
raise
Exception
(
'Cannot find config path'
)
return
config_dpath
def
_get_config_module
(
fname
):
"""Load a configuration as a python module."""
from
mmcv
import
Config
config_dpath
=
_get_config_directory
()
config_fpath
=
join
(
config_dpath
,
fname
)
config_mod
=
Config
.
fromfile
(
config_fpath
)
return
config_mod
def
_get_segmentor_cfg
(
fname
):
"""Grab configs necessary to create a segmentor.
These are deep copied to allow for safe modification of parameters without
influencing other tests.
"""
import
mmcv
config
=
_get_config_module
(
fname
)
model
=
copy
.
deepcopy
(
config
.
model
)
train_cfg
=
mmcv
.
Config
(
copy
.
deepcopy
(
config
.
model
.
train_cfg
))
test_cfg
=
mmcv
.
Config
(
copy
.
deepcopy
(
config
.
model
.
test_cfg
))
model
.
update
(
train_cfg
=
train_cfg
)
model
.
update
(
test_cfg
=
test_cfg
)
return
model
def
test_pointnet2_ssg
():
if
not
torch
.
cuda
.
is_available
():
pytest
.
skip
(
'test requires GPU and torch+cuda'
)
set_random_seed
(
0
,
True
)
pn2_ssg_cfg
=
_get_segmentor_cfg
(
'pointnet2/pointnet2_ssg_16x2_cosine_200e_scannet_seg-3d-20class.py'
)
pn2_ssg_cfg
.
test_cfg
.
num_points
=
32
self
=
build_segmentor
(
pn2_ssg_cfg
).
cuda
()
points
=
[
torch
.
rand
(
1024
,
6
).
float
().
cuda
()
for
_
in
range
(
2
)]
img_metas
=
[
dict
(),
dict
()]
gt_masks
=
[
torch
.
randint
(
0
,
20
,
(
1024
,
)).
long
().
cuda
()
for
_
in
range
(
2
)]
# test forward_train
losses
=
self
.
forward_train
(
points
,
img_metas
,
gt_masks
)
assert
losses
[
'decode.loss_sem_seg'
].
item
()
>=
0
# test forward function
set_random_seed
(
0
,
True
)
data_dict
=
dict
(
points
=
points
,
img_metas
=
img_metas
,
pts_semantic_mask
=
gt_masks
)
forward_losses
=
self
.
forward
(
return_loss
=
True
,
**
data_dict
)
assert
np
.
allclose
(
losses
[
'decode.loss_sem_seg'
].
item
(),
forward_losses
[
'decode.loss_sem_seg'
].
item
())
# test loss with ignore_index
ignore_masks
=
[
torch
.
ones_like
(
gt_masks
[
0
])
*
20
for
_
in
range
(
2
)]
losses
=
self
.
forward_train
(
points
,
img_metas
,
ignore_masks
)
assert
losses
[
'decode.loss_sem_seg'
].
item
()
==
0
# test simple_test
self
.
eval
()
with
torch
.
no_grad
():
scene_points
=
[
torch
.
randn
(
500
,
6
).
float
().
cuda
()
*
3.0
,
torch
.
randn
(
200
,
6
).
float
().
cuda
()
*
2.5
]
results
=
self
.
simple_test
(
scene_points
,
img_metas
)
assert
results
[
0
][
'semantic_mask'
].
shape
==
torch
.
Size
([
500
])
assert
results
[
1
][
'semantic_mask'
].
shape
==
torch
.
Size
([
200
])
# test forward function calling simple_test
with
torch
.
no_grad
():
data_dict
=
dict
(
points
=
[
scene_points
],
img_metas
=
[
img_metas
])
results
=
self
.
forward
(
return_loss
=
False
,
**
data_dict
)
assert
results
[
0
][
'semantic_mask'
].
shape
==
torch
.
Size
([
500
])
assert
results
[
1
][
'semantic_mask'
].
shape
==
torch
.
Size
([
200
])
# test aug_test
with
torch
.
no_grad
():
scene_points
=
[
torch
.
randn
(
2
,
500
,
6
).
float
().
cuda
()
*
3.0
,
torch
.
randn
(
2
,
200
,
6
).
float
().
cuda
()
*
2.5
]
img_metas
=
[[
dict
(),
dict
()],
[
dict
(),
dict
()]]
results
=
self
.
aug_test
(
scene_points
,
img_metas
)
assert
results
[
0
][
'semantic_mask'
].
shape
==
torch
.
Size
([
500
])
assert
results
[
1
][
'semantic_mask'
].
shape
==
torch
.
Size
([
200
])
# test forward function calling aug_test
with
torch
.
no_grad
():
data_dict
=
dict
(
points
=
scene_points
,
img_metas
=
img_metas
)
results
=
self
.
forward
(
return_loss
=
False
,
**
data_dict
)
assert
results
[
0
][
'semantic_mask'
].
shape
==
torch
.
Size
([
500
])
assert
results
[
1
][
'semantic_mask'
].
shape
==
torch
.
Size
([
200
])
def
test_pointnet2_msg
():
if
not
torch
.
cuda
.
is_available
():
pytest
.
skip
(
'test requires GPU and torch+cuda'
)
set_random_seed
(
0
,
True
)
pn2_msg_cfg
=
_get_segmentor_cfg
(
'pointnet2/pointnet2_msg_16x2_cosine_250e_scannet_seg-3d-20class.py'
)
pn2_msg_cfg
.
test_cfg
.
num_points
=
32
self
=
build_segmentor
(
pn2_msg_cfg
).
cuda
()
points
=
[
torch
.
rand
(
1024
,
6
).
float
().
cuda
()
for
_
in
range
(
2
)]
img_metas
=
[
dict
(),
dict
()]
gt_masks
=
[
torch
.
randint
(
0
,
20
,
(
1024
,
)).
long
().
cuda
()
for
_
in
range
(
2
)]
# test forward_train
losses
=
self
.
forward_train
(
points
,
img_metas
,
gt_masks
)
assert
losses
[
'decode.loss_sem_seg'
].
item
()
>=
0
# test loss with ignore_index
ignore_masks
=
[
torch
.
ones_like
(
gt_masks
[
0
])
*
20
for
_
in
range
(
2
)]
losses
=
self
.
forward_train
(
points
,
img_metas
,
ignore_masks
)
assert
losses
[
'decode.loss_sem_seg'
].
item
()
==
0
# test simple_test
self
.
eval
()
with
torch
.
no_grad
():
scene_points
=
[
torch
.
randn
(
500
,
6
).
float
().
cuda
()
*
3.0
,
torch
.
randn
(
200
,
6
).
float
().
cuda
()
*
2.5
]
results
=
self
.
simple_test
(
scene_points
,
img_metas
)
assert
results
[
0
][
'semantic_mask'
].
shape
==
torch
.
Size
([
500
])
assert
results
[
1
][
'semantic_mask'
].
shape
==
torch
.
Size
([
200
])
# test aug_test
with
torch
.
no_grad
():
scene_points
=
[
torch
.
randn
(
2
,
500
,
6
).
float
().
cuda
()
*
3.0
,
torch
.
randn
(
2
,
200
,
6
).
float
().
cuda
()
*
2.5
]
img_metas
=
[[
dict
(),
dict
()],
[
dict
(),
dict
()]]
results
=
self
.
aug_test
(
scene_points
,
img_metas
)
assert
results
[
0
][
'semantic_mask'
].
shape
==
torch
.
Size
([
500
])
assert
results
[
1
][
'semantic_mask'
].
shape
==
torch
.
Size
([
200
])
def
test_paconv_ssg
():
if
not
torch
.
cuda
.
is_available
():
pytest
.
skip
(
'test requires GPU and torch+cuda'
)
set_random_seed
(
0
,
True
)
paconv_ssg_cfg
=
_get_segmentor_cfg
(
'paconv/paconv_ssg_8x8_cosine_150e_s3dis_seg-3d-13class.py'
)
# for GPU memory consideration
paconv_ssg_cfg
.
backbone
.
num_points
=
(
256
,
64
,
16
,
4
)
paconv_ssg_cfg
.
test_cfg
.
num_points
=
32
self
=
build_segmentor
(
paconv_ssg_cfg
).
cuda
()
points
=
[
torch
.
rand
(
1024
,
9
).
float
().
cuda
()
for
_
in
range
(
2
)]
img_metas
=
[
dict
(),
dict
()]
gt_masks
=
[
torch
.
randint
(
0
,
13
,
(
1024
,
)).
long
().
cuda
()
for
_
in
range
(
2
)]
# test forward_train
losses
=
self
.
forward_train
(
points
,
img_metas
,
gt_masks
)
assert
losses
[
'decode.loss_sem_seg'
].
item
()
>=
0
assert
losses
[
'regularize.loss_regularize'
].
item
()
>=
0
# test forward function
set_random_seed
(
0
,
True
)
data_dict
=
dict
(
points
=
points
,
img_metas
=
img_metas
,
pts_semantic_mask
=
gt_masks
)
forward_losses
=
self
.
forward
(
return_loss
=
True
,
**
data_dict
)
assert
np
.
allclose
(
losses
[
'decode.loss_sem_seg'
].
item
(),
forward_losses
[
'decode.loss_sem_seg'
].
item
())
assert
np
.
allclose
(
losses
[
'regularize.loss_regularize'
].
item
(),
forward_losses
[
'regularize.loss_regularize'
].
item
())
# test loss with ignore_index
ignore_masks
=
[
torch
.
ones_like
(
gt_masks
[
0
])
*
13
for
_
in
range
(
2
)]
losses
=
self
.
forward_train
(
points
,
img_metas
,
ignore_masks
)
assert
losses
[
'decode.loss_sem_seg'
].
item
()
==
0
# test simple_test
self
.
eval
()
with
torch
.
no_grad
():
scene_points
=
[
torch
.
randn
(
200
,
6
).
float
().
cuda
()
*
3.0
,
torch
.
randn
(
100
,
6
).
float
().
cuda
()
*
2.5
]
results
=
self
.
simple_test
(
scene_points
,
img_metas
)
assert
results
[
0
][
'semantic_mask'
].
shape
==
torch
.
Size
([
200
])
assert
results
[
1
][
'semantic_mask'
].
shape
==
torch
.
Size
([
100
])
# test forward function calling simple_test
with
torch
.
no_grad
():
data_dict
=
dict
(
points
=
[
scene_points
],
img_metas
=
[
img_metas
])
results
=
self
.
forward
(
return_loss
=
False
,
**
data_dict
)
assert
results
[
0
][
'semantic_mask'
].
shape
==
torch
.
Size
([
200
])
assert
results
[
1
][
'semantic_mask'
].
shape
==
torch
.
Size
([
100
])
# test aug_test
with
torch
.
no_grad
():
scene_points
=
[
torch
.
randn
(
2
,
200
,
6
).
float
().
cuda
()
*
3.0
,
torch
.
randn
(
2
,
100
,
6
).
float
().
cuda
()
*
2.5
]
img_metas
=
[[
dict
(),
dict
()],
[
dict
(),
dict
()]]
results
=
self
.
aug_test
(
scene_points
,
img_metas
)
assert
results
[
0
][
'semantic_mask'
].
shape
==
torch
.
Size
([
200
])
assert
results
[
1
][
'semantic_mask'
].
shape
==
torch
.
Size
([
100
])
# test forward function calling aug_test
with
torch
.
no_grad
():
data_dict
=
dict
(
points
=
scene_points
,
img_metas
=
img_metas
)
results
=
self
.
forward
(
return_loss
=
False
,
**
data_dict
)
assert
results
[
0
][
'semantic_mask'
].
shape
==
torch
.
Size
([
200
])
assert
results
[
1
][
'semantic_mask'
].
shape
==
torch
.
Size
([
100
])
def
test_paconv_cuda_ssg
():
if
not
torch
.
cuda
.
is_available
():
pytest
.
skip
(
'test requires GPU and torch+cuda'
)
set_random_seed
(
0
,
True
)
paconv_cuda_ssg_cfg
=
_get_segmentor_cfg
(
'paconv/paconv_cuda_ssg_8x8_cosine_200e_s3dis_seg-3d-13class.py'
)
# for GPU memory consideration
paconv_cuda_ssg_cfg
.
backbone
.
num_points
=
(
256
,
64
,
16
,
4
)
paconv_cuda_ssg_cfg
.
test_cfg
.
num_points
=
32
self
=
build_segmentor
(
paconv_cuda_ssg_cfg
).
cuda
()
points
=
[
torch
.
rand
(
1024
,
9
).
float
().
cuda
()
for
_
in
range
(
2
)]
img_metas
=
[
dict
(),
dict
()]
gt_masks
=
[
torch
.
randint
(
0
,
13
,
(
1024
,
)).
long
().
cuda
()
for
_
in
range
(
2
)]
# test forward_train
losses
=
self
.
forward_train
(
points
,
img_metas
,
gt_masks
)
assert
losses
[
'decode.loss_sem_seg'
].
item
()
>=
0
assert
losses
[
'regularize.loss_regularize'
].
item
()
>=
0
# test forward function
set_random_seed
(
0
,
True
)
data_dict
=
dict
(
points
=
points
,
img_metas
=
img_metas
,
pts_semantic_mask
=
gt_masks
)
forward_losses
=
self
.
forward
(
return_loss
=
True
,
**
data_dict
)
assert
np
.
allclose
(
losses
[
'decode.loss_sem_seg'
].
item
(),
forward_losses
[
'decode.loss_sem_seg'
].
item
())
assert
np
.
allclose
(
losses
[
'regularize.loss_regularize'
].
item
(),
forward_losses
[
'regularize.loss_regularize'
].
item
())
# test loss with ignore_index
ignore_masks
=
[
torch
.
ones_like
(
gt_masks
[
0
])
*
13
for
_
in
range
(
2
)]
losses
=
self
.
forward_train
(
points
,
img_metas
,
ignore_masks
)
assert
losses
[
'decode.loss_sem_seg'
].
item
()
==
0
# test simple_test
self
.
eval
()
with
torch
.
no_grad
():
scene_points
=
[
torch
.
randn
(
200
,
6
).
float
().
cuda
()
*
3.0
,
torch
.
randn
(
100
,
6
).
float
().
cuda
()
*
2.5
]
results
=
self
.
simple_test
(
scene_points
,
img_metas
)
assert
results
[
0
][
'semantic_mask'
].
shape
==
torch
.
Size
([
200
])
assert
results
[
1
][
'semantic_mask'
].
shape
==
torch
.
Size
([
100
])
# test forward function calling simple_test
with
torch
.
no_grad
():
data_dict
=
dict
(
points
=
[
scene_points
],
img_metas
=
[
img_metas
])
results
=
self
.
forward
(
return_loss
=
False
,
**
data_dict
)
assert
results
[
0
][
'semantic_mask'
].
shape
==
torch
.
Size
([
200
])
assert
results
[
1
][
'semantic_mask'
].
shape
==
torch
.
Size
([
100
])
# test aug_test
with
torch
.
no_grad
():
scene_points
=
[
torch
.
randn
(
2
,
200
,
6
).
float
().
cuda
()
*
3.0
,
torch
.
randn
(
2
,
100
,
6
).
float
().
cuda
()
*
2.5
]
img_metas
=
[[
dict
(),
dict
()],
[
dict
(),
dict
()]]
results
=
self
.
aug_test
(
scene_points
,
img_metas
)
assert
results
[
0
][
'semantic_mask'
].
shape
==
torch
.
Size
([
200
])
assert
results
[
1
][
'semantic_mask'
].
shape
==
torch
.
Size
([
100
])
# test forward function calling aug_test
with
torch
.
no_grad
():
data_dict
=
dict
(
points
=
scene_points
,
img_metas
=
img_metas
)
results
=
self
.
forward
(
return_loss
=
False
,
**
data_dict
)
assert
results
[
0
][
'semantic_mask'
].
shape
==
torch
.
Size
([
200
])
assert
results
[
1
][
'semantic_mask'
].
shape
==
torch
.
Size
([
100
])
def
test_dgcnn
():
if
not
torch
.
cuda
.
is_available
():
pytest
.
skip
(
'test requires GPU and torch+cuda'
)
set_random_seed
(
0
,
True
)
dgcnn_cfg
=
_get_segmentor_cfg
(
'dgcnn/dgcnn_32x4_cosine_100e_s3dis_seg-3d-13class.py'
)
dgcnn_cfg
.
test_cfg
.
num_points
=
32
self
=
build_segmentor
(
dgcnn_cfg
).
cuda
()
points
=
[
torch
.
rand
(
4096
,
9
).
float
().
cuda
()
for
_
in
range
(
2
)]
img_metas
=
[
dict
(),
dict
()]
gt_masks
=
[
torch
.
randint
(
0
,
13
,
(
4096
,
)).
long
().
cuda
()
for
_
in
range
(
2
)]
# test forward_train
losses
=
self
.
forward_train
(
points
,
img_metas
,
gt_masks
)
assert
losses
[
'decode.loss_sem_seg'
].
item
()
>=
0
# test loss with ignore_index
ignore_masks
=
[
torch
.
ones_like
(
gt_masks
[
0
])
*
13
for
_
in
range
(
2
)]
losses
=
self
.
forward_train
(
points
,
img_metas
,
ignore_masks
)
assert
losses
[
'decode.loss_sem_seg'
].
item
()
==
0
# test simple_test
self
.
eval
()
with
torch
.
no_grad
():
scene_points
=
[
torch
.
randn
(
500
,
6
).
float
().
cuda
()
*
3.0
,
torch
.
randn
(
200
,
6
).
float
().
cuda
()
*
2.5
]
results
=
self
.
simple_test
(
scene_points
,
img_metas
)
assert
results
[
0
][
'semantic_mask'
].
shape
==
torch
.
Size
([
500
])
assert
results
[
1
][
'semantic_mask'
].
shape
==
torch
.
Size
([
200
])
# test aug_test
with
torch
.
no_grad
():
scene_points
=
[
torch
.
randn
(
2
,
500
,
6
).
float
().
cuda
()
*
3.0
,
torch
.
randn
(
2
,
200
,
6
).
float
().
cuda
()
*
2.5
]
img_metas
=
[[
dict
(),
dict
()],
[
dict
(),
dict
()]]
results
=
self
.
aug_test
(
scene_points
,
img_metas
)
assert
results
[
0
][
'semantic_mask'
].
shape
==
torch
.
Size
([
500
])
assert
results
[
1
][
'semantic_mask'
].
shape
==
torch
.
Size
([
200
])
tests/test_models/test_voxel_encoder/test_voxel_encoders.py
→
tests/test_models/test_voxel_encoder
s
/test_voxel_encoders.py
View file @
c9b69f5a
File moved
tests/test_models/test_voxel_encoder/test_voxel_generator.py
→
tests/test_models/test_voxel_encoder
s
/test_voxel_generator.py
View file @
c9b69f5a
File moved
tests/test_runtime/test_apis.py
deleted
100644 → 0
View file @
a34823dc
# Copyright (c) OpenMMLab. All rights reserved.
import
os
import
tempfile
from
os.path
import
dirname
,
exists
,
join
import
numpy
as
np
import
pytest
import
torch
from
mmcv.parallel
import
MMDataParallel
from
mmdet3d.apis
import
(
convert_SyncBN
,
inference_detector
,
inference_mono_3d_detector
,
inference_multi_modality_detector
,
inference_segmentor
,
init_model
,
show_result_meshlab
,
single_gpu_test
)
from
mmdet3d.core
import
Box3DMode
from
mmdet3d.core.bbox
import
(
CameraInstance3DBoxes
,
DepthInstance3DBoxes
,
LiDARInstance3DBoxes
)
from
mmdet3d.datasets
import
build_dataloader
,
build_dataset
from
mmdet3d.models
import
build_model
def
_get_config_directory
():
"""Find the predefined detector config directory."""
try
:
# Assume we are running in the source mmdetection3d repo
repo_dpath
=
dirname
(
dirname
(
dirname
(
__file__
)))
except
NameError
:
# For IPython development when this __file__ is not defined
import
mmdet3d
repo_dpath
=
dirname
(
dirname
(
mmdet3d
.
__file__
))
config_dpath
=
join
(
repo_dpath
,
'configs'
)
if
not
exists
(
config_dpath
):
raise
Exception
(
'Cannot find config path'
)
return
config_dpath
def
_get_config_module
(
fname
):
"""Load a configuration as a python module."""
from
mmcv
import
Config
config_dpath
=
_get_config_directory
()
config_fpath
=
join
(
config_dpath
,
fname
)
config_mod
=
Config
.
fromfile
(
config_fpath
)
return
config_mod
def
test_convert_SyncBN
():
cfg
=
_get_config_module
(
'pointpillars/hv_pointpillars_fpn_sbn-all_4x8_2x_nus-3d.py'
)
model_cfg
=
cfg
.
model
convert_SyncBN
(
model_cfg
)
assert
model_cfg
[
'pts_voxel_encoder'
][
'norm_cfg'
][
'type'
]
==
'BN1d'
assert
model_cfg
[
'pts_backbone'
][
'norm_cfg'
][
'type'
]
==
'BN2d'
assert
model_cfg
[
'pts_neck'
][
'norm_cfg'
][
'type'
]
==
'BN2d'
def
test_show_result_meshlab
():
pcd
=
'tests/data/nuscenes/samples/LIDAR_TOP/n015-2018-08-02-17-16-37+'
\
'0800__LIDAR_TOP__1533201470948018.pcd.bin'
box_3d
=
LiDARInstance3DBoxes
(
torch
.
tensor
(
[[
8.7314
,
-
1.8559
,
-
1.5997
,
0.4800
,
1.2000
,
1.8900
,
0.0100
]]))
labels_3d
=
torch
.
tensor
([
0
])
scores_3d
=
torch
.
tensor
([
0.5
])
points
=
np
.
random
.
rand
(
100
,
4
)
img_meta
=
dict
(
pts_filename
=
pcd
,
boxes_3d
=
box_3d
,
box_mode_3d
=
Box3DMode
.
LIDAR
)
data
=
dict
(
points
=
[[
torch
.
tensor
(
points
)]],
img_metas
=
[[
img_meta
]])
result
=
[
dict
(
pts_bbox
=
dict
(
boxes_3d
=
box_3d
,
labels_3d
=
labels_3d
,
scores_3d
=
scores_3d
))
]
tmp_dir
=
tempfile
.
TemporaryDirectory
()
temp_out_dir
=
tmp_dir
.
name
out_dir
,
file_name
=
show_result_meshlab
(
data
,
result
,
temp_out_dir
)
expected_outfile_pred
=
file_name
+
'_pred.obj'
expected_outfile_pts
=
file_name
+
'_points.obj'
expected_outfile_pred_path
=
os
.
path
.
join
(
out_dir
,
file_name
,
expected_outfile_pred
)
expected_outfile_pts_path
=
os
.
path
.
join
(
out_dir
,
file_name
,
expected_outfile_pts
)
assert
os
.
path
.
exists
(
expected_outfile_pred_path
)
assert
os
.
path
.
exists
(
expected_outfile_pts_path
)
tmp_dir
.
cleanup
()
# test multi-modality show
# indoor scene
pcd
=
'tests/data/sunrgbd/points/000001.bin'
filename
=
'tests/data/sunrgbd/sunrgbd_trainval/image/000001.jpg'
box_3d
=
DepthInstance3DBoxes
(
torch
.
tensor
(
[[
-
1.1580
,
3.3041
,
-
0.9961
,
0.3829
,
0.4647
,
0.5574
,
1.1213
]]))
img
=
np
.
random
.
randn
(
1
,
3
,
608
,
832
)
k_mat
=
np
.
array
([[
529.5000
,
0.0000
,
365.0000
],
[
0.0000
,
529.5000
,
265.0000
],
[
0.0000
,
0.0000
,
1.0000
]])
rt_mat
=
np
.
array
([[
0.9980
,
0.0058
,
-
0.0634
],
[
0.0058
,
0.9835
,
0.1808
],
[
0.0634
,
-
0.1808
,
0.9815
]])
rt_mat
=
np
.
array
([[
1
,
0
,
0
],
[
0
,
0
,
-
1
],
[
0
,
1
,
0
]])
@
rt_mat
.
transpose
(
1
,
0
)
depth2img
=
k_mat
@
rt_mat
img_meta
=
dict
(
filename
=
filename
,
depth2img
=
depth2img
,
pcd_horizontal_flip
=
False
,
pcd_vertical_flip
=
False
,
box_mode_3d
=
Box3DMode
.
DEPTH
,
box_type_3d
=
DepthInstance3DBoxes
,
pcd_trans
=
np
.
array
([
0.
,
0.
,
0.
]),
pcd_scale_factor
=
1.0
,
pts_filename
=
pcd
,
transformation_3d_flow
=
[
'R'
,
'S'
,
'T'
])
data
=
dict
(
points
=
[[
torch
.
tensor
(
points
)]],
img_metas
=
[[
img_meta
]],
img
=
[
img
])
result
=
[
dict
(
boxes_3d
=
box_3d
,
labels_3d
=
labels_3d
,
scores_3d
=
scores_3d
)]
tmp_dir
=
tempfile
.
TemporaryDirectory
()
temp_out_dir
=
tmp_dir
.
name
out_dir
,
file_name
=
show_result_meshlab
(
data
,
result
,
temp_out_dir
,
0.3
,
task
=
'multi_modality-det'
)
expected_outfile_pred
=
file_name
+
'_pred.obj'
expected_outfile_pts
=
file_name
+
'_points.obj'
expected_outfile_png
=
file_name
+
'_img.png'
expected_outfile_proj
=
file_name
+
'_pred.png'
expected_outfile_pred_path
=
os
.
path
.
join
(
out_dir
,
file_name
,
expected_outfile_pred
)
expected_outfile_pts_path
=
os
.
path
.
join
(
out_dir
,
file_name
,
expected_outfile_pts
)
expected_outfile_png_path
=
os
.
path
.
join
(
out_dir
,
file_name
,
expected_outfile_png
)
expected_outfile_proj_path
=
os
.
path
.
join
(
out_dir
,
file_name
,
expected_outfile_proj
)
assert
os
.
path
.
exists
(
expected_outfile_pred_path
)
assert
os
.
path
.
exists
(
expected_outfile_pts_path
)
assert
os
.
path
.
exists
(
expected_outfile_png_path
)
assert
os
.
path
.
exists
(
expected_outfile_proj_path
)
tmp_dir
.
cleanup
()
# outdoor scene
pcd
=
'tests/data/kitti/training/velodyne_reduced/000000.bin'
filename
=
'tests/data/kitti/training/image_2/000000.png'
box_3d
=
LiDARInstance3DBoxes
(
torch
.
tensor
(
[[
6.4495
,
-
3.9097
,
-
1.7409
,
1.5063
,
3.1819
,
1.4716
,
1.8782
]]))
img
=
np
.
random
.
randn
(
1
,
3
,
384
,
1280
)
lidar2img
=
np
.
array
(
[[
6.09695435e+02
,
-
7.21421631e+02
,
-
1.25125790e+00
,
-
1.23041824e+02
],
[
1.80384201e+02
,
7.64479828e+00
,
-
7.19651550e+02
,
-
1.01016693e+02
],
[
9.99945343e-01
,
1.24365499e-04
,
1.04513029e-02
,
-
2.69386917e-01
],
[
0.00000000e+00
,
0.00000000e+00
,
0.00000000e+00
,
1.00000000e+00
]])
img_meta
=
dict
(
filename
=
filename
,
pcd_horizontal_flip
=
False
,
pcd_vertical_flip
=
False
,
box_mode_3d
=
Box3DMode
.
LIDAR
,
box_type_3d
=
LiDARInstance3DBoxes
,
pcd_trans
=
np
.
array
([
0.
,
0.
,
0.
]),
pcd_scale_factor
=
1.0
,
pts_filename
=
pcd
,
lidar2img
=
lidar2img
)
data
=
dict
(
points
=
[[
torch
.
tensor
(
points
)]],
img_metas
=
[[
img_meta
]],
img
=
[
img
])
result
=
[
dict
(
pts_bbox
=
dict
(
boxes_3d
=
box_3d
,
labels_3d
=
labels_3d
,
scores_3d
=
scores_3d
))
]
out_dir
,
file_name
=
show_result_meshlab
(
data
,
result
,
temp_out_dir
,
0.1
,
task
=
'multi_modality-det'
)
tmp_dir
=
tempfile
.
TemporaryDirectory
()
temp_out_dir
=
tmp_dir
.
name
expected_outfile_pred
=
file_name
+
'_pred.obj'
expected_outfile_pts
=
file_name
+
'_points.obj'
expected_outfile_png
=
file_name
+
'_img.png'
expected_outfile_proj
=
file_name
+
'_pred.png'
expected_outfile_pred_path
=
os
.
path
.
join
(
out_dir
,
file_name
,
expected_outfile_pred
)
expected_outfile_pts_path
=
os
.
path
.
join
(
out_dir
,
file_name
,
expected_outfile_pts
)
expected_outfile_png_path
=
os
.
path
.
join
(
out_dir
,
file_name
,
expected_outfile_png
)
expected_outfile_proj_path
=
os
.
path
.
join
(
out_dir
,
file_name
,
expected_outfile_proj
)
assert
os
.
path
.
exists
(
expected_outfile_pred_path
)
assert
os
.
path
.
exists
(
expected_outfile_pts_path
)
assert
os
.
path
.
exists
(
expected_outfile_png_path
)
assert
os
.
path
.
exists
(
expected_outfile_proj_path
)
tmp_dir
.
cleanup
()
# test mono-3d show
filename
=
'tests/data/nuscenes/samples/CAM_BACK_LEFT/n015-2018-'
\
'07-18-11-07-57+0800__CAM_BACK_LEFT__1531883530447423.jpg'
box_3d
=
CameraInstance3DBoxes
(
torch
.
tensor
(
[[
6.4495
,
-
3.9097
,
-
1.7409
,
1.5063
,
3.1819
,
1.4716
,
1.8782
]]))
img
=
np
.
random
.
randn
(
1
,
3
,
384
,
1280
)
cam2img
=
np
.
array
([[
100.0
,
0.0
,
50.0
],
[
0.0
,
100.0
,
50.0
],
[
0.0
,
0.0
,
1.0
]])
img_meta
=
dict
(
filename
=
filename
,
pcd_horizontal_flip
=
False
,
pcd_vertical_flip
=
False
,
box_mode_3d
=
Box3DMode
.
CAM
,
box_type_3d
=
CameraInstance3DBoxes
,
pcd_trans
=
np
.
array
([
0.
,
0.
,
0.
]),
pcd_scale_factor
=
1.0
,
cam2img
=
cam2img
)
data
=
dict
(
points
=
[[
torch
.
tensor
(
points
)]],
img_metas
=
[[
img_meta
]],
img
=
[
img
])
result
=
[
dict
(
img_bbox
=
dict
(
boxes_3d
=
box_3d
,
labels_3d
=
labels_3d
,
scores_3d
=
scores_3d
))
]
out_dir
,
file_name
=
show_result_meshlab
(
data
,
result
,
temp_out_dir
,
0.1
,
task
=
'mono-det'
)
tmp_dir
=
tempfile
.
TemporaryDirectory
()
temp_out_dir
=
tmp_dir
.
name
expected_outfile_png
=
file_name
+
'_img.png'
expected_outfile_proj
=
file_name
+
'_pred.png'
expected_outfile_png_path
=
os
.
path
.
join
(
out_dir
,
file_name
,
expected_outfile_png
)
expected_outfile_proj_path
=
os
.
path
.
join
(
out_dir
,
file_name
,
expected_outfile_proj
)
assert
os
.
path
.
exists
(
expected_outfile_png_path
)
assert
os
.
path
.
exists
(
expected_outfile_proj_path
)
tmp_dir
.
cleanup
()
# test seg show
pcd
=
'tests/data/scannet/points/scene0000_00.bin'
points
=
np
.
random
.
rand
(
100
,
6
)
img_meta
=
dict
(
pts_filename
=
pcd
)
data
=
dict
(
points
=
[[
torch
.
tensor
(
points
)]],
img_metas
=
[[
img_meta
]])
pred_seg
=
torch
.
randint
(
0
,
20
,
(
100
,
))
result
=
[
dict
(
semantic_mask
=
pred_seg
)]
tmp_dir
=
tempfile
.
TemporaryDirectory
()
temp_out_dir
=
tmp_dir
.
name
out_dir
,
file_name
=
show_result_meshlab
(
data
,
result
,
temp_out_dir
,
task
=
'seg'
)
expected_outfile_pred
=
file_name
+
'_pred.obj'
expected_outfile_pts
=
file_name
+
'_points.obj'
expected_outfile_pred_path
=
os
.
path
.
join
(
out_dir
,
file_name
,
expected_outfile_pred
)
expected_outfile_pts_path
=
os
.
path
.
join
(
out_dir
,
file_name
,
expected_outfile_pts
)
assert
os
.
path
.
exists
(
expected_outfile_pred_path
)
assert
os
.
path
.
exists
(
expected_outfile_pts_path
)
tmp_dir
.
cleanup
()
def
test_inference_detector
():
if
not
torch
.
cuda
.
is_available
():
pytest
.
skip
(
'test requires GPU and torch+cuda'
)
pcd
=
'tests/data/kitti/training/velodyne_reduced/000000.bin'
detector_cfg
=
'configs/pointpillars/hv_pointpillars_secfpn_'
\
'6x8_160e_kitti-3d-3class.py'
detector
=
init_model
(
detector_cfg
,
device
=
'cuda:0'
)
results
=
inference_detector
(
detector
,
pcd
)
bboxes_3d
=
results
[
0
][
0
][
'boxes_3d'
]
scores_3d
=
results
[
0
][
0
][
'scores_3d'
]
labels_3d
=
results
[
0
][
0
][
'labels_3d'
]
assert
bboxes_3d
.
tensor
.
shape
[
0
]
>=
0
assert
bboxes_3d
.
tensor
.
shape
[
1
]
==
7
assert
scores_3d
.
shape
[
0
]
>=
0
assert
labels_3d
.
shape
[
0
]
>=
0
def
test_inference_multi_modality_detector
():
# these two multi-modality models both only have GPU implementations
if
not
torch
.
cuda
.
is_available
():
pytest
.
skip
(
'test requires GPU and torch+cuda'
)
# indoor scene
pcd
=
'tests/data/sunrgbd/points/000001.bin'
img
=
'tests/data/sunrgbd/sunrgbd_trainval/image/000001.jpg'
ann_file
=
'tests/data/sunrgbd/sunrgbd_infos.pkl'
detector_cfg
=
'configs/imvotenet/imvotenet_stage2_'
\
'16x8_sunrgbd-3d-10class.py'
detector
=
init_model
(
detector_cfg
,
device
=
'cuda:0'
)
results
=
inference_multi_modality_detector
(
detector
,
pcd
,
img
,
ann_file
)
bboxes_3d
=
results
[
0
][
0
][
'boxes_3d'
]
scores_3d
=
results
[
0
][
0
][
'scores_3d'
]
labels_3d
=
results
[
0
][
0
][
'labels_3d'
]
assert
bboxes_3d
.
tensor
.
shape
[
0
]
>=
0
assert
bboxes_3d
.
tensor
.
shape
[
1
]
==
7
assert
scores_3d
.
shape
[
0
]
>=
0
assert
labels_3d
.
shape
[
0
]
>=
0
# outdoor scene
pcd
=
'tests/data/kitti/training/velodyne_reduced/000000.bin'
img
=
'tests/data/kitti/training/image_2/000000.png'
ann_file
=
'tests/data/kitti/kitti_infos_train.pkl'
detector_cfg
=
'configs/mvxnet/dv_mvx-fpn_second_secfpn_adamw_'
\
'2x8_80e_kitti-3d-3class.py'
detector
=
init_model
(
detector_cfg
,
device
=
'cuda:0'
)
results
=
inference_multi_modality_detector
(
detector
,
pcd
,
img
,
ann_file
)
bboxes_3d
=
results
[
0
][
0
][
'pts_bbox'
][
'boxes_3d'
]
scores_3d
=
results
[
0
][
0
][
'pts_bbox'
][
'scores_3d'
]
labels_3d
=
results
[
0
][
0
][
'pts_bbox'
][
'labels_3d'
]
assert
bboxes_3d
.
tensor
.
shape
[
0
]
>=
0
assert
bboxes_3d
.
tensor
.
shape
[
1
]
==
7
assert
scores_3d
.
shape
[
0
]
>=
0
assert
labels_3d
.
shape
[
0
]
>=
0
def
test_inference_mono_3d_detector
():
# FCOS3D only has GPU implementations
if
not
torch
.
cuda
.
is_available
():
pytest
.
skip
(
'test requires GPU and torch+cuda'
)
img
=
'tests/data/nuscenes/samples/CAM_BACK_LEFT/'
\
'n015-2018-07-18-11-07-57+0800__CAM_BACK_LEFT__1531883530447423.jpg'
ann_file
=
'tests/data/nuscenes/nus_infos_mono3d.coco.json'
detector_cfg
=
'configs/fcos3d/fcos3d_r101_caffe_fpn_gn-head_dcn_'
\
'2x8_1x_nus-mono3d.py'
detector
=
init_model
(
detector_cfg
,
device
=
'cuda:0'
)
results
=
inference_mono_3d_detector
(
detector
,
img
,
ann_file
)
bboxes_3d
=
results
[
0
][
0
][
'img_bbox'
][
'boxes_3d'
]
scores_3d
=
results
[
0
][
0
][
'img_bbox'
][
'scores_3d'
]
labels_3d
=
results
[
0
][
0
][
'img_bbox'
][
'labels_3d'
]
assert
bboxes_3d
.
tensor
.
shape
[
0
]
>=
0
assert
bboxes_3d
.
tensor
.
shape
[
1
]
==
9
assert
scores_3d
.
shape
[
0
]
>=
0
assert
labels_3d
.
shape
[
0
]
>=
0
def
test_inference_segmentor
():
# PN2 only has GPU implementations
if
not
torch
.
cuda
.
is_available
():
pytest
.
skip
(
'test requires GPU and torch+cuda'
)
pcd
=
'tests/data/scannet/points/scene0000_00.bin'
segmentor_cfg
=
'configs/pointnet2/pointnet2_ssg_'
\
'16x2_cosine_200e_scannet_seg-3d-20class.py'
segmentor
=
init_model
(
segmentor_cfg
,
device
=
'cuda:0'
)
results
=
inference_segmentor
(
segmentor
,
pcd
)
seg_3d
=
results
[
0
][
0
][
'semantic_mask'
]
assert
seg_3d
.
shape
==
torch
.
Size
([
100
])
assert
seg_3d
.
min
()
>=
0
assert
seg_3d
.
max
()
<=
19
def
test_single_gpu_test
():
if
not
torch
.
cuda
.
is_available
():
pytest
.
skip
(
'test requires GPU and torch+cuda'
)
cfg
=
_get_config_module
(
'votenet/votenet_16x8_sunrgbd-3d-10class.py'
)
cfg
.
model
.
train_cfg
=
None
model
=
build_model
(
cfg
.
model
,
test_cfg
=
cfg
.
get
(
'test_cfg'
))
dataset_cfg
=
cfg
.
data
.
test
dataset_cfg
.
data_root
=
'./tests/data/sunrgbd'
dataset_cfg
.
ann_file
=
'tests/data/sunrgbd/sunrgbd_infos.pkl'
dataset
=
build_dataset
(
dataset_cfg
)
data_loader
=
build_dataloader
(
dataset
,
samples_per_gpu
=
1
,
workers_per_gpu
=
cfg
.
data
.
workers_per_gpu
,
dist
=
False
,
shuffle
=
False
)
model
=
MMDataParallel
(
model
,
device_ids
=
[
0
])
results
=
single_gpu_test
(
model
,
data_loader
)
bboxes_3d
=
results
[
0
][
'boxes_3d'
]
scores_3d
=
results
[
0
][
'scores_3d'
]
labels_3d
=
results
[
0
][
'labels_3d'
]
assert
bboxes_3d
.
tensor
.
shape
[
0
]
>=
0
assert
bboxes_3d
.
tensor
.
shape
[
1
]
==
7
assert
scores_3d
.
shape
[
0
]
>=
0
assert
labels_3d
.
shape
[
0
]
>=
0
tests/test_runtime/test_config.py
deleted
100644 → 0
View file @
a34823dc
# Copyright (c) OpenMMLab. All rights reserved.
from
os.path
import
dirname
,
exists
,
join
,
relpath
def
_get_config_directory
():
"""Find the predefined detector config directory."""
try
:
# Assume we are running in the source mmdetection3d repo
repo_dpath
=
dirname
(
dirname
(
dirname
(
__file__
)))
except
NameError
:
# For IPython development when this __file__ is not defined
import
mmdet3d
repo_dpath
=
dirname
(
dirname
(
mmdet3d
.
__file__
))
config_dpath
=
join
(
repo_dpath
,
'configs'
)
if
not
exists
(
config_dpath
):
raise
Exception
(
'Cannot find config path'
)
return
config_dpath
def
test_config_build_model
():
"""Test that all detection models defined in the configs can be
initialized."""
from
mmcv
import
Config
from
mmdet3d.models
import
build_model
config_dpath
=
_get_config_directory
()
print
(
'Found config_dpath = {!r}'
.
format
(
config_dpath
))
import
glob
config_fpaths
=
list
(
glob
.
glob
(
join
(
config_dpath
,
'**'
,
'*.py'
)))
config_fpaths
=
[
p
for
p
in
config_fpaths
if
p
.
find
(
'_base_'
)
==
-
1
]
config_names
=
[
relpath
(
p
,
config_dpath
)
for
p
in
config_fpaths
]
print
(
'Using {} config files'
.
format
(
len
(
config_names
)))
for
config_fname
in
config_names
:
config_fpath
=
join
(
config_dpath
,
config_fname
)
config_mod
=
Config
.
fromfile
(
config_fpath
)
config_mod
.
model
config_mod
.
model
.
train_cfg
config_mod
.
model
.
test_cfg
print
(
'Building detector, config_fpath = {!r}'
.
format
(
config_fpath
))
# Remove pretrained keys to allow for testing in an offline environment
if
'pretrained'
in
config_mod
.
model
:
config_mod
.
model
[
'pretrained'
]
=
None
detector
=
build_model
(
config_mod
.
model
)
assert
detector
is
not
None
if
'roi_head'
in
config_mod
.
model
.
keys
():
# for two stage detector
# detectors must have bbox head
assert
detector
.
roi_head
.
with_bbox
and
detector
.
with_bbox
assert
detector
.
roi_head
.
with_mask
==
detector
.
with_mask
head_config
=
config_mod
.
model
[
'roi_head'
]
if
head_config
.
type
==
'PartAggregationROIHead'
:
check_parta2_roi_head
(
head_config
,
detector
.
roi_head
)
elif
head_config
.
type
==
'H3DRoIHead'
:
check_h3d_roi_head
(
head_config
,
detector
.
roi_head
)
elif
head_config
.
type
==
'PointRCNNRoIHead'
:
check_pointrcnn_roi_head
(
head_config
,
detector
.
roi_head
)
else
:
_check_roi_head
(
head_config
,
detector
.
roi_head
)
# else:
# # for single stage detector
# # detectors must have bbox head
# # assert detector.with_bbox
# head_config = config_mod.model['bbox_head']
# _check_bbox_head(head_config, detector.bbox_head)
def
test_config_build_pipeline
():
"""Test that all detection models defined in the configs can be
initialized."""
from
mmcv
import
Config
from
mmdet3d.datasets.pipelines
import
Compose
config_dpath
=
_get_config_directory
()
print
(
'Found config_dpath = {!r}'
.
format
(
config_dpath
))
# Other configs needs database sampler.
config_names
=
[
'pointpillars/hv_pointpillars_secfpn_sbn-all_4x8_2x_nus-3d.py'
,
]
print
(
'Using {} config files'
.
format
(
len
(
config_names
)))
for
config_fname
in
config_names
:
config_fpath
=
join
(
config_dpath
,
config_fname
)
config_mod
=
Config
.
fromfile
(
config_fpath
)
# build train_pipeline
train_pipeline
=
Compose
(
config_mod
.
train_pipeline
)
test_pipeline
=
Compose
(
config_mod
.
test_pipeline
)
assert
train_pipeline
is
not
None
assert
test_pipeline
is
not
None
def
_check_roi_head
(
config
,
head
):
# check consistency between head_config and roi_head
assert
config
[
'type'
]
==
head
.
__class__
.
__name__
# check roi_align
bbox_roi_cfg
=
config
.
bbox_roi_extractor
bbox_roi_extractor
=
head
.
bbox_roi_extractor
_check_roi_extractor
(
bbox_roi_cfg
,
bbox_roi_extractor
)
# check bbox head infos
bbox_cfg
=
config
.
bbox_head
bbox_head
=
head
.
bbox_head
_check_bbox_head
(
bbox_cfg
,
bbox_head
)
if
head
.
with_mask
:
# check roi_align
if
config
.
mask_roi_extractor
:
mask_roi_cfg
=
config
.
mask_roi_extractor
mask_roi_extractor
=
head
.
mask_roi_extractor
_check_roi_extractor
(
mask_roi_cfg
,
mask_roi_extractor
,
bbox_roi_extractor
)
# check mask head infos
mask_head
=
head
.
mask_head
mask_cfg
=
config
.
mask_head
_check_mask_head
(
mask_cfg
,
mask_head
)
def
_check_roi_extractor
(
config
,
roi_extractor
,
prev_roi_extractor
=
None
):
from
torch
import
nn
as
nn
if
isinstance
(
roi_extractor
,
nn
.
ModuleList
):
if
prev_roi_extractor
:
prev_roi_extractor
=
prev_roi_extractor
[
0
]
roi_extractor
=
roi_extractor
[
0
]
assert
(
len
(
config
.
featmap_strides
)
==
len
(
roi_extractor
.
roi_layers
))
assert
(
config
.
out_channels
==
roi_extractor
.
out_channels
)
from
torch.nn.modules.utils
import
_pair
assert
(
_pair
(
config
.
roi_layer
.
output_size
)
==
roi_extractor
.
roi_layers
[
0
].
output_size
)
if
'use_torchvision'
in
config
.
roi_layer
:
assert
(
config
.
roi_layer
.
use_torchvision
==
roi_extractor
.
roi_layers
[
0
].
use_torchvision
)
elif
'aligned'
in
config
.
roi_layer
:
assert
(
config
.
roi_layer
.
aligned
==
roi_extractor
.
roi_layers
[
0
].
aligned
)
if
prev_roi_extractor
:
assert
(
roi_extractor
.
roi_layers
[
0
].
aligned
==
prev_roi_extractor
.
roi_layers
[
0
].
aligned
)
assert
(
roi_extractor
.
roi_layers
[
0
].
use_torchvision
==
prev_roi_extractor
.
roi_layers
[
0
].
use_torchvision
)
def
_check_mask_head
(
mask_cfg
,
mask_head
):
from
torch
import
nn
as
nn
if
isinstance
(
mask_cfg
,
list
):
for
single_mask_cfg
,
single_mask_head
in
zip
(
mask_cfg
,
mask_head
):
_check_mask_head
(
single_mask_cfg
,
single_mask_head
)
elif
isinstance
(
mask_head
,
nn
.
ModuleList
):
for
single_mask_head
in
mask_head
:
_check_mask_head
(
mask_cfg
,
single_mask_head
)
else
:
assert
mask_cfg
[
'type'
]
==
mask_head
.
__class__
.
__name__
assert
mask_cfg
.
in_channels
==
mask_head
.
in_channels
assert
(
mask_cfg
.
conv_out_channels
==
mask_head
.
conv_logits
.
in_channels
)
class_agnostic
=
mask_cfg
.
get
(
'class_agnostic'
,
False
)
out_dim
=
(
1
if
class_agnostic
else
mask_cfg
.
num_classes
)
assert
mask_head
.
conv_logits
.
out_channels
==
out_dim
def
_check_bbox_head
(
bbox_cfg
,
bbox_head
):
from
torch
import
nn
as
nn
if
isinstance
(
bbox_cfg
,
list
):
for
single_bbox_cfg
,
single_bbox_head
in
zip
(
bbox_cfg
,
bbox_head
):
_check_bbox_head
(
single_bbox_cfg
,
single_bbox_head
)
elif
isinstance
(
bbox_head
,
nn
.
ModuleList
):
for
single_bbox_head
in
bbox_head
:
_check_bbox_head
(
bbox_cfg
,
single_bbox_head
)
else
:
assert
bbox_cfg
[
'type'
]
==
bbox_head
.
__class__
.
__name__
assert
bbox_cfg
.
in_channels
==
bbox_head
.
in_channels
with_cls
=
bbox_cfg
.
get
(
'with_cls'
,
True
)
if
with_cls
:
fc_out_channels
=
bbox_cfg
.
get
(
'fc_out_channels'
,
2048
)
assert
(
fc_out_channels
==
bbox_head
.
fc_cls
.
in_features
)
assert
bbox_cfg
.
num_classes
+
1
==
bbox_head
.
fc_cls
.
out_features
with_reg
=
bbox_cfg
.
get
(
'with_reg'
,
True
)
if
with_reg
:
out_dim
=
(
4
if
bbox_cfg
.
reg_class_agnostic
else
4
*
bbox_cfg
.
num_classes
)
assert
bbox_head
.
fc_reg
.
out_features
==
out_dim
def
check_parta2_roi_head
(
config
,
head
):
assert
config
[
'type'
]
==
head
.
__class__
.
__name__
# check seg_roi_extractor
seg_roi_cfg
=
config
.
seg_roi_extractor
seg_roi_extractor
=
head
.
seg_roi_extractor
_check_parta2_roi_extractor
(
seg_roi_cfg
,
seg_roi_extractor
)
# check part_roi_extractor
part_roi_cfg
=
config
.
part_roi_extractor
part_roi_extractor
=
head
.
part_roi_extractor
_check_parta2_roi_extractor
(
part_roi_cfg
,
part_roi_extractor
)
# check bbox head infos
bbox_cfg
=
config
.
bbox_head
bbox_head
=
head
.
bbox_head
_check_parta2_bbox_head
(
bbox_cfg
,
bbox_head
)
def
_check_parta2_roi_extractor
(
config
,
roi_extractor
):
assert
config
[
'type'
]
==
roi_extractor
.
__class__
.
__name__
assert
(
config
.
roi_layer
.
out_size
==
roi_extractor
.
roi_layer
.
out_size
)
assert
(
config
.
roi_layer
.
max_pts_per_voxel
==
roi_extractor
.
roi_layer
.
max_pts_per_voxel
)
def
_check_parta2_bbox_head
(
bbox_cfg
,
bbox_head
):
from
torch
import
nn
as
nn
if
isinstance
(
bbox_cfg
,
list
):
for
single_bbox_cfg
,
single_bbox_head
in
zip
(
bbox_cfg
,
bbox_head
):
_check_bbox_head
(
single_bbox_cfg
,
single_bbox_head
)
elif
isinstance
(
bbox_head
,
nn
.
ModuleList
):
for
single_bbox_head
in
bbox_head
:
_check_bbox_head
(
bbox_cfg
,
single_bbox_head
)
else
:
assert
bbox_cfg
[
'type'
]
==
bbox_head
.
__class__
.
__name__
assert
bbox_cfg
.
seg_in_channels
==
bbox_head
.
seg_conv
[
0
][
0
].
in_channels
assert
bbox_cfg
.
part_in_channels
==
bbox_head
.
part_conv
[
0
][
0
].
in_channels
def
check_h3d_roi_head
(
config
,
head
):
assert
config
[
'type'
]
==
head
.
__class__
.
__name__
# check seg_roi_extractor
primitive_z_cfg
=
config
.
primitive_list
[
0
]
primitive_z_extractor
=
head
.
primitive_z
_check_primitive_extractor
(
primitive_z_cfg
,
primitive_z_extractor
)
primitive_xy_cfg
=
config
.
primitive_list
[
1
]
primitive_xy_extractor
=
head
.
primitive_xy
_check_primitive_extractor
(
primitive_xy_cfg
,
primitive_xy_extractor
)
primitive_line_cfg
=
config
.
primitive_list
[
2
]
primitive_line_extractor
=
head
.
primitive_line
_check_primitive_extractor
(
primitive_line_cfg
,
primitive_line_extractor
)
# check bbox head infos
bbox_cfg
=
config
.
bbox_head
bbox_head
=
head
.
bbox_head
_check_h3d_bbox_head
(
bbox_cfg
,
bbox_head
)
def
_check_primitive_extractor
(
config
,
primitive_extractor
):
assert
config
[
'type'
]
==
primitive_extractor
.
__class__
.
__name__
assert
(
config
.
num_dims
==
primitive_extractor
.
num_dims
)
assert
(
config
.
num_classes
==
primitive_extractor
.
num_classes
)
def
_check_h3d_bbox_head
(
bbox_cfg
,
bbox_head
):
assert
bbox_cfg
[
'type'
]
==
bbox_head
.
__class__
.
__name__
assert
bbox_cfg
.
num_proposal
*
\
6
==
bbox_head
.
surface_center_matcher
.
num_point
[
0
]
assert
bbox_cfg
.
num_proposal
*
\
12
==
bbox_head
.
line_center_matcher
.
num_point
[
0
]
assert
bbox_cfg
.
suface_matching_cfg
.
mlp_channels
[
-
1
]
*
\
18
==
bbox_head
.
bbox_pred
[
0
].
in_channels
def
check_pointrcnn_roi_head
(
config
,
head
):
assert
config
[
'type'
]
==
head
.
__class__
.
__name__
# check point_roi_extractor
point_roi_cfg
=
config
.
point_roi_extractor
point_roi_extractor
=
head
.
point_roi_extractor
_check_pointrcnn_roi_extractor
(
point_roi_cfg
,
point_roi_extractor
)
# check pointrcnn rcnn bboxhead
bbox_cfg
=
config
.
bbox_head
bbox_head
=
head
.
bbox_head
_check_pointrcnn_bbox_head
(
bbox_cfg
,
bbox_head
)
def
_check_pointrcnn_roi_extractor
(
config
,
roi_extractor
):
assert
config
[
'type'
]
==
roi_extractor
.
__class__
.
__name__
assert
config
.
roi_layer
.
num_sampled_points
==
\
roi_extractor
.
roi_layer
.
num_sampled_points
def
_check_pointrcnn_bbox_head
(
bbox_cfg
,
bbox_head
):
assert
bbox_cfg
[
'type'
]
==
bbox_head
.
__class__
.
__name__
assert
bbox_cfg
.
num_classes
==
bbox_head
.
num_classes
assert
bbox_cfg
.
with_corner_loss
==
bbox_head
.
with_corner_loss
tests/test_utils/test_assigners.py
deleted
100644 → 0
View file @
a34823dc
# Copyright (c) OpenMMLab. All rights reserved.
"""Tests the Assigner objects.
CommandLine:
pytest tests/test_utils/test_assigner.py
xdoctest tests/test_utils/test_assigner.py zero
"""
import
torch
from
mmdet3d.core.bbox.assigners
import
MaxIoUAssigner
def
test_max_iou_assigner
():
self
=
MaxIoUAssigner
(
pos_iou_thr
=
0.5
,
neg_iou_thr
=
0.5
,
)
bboxes
=
torch
.
FloatTensor
([
[
0
,
0
,
10
,
10
],
[
10
,
10
,
20
,
20
],
[
5
,
5
,
15
,
15
],
[
32
,
32
,
38
,
42
],
])
gt_bboxes
=
torch
.
FloatTensor
([
[
0
,
0
,
10
,
9
],
[
0
,
10
,
10
,
19
],
])
gt_labels
=
torch
.
LongTensor
([
2
,
3
])
assign_result
=
self
.
assign
(
bboxes
,
gt_bboxes
,
gt_labels
=
gt_labels
)
assert
len
(
assign_result
.
gt_inds
)
==
4
assert
len
(
assign_result
.
labels
)
==
4
expected_gt_inds
=
torch
.
LongTensor
([
1
,
0
,
2
,
0
])
assert
torch
.
all
(
assign_result
.
gt_inds
==
expected_gt_inds
)
def
test_max_iou_assigner_with_ignore
():
self
=
MaxIoUAssigner
(
pos_iou_thr
=
0.5
,
neg_iou_thr
=
0.5
,
ignore_iof_thr
=
0.5
,
ignore_wrt_candidates
=
False
,
)
bboxes
=
torch
.
FloatTensor
([
[
0
,
0
,
10
,
10
],
[
10
,
10
,
20
,
20
],
[
5
,
5
,
15
,
15
],
[
30
,
32
,
40
,
42
],
])
gt_bboxes
=
torch
.
FloatTensor
([
[
0
,
0
,
10
,
9
],
[
0
,
10
,
10
,
19
],
])
gt_bboxes_ignore
=
torch
.
Tensor
([
[
30
,
30
,
40
,
40
],
])
assign_result
=
self
.
assign
(
bboxes
,
gt_bboxes
,
gt_bboxes_ignore
=
gt_bboxes_ignore
)
expected_gt_inds
=
torch
.
LongTensor
([
1
,
0
,
2
,
-
1
])
assert
torch
.
all
(
assign_result
.
gt_inds
==
expected_gt_inds
)
def
test_max_iou_assigner_with_empty_gt
():
"""Test corner case where an image might have no true detections."""
self
=
MaxIoUAssigner
(
pos_iou_thr
=
0.5
,
neg_iou_thr
=
0.5
,
)
bboxes
=
torch
.
FloatTensor
([
[
0
,
0
,
10
,
10
],
[
10
,
10
,
20
,
20
],
[
5
,
5
,
15
,
15
],
[
32
,
32
,
38
,
42
],
])
gt_bboxes
=
torch
.
FloatTensor
(
size
=
(
0
,
4
))
assign_result
=
self
.
assign
(
bboxes
,
gt_bboxes
)
expected_gt_inds
=
torch
.
LongTensor
([
0
,
0
,
0
,
0
])
assert
torch
.
all
(
assign_result
.
gt_inds
==
expected_gt_inds
)
def
test_max_iou_assigner_with_empty_boxes
():
"""Test corner case where an network might predict no boxes."""
self
=
MaxIoUAssigner
(
pos_iou_thr
=
0.5
,
neg_iou_thr
=
0.5
,
)
bboxes
=
torch
.
empty
((
0
,
4
))
gt_bboxes
=
torch
.
FloatTensor
([
[
0
,
0
,
10
,
9
],
[
0
,
10
,
10
,
19
],
])
gt_labels
=
torch
.
LongTensor
([
2
,
3
])
# Test with gt_labels
assign_result
=
self
.
assign
(
bboxes
,
gt_bboxes
,
gt_labels
=
gt_labels
)
assert
len
(
assign_result
.
gt_inds
)
==
0
assert
tuple
(
assign_result
.
labels
.
shape
)
==
(
0
,
)
# Test without gt_labels
assign_result
=
self
.
assign
(
bboxes
,
gt_bboxes
,
gt_labels
=
None
)
assert
len
(
assign_result
.
gt_inds
)
==
0
assert
assign_result
.
labels
is
None
def
test_max_iou_assigner_with_empty_boxes_and_ignore
():
"""Test corner case where an network might predict no boxes and
ignore_iof_thr is on."""
self
=
MaxIoUAssigner
(
pos_iou_thr
=
0.5
,
neg_iou_thr
=
0.5
,
ignore_iof_thr
=
0.5
,
)
bboxes
=
torch
.
empty
((
0
,
4
))
gt_bboxes
=
torch
.
FloatTensor
([
[
0
,
0
,
10
,
9
],
[
0
,
10
,
10
,
19
],
])
gt_bboxes_ignore
=
torch
.
Tensor
([
[
30
,
30
,
40
,
40
],
])
gt_labels
=
torch
.
LongTensor
([
2
,
3
])
# Test with gt_labels
assign_result
=
self
.
assign
(
bboxes
,
gt_bboxes
,
gt_labels
=
gt_labels
,
gt_bboxes_ignore
=
gt_bboxes_ignore
)
assert
len
(
assign_result
.
gt_inds
)
==
0
assert
tuple
(
assign_result
.
labels
.
shape
)
==
(
0
,
)
# Test without gt_labels
assign_result
=
self
.
assign
(
bboxes
,
gt_bboxes
,
gt_labels
=
None
,
gt_bboxes_ignore
=
gt_bboxes_ignore
)
assert
len
(
assign_result
.
gt_inds
)
==
0
assert
assign_result
.
labels
is
None
def
test_max_iou_assigner_with_empty_boxes_and_gt
():
"""Test corner case where an network might predict no boxes and no gt."""
self
=
MaxIoUAssigner
(
pos_iou_thr
=
0.5
,
neg_iou_thr
=
0.5
,
)
bboxes
=
torch
.
empty
((
0
,
4
))
gt_bboxes
=
torch
.
empty
((
0
,
4
))
assign_result
=
self
.
assign
(
bboxes
,
gt_bboxes
)
assert
len
(
assign_result
.
gt_inds
)
==
0
Prev
1
2
3
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment