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
dcnv3
Commits
41b18fd8
Commit
41b18fd8
authored
Jan 06, 2025
by
zhe chen
Browse files
Use pre-commit to reformat code
Use pre-commit to reformat code
parent
ff20ea39
Changes
390
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
544 additions
and
625 deletions
+544
-625
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/bevformer/runner/__init__.py
...tion/projects/mmdet3d_plugin/bevformer/runner/__init__.py
+1
-1
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/bevformer/runner/epoch_based_runner.py
...cts/mmdet3d_plugin/bevformer/runner/epoch_based_runner.py
+93
-97
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/core/bbox/assigners/hungarian_assigner_3d.py
...det3d_plugin/core/bbox/assigners/hungarian_assigner_3d.py
+9
-12
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/core/bbox/coders/nms_free_coder.py
...rojects/mmdet3d_plugin/core/bbox/coders/nms_free_coder.py
+5
-8
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/core/bbox/match_costs/__init__.py
...projects/mmdet3d_plugin/core/bbox/match_costs/__init__.py
+1
-2
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/core/bbox/match_costs/match_cost.py
...ojects/mmdet3d_plugin/core/bbox/match_costs/match_cost.py
+1
-1
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/core/bbox/util.py
...ancy_prediction/projects/mmdet3d_plugin/core/bbox/util.py
+10
-10
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/core/evaluation/__init__.py
...ction/projects/mmdet3d_plugin/core/evaluation/__init__.py
+1
-1
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/core/evaluation/eval_hooks.py
...ion/projects/mmdet3d_plugin/core/evaluation/eval_hooks.py
+4
-7
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/datasets/__init__.py
...y_prediction/projects/mmdet3d_plugin/datasets/__init__.py
+1
-1
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/datasets/builder.py
...cy_prediction/projects/mmdet3d_plugin/datasets/builder.py
+26
-23
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/datasets/nuscenes_dataset.py
...tion/projects/mmdet3d_plugin/datasets/nuscenes_dataset.py
+11
-16
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/datasets/nuscenes_occ.py
...ediction/projects/mmdet3d_plugin/datasets/nuscenes_occ.py
+16
-23
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/datasets/nuscnes_eval.py
...ediction/projects/mmdet3d_plugin/datasets/nuscnes_eval.py
+36
-69
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/datasets/occ_metrics.py
...rediction/projects/mmdet3d_plugin/datasets/occ_metrics.py
+225
-239
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/datasets/pipelines/__init__.py
...on/projects/mmdet3d_plugin/datasets/pipelines/__init__.py
+9
-6
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/datasets/pipelines/formating.py
...n/projects/mmdet3d_plugin/datasets/pipelines/formating.py
+35
-39
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/datasets/pipelines/loading.py
...ion/projects/mmdet3d_plugin/datasets/pipelines/loading.py
+44
-46
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/datasets/pipelines/transform_3d.py
...rojects/mmdet3d_plugin/datasets/pipelines/transform_3d.py
+15
-22
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/datasets/samplers/__init__.py
...ion/projects/mmdet3d_plugin/datasets/samplers/__init__.py
+1
-2
No files found.
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/bevformer/runner/__init__.py
View file @
41b18fd8
from
.epoch_based_runner
import
EpochBasedRunner_video
from
.epoch_based_runner
import
EpochBasedRunner_video
\ No newline at end of file
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/bevformer/runner/epoch_based_runner.py
View file @
41b18fd8
# Copyright (c) OpenMMLab. All rights reserved.
# Copyright (c) OpenMMLab. All rights reserved.
# ---------------------------------------------
# ---------------------------------------------
# Modified by Zhiqi Li
# Modified by Zhiqi Li
# ---------------------------------------------
# ---------------------------------------------
import
os.path
as
osp
import
torch
import
torch
from
mmcv.parallel.data_container
import
DataContainer
import
mmcv
from
mmcv.runner.builder
import
RUNNERS
from
mmcv.runner.base_runner
import
BaseRunner
from
mmcv.runner.epoch_based_runner
import
EpochBasedRunner
from
mmcv.runner.epoch_based_runner
import
EpochBasedRunner
from
mmcv.runner.builder
import
RUNNERS
from
mmcv.runner.checkpoint
import
save_checkpoint
@
RUNNERS
.
register_module
()
from
mmcv.runner.utils
import
get_host_info
class
EpochBasedRunner_video
(
EpochBasedRunner
):
from
pprint
import
pprint
'''
from
mmcv.parallel.data_container
import
DataContainer
# basic logic
input_sequence = [a, b, c] # given a sequence of samples
@
RUNNERS
.
register_module
()
class
EpochBasedRunner_video
(
EpochBasedRunner
):
prev_bev = None
for each in input_sequcene[:-1]
'''
prev_bev = eval_model(each, prev_bev)) # inference only.
# basic logic
model(input_sequcene[-1], prev_bev) # train the last sample.
input_sequence = [a, b, c] # given a sequence of samples
'''
prev_bev = None
def
__init__
(
self
,
for each in input_sequcene[:-1]
model
,
prev_bev = eval_model(each, prev_bev)) # inference only.
eval_model
=
None
,
batch_processor
=
None
,
model(input_sequcene[-1], prev_bev) # train the last sample.
optimizer
=
None
,
'''
work_dir
=
None
,
logger
=
None
,
def
__init__
(
self
,
meta
=
None
,
model
,
keys
=
[
'gt_bboxes_3d'
,
'gt_labels_3d'
,
'img'
],
eval_model
=
None
,
max_iters
=
None
,
batch_processor
=
None
,
max_epochs
=
None
):
optimizer
=
None
,
super
().
__init__
(
model
,
work_dir
=
None
,
batch_processor
,
logger
=
None
,
optimizer
,
meta
=
None
,
work_dir
,
keys
=
[
'gt_bboxes_3d'
,
'gt_labels_3d'
,
'img'
],
logger
,
max_iters
=
None
,
meta
,
max_epochs
=
None
):
max_iters
,
super
().
__init__
(
model
,
max_epochs
)
batch_processor
,
keys
.
append
(
'img_metas'
)
optimizer
,
self
.
keys
=
keys
work_dir
,
self
.
eval_model
=
eval_model
logger
,
self
.
eval_model
.
eval
()
meta
,
max_iters
,
def
run_iter
(
self
,
data_batch
,
train_mode
,
**
kwargs
):
max_epochs
)
if
self
.
batch_processor
is
not
None
:
keys
.
append
(
'img_metas'
)
assert
False
self
.
keys
=
keys
# outputs = self.batch_processor(
self
.
eval_model
=
eval_model
# self.model, data_batch, train_mode=train_mode, **kwargs)
self
.
eval_model
.
eval
()
elif
train_mode
:
def
run_iter
(
self
,
data_batch
,
train_mode
,
**
kwargs
):
num_samples
=
data_batch
[
'img'
].
data
[
0
].
size
(
1
)
if
self
.
batch_processor
is
not
None
:
data_list
=
[]
assert
False
prev_bev
=
None
# outputs = self.batch_processor(
for
i
in
range
(
num_samples
):
# self.model, data_batch, train_mode=train_mode, **kwargs)
data
=
{}
elif
train_mode
:
for
key
in
self
.
keys
:
if
key
not
in
[
'img_metas'
,
'img'
,
'points'
]:
num_samples
=
data_batch
[
'img'
].
data
[
0
].
size
(
1
)
data
[
key
]
=
data_batch
[
key
]
data_list
=
[]
else
:
prev_bev
=
None
if
key
==
'img'
:
for
i
in
range
(
num_samples
):
data
[
'img'
]
=
DataContainer
(
data
=
[
data_batch
[
'img'
].
data
[
0
][:,
i
]],
data
=
{}
cpu_only
=
data_batch
[
'img'
].
cpu_only
,
stack
=
True
)
for
key
in
self
.
keys
:
elif
key
==
'img_metas'
:
if
key
not
in
[
'img_metas'
,
'img'
,
'points'
]:
data
[
'img_metas'
]
=
DataContainer
(
data
[
key
]
=
data_batch
[
key
]
data
=
[[
each
[
i
]
for
each
in
data_batch
[
'img_metas'
].
data
[
0
]]],
else
:
cpu_only
=
data_batch
[
'img_metas'
].
cpu_only
)
if
key
==
'img'
:
else
:
data
[
'img'
]
=
DataContainer
(
data
=
[
data_batch
[
'img'
].
data
[
0
][:,
i
]],
cpu_only
=
data_batch
[
'img'
].
cpu_only
,
stack
=
True
)
assert
False
elif
key
==
'img_metas'
:
data_list
.
append
(
data
)
data
[
'img_metas'
]
=
DataContainer
(
data
=
[[
each
[
i
]
for
each
in
data_batch
[
'img_metas'
].
data
[
0
]]],
cpu_only
=
data_batch
[
'img_metas'
].
cpu_only
)
with
torch
.
no_grad
():
else
:
for
i
in
range
(
num_samples
-
1
):
assert
False
if
data_list
[
i
][
'img_metas'
].
data
[
0
][
0
][
'prev_bev_exists'
]:
data_list
.
append
(
data
)
data_list
[
i
][
'prev_bev'
]
=
DataContainer
(
data
=
[
prev_bev
],
cpu_only
=
False
)
with
torch
.
no_grad
():
prev_bev
=
self
.
eval_model
.
val_step
(
data_list
[
i
],
self
.
optimizer
,
**
kwargs
)
for
i
in
range
(
num_samples
-
1
):
if
data_list
[
-
1
][
'img_metas'
].
data
[
0
][
0
][
'prev_bev_exists'
]:
if
data_list
[
i
][
'img_metas'
].
data
[
0
][
0
][
'prev_bev_exists'
]:
data_list
[
-
1
][
'prev_bev'
]
=
DataContainer
(
data
=
[
prev_bev
],
cpu_only
=
False
)
data_list
[
i
][
'prev_bev'
]
=
DataContainer
(
data
=
[
prev_bev
],
cpu_only
=
False
)
outputs
=
self
.
model
.
train_step
(
data_list
[
-
1
],
self
.
optimizer
,
**
kwargs
)
prev_bev
=
self
.
eval_model
.
val_step
(
data_list
[
i
],
self
.
optimizer
,
**
kwargs
)
else
:
if
data_list
[
-
1
][
'img_metas'
].
data
[
0
][
0
][
'prev_bev_exists'
]:
assert
False
data_list
[
-
1
][
'prev_bev'
]
=
DataContainer
(
data
=
[
prev_bev
],
cpu_only
=
False
)
# outputs = self.model.val_step(data_batch, self.optimizer, **kwargs)
outputs
=
self
.
model
.
train_step
(
data_list
[
-
1
],
self
.
optimizer
,
**
kwargs
)
else
:
if
not
isinstance
(
outputs
,
dict
):
assert
False
raise
TypeError
(
'"batch_processor()" or "model.train_step()"'
# outputs = self.model.val_step(data_batch, self.optimizer, **kwargs)
'and "model.val_step()" must return a dict'
)
if
'log_vars'
in
outputs
:
if
not
isinstance
(
outputs
,
dict
):
self
.
log_buffer
.
update
(
outputs
[
'log_vars'
],
outputs
[
'num_samples'
])
raise
TypeError
(
'"batch_processor()" or "model.train_step()"'
self
.
outputs
=
outputs
'and "model.val_step()" must return a dict'
)
if
'log_vars'
in
outputs
:
self
.
log_buffer
.
update
(
outputs
[
'log_vars'
],
outputs
[
'num_samples'
])
self
.
outputs
=
outputs
\ No newline at end of file
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/core/bbox/assigners/hungarian_assigner_3d.py
View file @
41b18fd8
import
torch
import
torch
from
mmdet.core.bbox.assigners
import
AssignResult
,
BaseAssigner
from
mmdet.core.bbox.builder
import
BBOX_ASSIGNERS
from
mmdet.core.bbox.builder
import
BBOX_ASSIGNERS
from
mmdet.core.bbox.assigners
import
AssignResult
from
mmdet.core.bbox.assigners
import
BaseAssigner
from
mmdet.core.bbox.match_costs
import
build_match_cost
from
mmdet.core.bbox.match_costs
import
build_match_cost
from
mmdet.models.utils.transformer
import
inverse_sigmoid
from
projects.mmdet3d_plugin.core.bbox.util
import
normalize_bbox
from
projects.mmdet3d_plugin.core.bbox.util
import
normalize_bbox
try
:
try
:
...
@@ -52,7 +49,7 @@ class HungarianAssigner3D(BaseAssigner):
...
@@ -52,7 +49,7 @@ class HungarianAssigner3D(BaseAssigner):
def
assign
(
self
,
def
assign
(
self
,
bbox_pred
,
bbox_pred
,
cls_pred
,
cls_pred
,
gt_bboxes
,
gt_bboxes
,
gt_labels
,
gt_labels
,
gt_bboxes_ignore
=
None
,
gt_bboxes_ignore
=
None
,
eps
=
1e-7
):
eps
=
1e-7
):
...
@@ -89,10 +86,10 @@ class HungarianAssigner3D(BaseAssigner):
...
@@ -89,10 +86,10 @@ class HungarianAssigner3D(BaseAssigner):
num_gts
,
num_bboxes
=
gt_bboxes
.
size
(
0
),
bbox_pred
.
size
(
0
)
num_gts
,
num_bboxes
=
gt_bboxes
.
size
(
0
),
bbox_pred
.
size
(
0
)
# 1. assign -1 by default
# 1. assign -1 by default
assigned_gt_inds
=
bbox_pred
.
new_full
((
num_bboxes
,
),
assigned_gt_inds
=
bbox_pred
.
new_full
((
num_bboxes
,),
-
1
,
-
1
,
dtype
=
torch
.
long
)
dtype
=
torch
.
long
)
assigned_labels
=
bbox_pred
.
new_full
((
num_bboxes
,
),
assigned_labels
=
bbox_pred
.
new_full
((
num_bboxes
,),
-
1
,
-
1
,
dtype
=
torch
.
long
)
dtype
=
torch
.
long
)
if
num_gts
==
0
or
num_bboxes
==
0
:
if
num_gts
==
0
or
num_bboxes
==
0
:
...
@@ -107,14 +104,14 @@ class HungarianAssigner3D(BaseAssigner):
...
@@ -107,14 +104,14 @@ class HungarianAssigner3D(BaseAssigner):
# classification and bboxcost.
# classification and bboxcost.
cls_cost
=
self
.
cls_cost
(
cls_pred
,
gt_labels
)
cls_cost
=
self
.
cls_cost
(
cls_pred
,
gt_labels
)
# regression L1 cost
# regression L1 cost
normalized_gt_bboxes
=
normalize_bbox
(
gt_bboxes
,
self
.
pc_range
)
normalized_gt_bboxes
=
normalize_bbox
(
gt_bboxes
,
self
.
pc_range
)
reg_cost
=
self
.
reg_cost
(
bbox_pred
[:,
:
8
],
normalized_gt_bboxes
[:,
:
8
])
reg_cost
=
self
.
reg_cost
(
bbox_pred
[:,
:
8
],
normalized_gt_bboxes
[:,
:
8
])
# weighted sum of above two costs
# weighted sum of above two costs
cost
=
cls_cost
+
reg_cost
cost
=
cls_cost
+
reg_cost
# 3. do Hungarian matching on CPU using linear_sum_assignment
# 3. do Hungarian matching on CPU using linear_sum_assignment
cost
=
cost
.
detach
().
cpu
()
cost
=
cost
.
detach
().
cpu
()
if
linear_sum_assignment
is
None
:
if
linear_sum_assignment
is
None
:
...
@@ -133,4 +130,4 @@ class HungarianAssigner3D(BaseAssigner):
...
@@ -133,4 +130,4 @@ class HungarianAssigner3D(BaseAssigner):
assigned_gt_inds
[
matched_row_inds
]
=
matched_col_inds
+
1
assigned_gt_inds
[
matched_row_inds
]
=
matched_col_inds
+
1
assigned_labels
[
matched_row_inds
]
=
gt_labels
[
matched_col_inds
]
assigned_labels
[
matched_row_inds
]
=
gt_labels
[
matched_col_inds
]
return
AssignResult
(
return
AssignResult
(
num_gts
,
assigned_gt_inds
,
None
,
labels
=
assigned_labels
)
num_gts
,
assigned_gt_inds
,
None
,
labels
=
assigned_labels
)
\ No newline at end of file
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/core/bbox/coders/nms_free_coder.py
View file @
41b18fd8
import
torch
import
torch
from
mmdet.core.bbox
import
BaseBBoxCoder
from
mmdet.core.bbox
import
BaseBBoxCoder
from
mmdet.core.bbox.builder
import
BBOX_CODERS
from
mmdet.core.bbox.builder
import
BBOX_CODERS
from
projects.mmdet3d_plugin.core.bbox.util
import
denormalize_bbox
from
projects.mmdet3d_plugin.core.bbox.util
import
denormalize_bbox
import
numpy
as
np
@
BBOX_CODERS
.
register_module
()
@
BBOX_CODERS
.
register_module
()
...
@@ -56,10 +54,10 @@ class NMSFreeCoder(BaseBBoxCoder):
...
@@ -56,10 +54,10 @@ class NMSFreeCoder(BaseBBoxCoder):
labels
=
indexs
%
self
.
num_classes
labels
=
indexs
%
self
.
num_classes
bbox_index
=
indexs
//
self
.
num_classes
bbox_index
=
indexs
//
self
.
num_classes
bbox_preds
=
bbox_preds
[
bbox_index
]
bbox_preds
=
bbox_preds
[
bbox_index
]
final_box_preds
=
denormalize_bbox
(
bbox_preds
,
self
.
pc_range
)
final_box_preds
=
denormalize_bbox
(
bbox_preds
,
self
.
pc_range
)
final_scores
=
scores
final_scores
=
scores
final_preds
=
labels
final_preds
=
labels
# use score threshold
# use score threshold
if
self
.
score_threshold
is
not
None
:
if
self
.
score_threshold
is
not
None
:
...
@@ -113,10 +111,9 @@ class NMSFreeCoder(BaseBBoxCoder):
...
@@ -113,10 +111,9 @@ class NMSFreeCoder(BaseBBoxCoder):
"""
"""
all_cls_scores
=
preds_dicts
[
'all_cls_scores'
][
-
1
]
all_cls_scores
=
preds_dicts
[
'all_cls_scores'
][
-
1
]
all_bbox_preds
=
preds_dicts
[
'all_bbox_preds'
][
-
1
]
all_bbox_preds
=
preds_dicts
[
'all_bbox_preds'
][
-
1
]
batch_size
=
all_cls_scores
.
size
()[
0
]
batch_size
=
all_cls_scores
.
size
()[
0
]
predictions_list
=
[]
predictions_list
=
[]
for
i
in
range
(
batch_size
):
for
i
in
range
(
batch_size
):
predictions_list
.
append
(
self
.
decode_single
(
all_cls_scores
[
i
],
all_bbox_preds
[
i
]))
predictions_list
.
append
(
self
.
decode_single
(
all_cls_scores
[
i
],
all_bbox_preds
[
i
]))
return
predictions_list
return
predictions_list
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/core/bbox/match_costs/__init__.py
View file @
41b18fd8
from
mmdet.core.bbox.match_costs
import
build_match_cost
from
.match_cost
import
BBox3DL1Cost
from
.match_cost
import
BBox3DL1Cost
__all__
=
[
'build_match_cost'
,
'BBox3DL1Cost'
]
__all__
=
[
'build_match_cost'
,
'BBox3DL1Cost'
]
\ No newline at end of file
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/core/bbox/match_costs/match_cost.py
View file @
41b18fd8
...
@@ -24,4 +24,4 @@ class BBox3DL1Cost(object):
...
@@ -24,4 +24,4 @@ class BBox3DL1Cost(object):
torch.Tensor: bbox_cost value with weight
torch.Tensor: bbox_cost value with weight
"""
"""
bbox_cost
=
torch
.
cdist
(
bbox_pred
,
gt_bboxes
,
p
=
1
)
bbox_cost
=
torch
.
cdist
(
bbox_pred
,
gt_bboxes
,
p
=
1
)
return
bbox_cost
*
self
.
weight
return
bbox_cost
*
self
.
weight
\ No newline at end of file
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/core/bbox/util.py
View file @
41b18fd8
import
torch
import
torch
def
normalize_bbox
(
bboxes
,
pc_range
):
def
normalize_bbox
(
bboxes
,
pc_range
):
cx
=
bboxes
[...,
0
:
1
]
cx
=
bboxes
[...,
0
:
1
]
cy
=
bboxes
[...,
1
:
2
]
cy
=
bboxes
[...,
1
:
2
]
cz
=
bboxes
[...,
2
:
3
]
cz
=
bboxes
[...,
2
:
3
]
...
@@ -12,7 +11,7 @@ def normalize_bbox(bboxes, pc_range):
...
@@ -12,7 +11,7 @@ def normalize_bbox(bboxes, pc_range):
rot
=
bboxes
[...,
6
:
7
]
rot
=
bboxes
[...,
6
:
7
]
if
bboxes
.
size
(
-
1
)
>
7
:
if
bboxes
.
size
(
-
1
)
>
7
:
vx
=
bboxes
[...,
7
:
8
]
vx
=
bboxes
[...,
7
:
8
]
vy
=
bboxes
[...,
8
:
9
]
vy
=
bboxes
[...,
8
:
9
]
normalized_bboxes
=
torch
.
cat
(
normalized_bboxes
=
torch
.
cat
(
(
cx
,
cy
,
w
,
l
,
cz
,
h
,
rot
.
sin
(),
rot
.
cos
(),
vx
,
vy
),
dim
=-
1
(
cx
,
cy
,
w
,
l
,
cz
,
h
,
rot
.
sin
(),
rot
.
cos
(),
vx
,
vy
),
dim
=-
1
...
@@ -23,8 +22,9 @@ def normalize_bbox(bboxes, pc_range):
...
@@ -23,8 +22,9 @@ def normalize_bbox(bboxes, pc_range):
)
)
return
normalized_bboxes
return
normalized_bboxes
def
denormalize_bbox
(
normalized_bboxes
,
pc_range
):
def
denormalize_bbox
(
normalized_bboxes
,
pc_range
):
# rotation
# rotation
rot_sine
=
normalized_bboxes
[...,
6
:
7
]
rot_sine
=
normalized_bboxes
[...,
6
:
7
]
rot_cosine
=
normalized_bboxes
[...,
7
:
8
]
rot_cosine
=
normalized_bboxes
[...,
7
:
8
]
...
@@ -34,20 +34,20 @@ def denormalize_bbox(normalized_bboxes, pc_range):
...
@@ -34,20 +34,20 @@ def denormalize_bbox(normalized_bboxes, pc_range):
cx
=
normalized_bboxes
[...,
0
:
1
]
cx
=
normalized_bboxes
[...,
0
:
1
]
cy
=
normalized_bboxes
[...,
1
:
2
]
cy
=
normalized_bboxes
[...,
1
:
2
]
cz
=
normalized_bboxes
[...,
4
:
5
]
cz
=
normalized_bboxes
[...,
4
:
5
]
# size
# size
w
=
normalized_bboxes
[...,
2
:
3
]
w
=
normalized_bboxes
[...,
2
:
3
]
l
=
normalized_bboxes
[...,
3
:
4
]
l
=
normalized_bboxes
[...,
3
:
4
]
h
=
normalized_bboxes
[...,
5
:
6
]
h
=
normalized_bboxes
[...,
5
:
6
]
w
=
w
.
exp
()
w
=
w
.
exp
()
l
=
l
.
exp
()
l
=
l
.
exp
()
h
=
h
.
exp
()
h
=
h
.
exp
()
if
normalized_bboxes
.
size
(
-
1
)
>
8
:
if
normalized_bboxes
.
size
(
-
1
)
>
8
:
# velocity
# velocity
vx
=
normalized_bboxes
[:,
8
:
9
]
vx
=
normalized_bboxes
[:,
8
:
9
]
vy
=
normalized_bboxes
[:,
9
:
10
]
vy
=
normalized_bboxes
[:,
9
:
10
]
denormalized_bboxes
=
torch
.
cat
([
cx
,
cy
,
cz
,
w
,
l
,
h
,
rot
,
vx
,
vy
],
dim
=-
1
)
denormalized_bboxes
=
torch
.
cat
([
cx
,
cy
,
cz
,
w
,
l
,
h
,
rot
,
vx
,
vy
],
dim
=-
1
)
else
:
else
:
denormalized_bboxes
=
torch
.
cat
([
cx
,
cy
,
cz
,
w
,
l
,
h
,
rot
],
dim
=-
1
)
denormalized_bboxes
=
torch
.
cat
([
cx
,
cy
,
cz
,
w
,
l
,
h
,
rot
],
dim
=-
1
)
return
denormalized_bboxes
return
denormalized_bboxes
\ No newline at end of file
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/core/evaluation/__init__.py
View file @
41b18fd8
from
.eval_hooks
import
CustomDistEvalHook
from
.eval_hooks
import
CustomDistEvalHook
\ No newline at end of file
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/core/evaluation/eval_hooks.py
View file @
41b18fd8
# Note: Considering that MMCV's EvalHook updated its interface in V1.3.16,
# Note: Considering that MMCV's EvalHook updated its interface in V1.3.16,
# in order to avoid strong version dependency, we did not directly
# in order to avoid strong version dependency, we did not directly
# inherit EvalHook but BaseDistEvalHook.
# inherit EvalHook but BaseDistEvalHook.
...
@@ -9,9 +8,7 @@ import os.path as osp
...
@@ -9,9 +8,7 @@ import os.path as osp
import
mmcv
import
mmcv
import
torch.distributed
as
dist
import
torch.distributed
as
dist
from
mmcv.runner
import
DistEvalHook
as
BaseDistEvalHook
from
mmcv.runner
import
DistEvalHook
as
BaseDistEvalHook
from
mmcv.runner
import
EvalHook
as
BaseEvalHook
from
torch.nn.modules.batchnorm
import
_BatchNorm
from
torch.nn.modules.batchnorm
import
_BatchNorm
from
mmdet.core.evaluation.eval_hooks
import
DistEvalHook
def
_calc_dynamic_intervals
(
start_interval
,
dynamic_interval_list
):
def
_calc_dynamic_intervals
(
start_interval
,
dynamic_interval_list
):
...
@@ -28,7 +25,7 @@ def _calc_dynamic_intervals(start_interval, dynamic_interval_list):
...
@@ -28,7 +25,7 @@ def _calc_dynamic_intervals(start_interval, dynamic_interval_list):
class
CustomDistEvalHook
(
BaseDistEvalHook
):
class
CustomDistEvalHook
(
BaseDistEvalHook
):
def
__init__
(
self
,
*
args
,
dynamic_intervals
=
None
,
**
kwargs
):
def
__init__
(
self
,
*
args
,
dynamic_intervals
=
None
,
**
kwargs
):
super
(
CustomDistEvalHook
,
self
).
__init__
(
*
args
,
**
kwargs
)
super
(
CustomDistEvalHook
,
self
).
__init__
(
*
args
,
**
kwargs
)
self
.
use_dynamic_intervals
=
dynamic_intervals
is
not
None
self
.
use_dynamic_intervals
=
dynamic_intervals
is
not
None
if
self
.
use_dynamic_intervals
:
if
self
.
use_dynamic_intervals
:
...
@@ -73,7 +70,8 @@ class CustomDistEvalHook(BaseDistEvalHook):
...
@@ -73,7 +70,8 @@ class CustomDistEvalHook(BaseDistEvalHook):
if
tmpdir
is
None
:
if
tmpdir
is
None
:
tmpdir
=
osp
.
join
(
runner
.
work_dir
,
'.eval_hook'
)
tmpdir
=
osp
.
join
(
runner
.
work_dir
,
'.eval_hook'
)
from
projects.mmdet3d_plugin.bevformer.apis.test
import
custom_multi_gpu_test
# to solve circlur import
from
projects.mmdet3d_plugin.bevformer.apis.test
import
\
custom_multi_gpu_test
# to solve circlur import
results
=
custom_multi_gpu_test
(
results
=
custom_multi_gpu_test
(
runner
.
model
,
runner
.
model
,
...
@@ -86,7 +84,6 @@ class CustomDistEvalHook(BaseDistEvalHook):
...
@@ -86,7 +84,6 @@ class CustomDistEvalHook(BaseDistEvalHook):
# key_score = self.evaluate(runner, results)
# key_score = self.evaluate(runner, results)
self
.
dataloader
.
dataset
.
evaluate_miou
(
results
,
self
.
dataloader
.
dataset
.
evaluate_miou
(
results
,
runner
=
runner
)
runner
=
runner
)
# if self.save_best:
# if self.save_best:
# self._save_ckpt(runner, key_score)
# self._save_ckpt(runner, key_score)
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/datasets/__init__.py
View file @
41b18fd8
from
.builder
import
custom_build_dataset
from
.nuscenes_dataset
import
CustomNuScenesDataset
from
.nuscenes_dataset
import
CustomNuScenesDataset
from
.nuscenes_occ
import
NuSceneOcc
from
.nuscenes_occ
import
NuSceneOcc
from
.builder
import
custom_build_dataset
__all__
=
[
__all__
=
[
'CustomNuScenesDataset'
'CustomNuScenesDataset'
...
...
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/datasets/builder.py
View file @
41b18fd8
# Copyright (c) OpenMMLab. All rights reserved.
# Copyright (c) OpenMMLab. All rights reserved.
import
copy
import
copy
import
platform
import
platform
...
@@ -8,13 +7,14 @@ from functools import partial
...
@@ -8,13 +7,14 @@ from functools import partial
import
numpy
as
np
import
numpy
as
np
from
mmcv.parallel
import
collate
from
mmcv.parallel
import
collate
from
mmcv.runner
import
get_dist_info
from
mmcv.runner
import
get_dist_info
from
mmcv.utils
import
Registry
,
build_from_cfg
from
torch.utils.data
import
DataLoader
from
mmdet.datasets.samplers
import
GroupSampler
from
mmdet.datasets.samplers
import
GroupSampler
from
projects.mmdet3d_plugin.datasets.samplers.group_sampler
import
DistributedGroupSampler
from
projects.mmdet3d_plugin.datasets.samplers.distributed_sampler
import
\
from
projects.mmdet3d_plugin.datasets.samplers.distributed_sampler
import
DistributedSampler
DistributedSampler
from
projects.mmdet3d_plugin.datasets.samplers.group_sampler
import
\
DistributedGroupSampler
from
projects.mmdet3d_plugin.datasets.samplers.sampler
import
build_sampler
from
projects.mmdet3d_plugin.datasets.samplers.sampler
import
build_sampler
from
torch.utils.data
import
DataLoader
def
build_dataloader
(
dataset
,
def
build_dataloader
(
dataset
,
samples_per_gpu
,
samples_per_gpu
,
...
@@ -48,24 +48,26 @@ def build_dataloader(dataset,
...
@@ -48,24 +48,26 @@ def build_dataloader(dataset,
# DistributedGroupSampler will definitely shuffle the data to satisfy
# DistributedGroupSampler will definitely shuffle the data to satisfy
# that images on each GPU are in the same group
# that images on each GPU are in the same group
if
shuffle
:
if
shuffle
:
sampler
=
build_sampler
(
shuffler_sampler
if
shuffler_sampler
is
not
None
else
dict
(
type
=
'DistributedGroupSampler'
),
sampler
=
build_sampler
(
dict
(
shuffler_sampler
if
shuffler_sampler
is
not
None
else
dict
(
type
=
'DistributedGroupSampler'
),
dataset
=
dataset
,
dict
(
samples_per_gpu
=
samples_per_gpu
,
dataset
=
dataset
,
num_replicas
=
world_size
,
samples_per_gpu
=
samples_per_gpu
,
rank
=
rank
,
num_replicas
=
world_size
,
seed
=
seed
)
rank
=
rank
,
)
seed
=
seed
)
)
else
:
else
:
sampler
=
build_sampler
(
nonshuffler_sampler
if
nonshuffler_sampler
is
not
None
else
dict
(
type
=
'DistributedSampler'
),
sampler
=
build_sampler
(
dict
(
nonshuffler_sampler
if
nonshuffler_sampler
is
not
None
else
dict
(
type
=
'DistributedSampler'
),
dataset
=
dataset
,
dict
(
num_replicas
=
world_size
,
dataset
=
dataset
,
rank
=
rank
,
num_replicas
=
world_size
,
shuffle
=
shuffle
,
rank
=
rank
,
seed
=
seed
)
shuffle
=
shuffle
,
)
seed
=
seed
)
)
batch_size
=
samples_per_gpu
batch_size
=
samples_per_gpu
num_workers
=
workers_per_gpu
num_workers
=
workers_per_gpu
...
@@ -103,14 +105,15 @@ def worker_init_fn(worker_id, num_workers, rank, seed):
...
@@ -103,14 +105,15 @@ def worker_init_fn(worker_id, num_workers, rank, seed):
# Copyright (c) OpenMMLab. All rights reserved.
# Copyright (c) OpenMMLab. All rights reserved.
import
platform
import
platform
from
mmcv.utils
import
Registry
,
build_from_cfg
from
mmcv.utils
import
Registry
,
build_from_cfg
from
mmdet.datasets
import
DATASETS
from
mmdet.datasets
import
DATASETS
from
mmdet.datasets.builder
import
_concat_dataset
from
mmdet.datasets.builder
import
_concat_dataset
if
platform
.
system
()
!=
'Windows'
:
if
platform
.
system
()
!=
'Windows'
:
# https://github.com/pytorch/pytorch/issues/973
# https://github.com/pytorch/pytorch/issues/973
import
resource
import
resource
rlimit
=
resource
.
getrlimit
(
resource
.
RLIMIT_NOFILE
)
rlimit
=
resource
.
getrlimit
(
resource
.
RLIMIT_NOFILE
)
base_soft_limit
=
rlimit
[
0
]
base_soft_limit
=
rlimit
[
0
]
hard_limit
=
rlimit
[
1
]
hard_limit
=
rlimit
[
1
]
...
...
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/datasets/nuscenes_dataset.py
View file @
41b18fd8
import
copy
import
copy
import
random
from
os
import
path
as
osp
import
mmcv
import
numpy
as
np
import
numpy
as
np
from
mmdet.datasets
import
DATASETS
import
torch
from
mmcv.parallel
import
DataContainer
as
DC
from
mmdet3d.core.bbox
import
LiDARInstance3DBoxes
from
mmdet3d.datasets
import
NuScenesDataset
from
mmdet3d.datasets
import
NuScenesDataset
import
mmcv
from
os
import
path
as
osp
from
mmdet.datasets
import
DATASETS
from
mmdet.datasets
import
DATASETS
import
torch
from
nuscenes.eval.common.utils
import
Quaternion
,
quaternion_yaw
import
numpy
as
np
from
nuscenes.eval.common.utils
import
quaternion_yaw
,
Quaternion
from
mmdet3d.core.bbox
import
Box3DMode
,
Coord3DMode
,
LiDARInstance3DBoxes
from
.nuscnes_eval
import
NuScenesEval_custom
from
.nuscnes_eval
import
NuScenesEval_custom
from
projects.mmdet3d_plugin.models.utils.visual
import
save_tensor
from
mmcv.parallel
import
DataContainer
as
DC
import
random
@
DATASETS
.
register_module
()
@
DATASETS
.
register_module
()
...
@@ -28,7 +26,7 @@ class CustomNuScenesDataset(NuScenesDataset):
...
@@ -28,7 +26,7 @@ class CustomNuScenesDataset(NuScenesDataset):
self
.
queue_length
=
queue_length
self
.
queue_length
=
queue_length
self
.
overlap_test
=
overlap_test
self
.
overlap_test
=
overlap_test
self
.
bev_size
=
bev_size
self
.
bev_size
=
bev_size
def
prepare_train_data
(
self
,
index
):
def
prepare_train_data
(
self
,
index
):
"""
"""
Training data preparation.
Training data preparation.
...
@@ -38,7 +36,7 @@ class CustomNuScenesDataset(NuScenesDataset):
...
@@ -38,7 +36,7 @@ class CustomNuScenesDataset(NuScenesDataset):
dict: Training data dict of the corresponding index.
dict: Training data dict of the corresponding index.
"""
"""
queue
=
[]
queue
=
[]
index_list
=
list
(
range
(
index
-
self
.
queue_length
,
index
))
index_list
=
list
(
range
(
index
-
self
.
queue_length
,
index
))
random
.
shuffle
(
index_list
)
random
.
shuffle
(
index_list
)
index_list
=
sorted
(
index_list
[
1
:])
index_list
=
sorted
(
index_list
[
1
:])
index_list
.
append
(
index
)
index_list
.
append
(
index
)
...
@@ -55,7 +53,6 @@ class CustomNuScenesDataset(NuScenesDataset):
...
@@ -55,7 +53,6 @@ class CustomNuScenesDataset(NuScenesDataset):
queue
.
append
(
example
)
queue
.
append
(
example
)
return
self
.
union2one
(
queue
)
return
self
.
union2one
(
queue
)
def
union2one
(
self
,
queue
):
def
union2one
(
self
,
queue
):
imgs_list
=
[
each
[
'img'
].
data
for
each
in
queue
]
imgs_list
=
[
each
[
'img'
].
data
for
each
in
queue
]
metas_map
=
{}
metas_map
=
{}
...
@@ -127,8 +124,6 @@ class CustomNuScenesDataset(NuScenesDataset):
...
@@ -127,8 +124,6 @@ class CustomNuScenesDataset(NuScenesDataset):
box_dim
=
gt_bboxes_3d
.
shape
[
-
1
],
box_dim
=
gt_bboxes_3d
.
shape
[
-
1
],
origin
=
(
0.5
,
0.5
,
0.5
)).
convert_to
(
self
.
box_mode_3d
)
origin
=
(
0.5
,
0.5
,
0.5
)).
convert_to
(
self
.
box_mode_3d
)
anns_results
=
dict
(
anns_results
=
dict
(
gt_bboxes_3d
=
gt_bboxes_3d
,
gt_bboxes_3d
=
gt_bboxes_3d
,
gt_labels_3d
=
gt_labels_3d
,
gt_labels_3d
=
gt_labels_3d
,
...
@@ -180,7 +175,7 @@ class CustomNuScenesDataset(NuScenesDataset):
...
@@ -180,7 +175,7 @@ class CustomNuScenesDataset(NuScenesDataset):
# obtain lidar to image transformation matrix
# obtain lidar to image transformation matrix
lidar2cam_r
=
np
.
linalg
.
inv
(
cam_info
[
'sensor2lidar_rotation'
])
lidar2cam_r
=
np
.
linalg
.
inv
(
cam_info
[
'sensor2lidar_rotation'
])
lidar2cam_t
=
cam_info
[
lidar2cam_t
=
cam_info
[
'sensor2lidar_translation'
]
@
lidar2cam_r
.
T
'sensor2lidar_translation'
]
@
lidar2cam_r
.
T
lidar2cam_rt
=
np
.
eye
(
4
)
lidar2cam_rt
=
np
.
eye
(
4
)
lidar2cam_rt
[:
3
,
:
3
]
=
lidar2cam_r
.
T
lidar2cam_rt
[:
3
,
:
3
]
=
lidar2cam_r
.
T
lidar2cam_rt
[
3
,
:
3
]
=
-
lidar2cam_t
lidar2cam_rt
[
3
,
:
3
]
=
-
lidar2cam_t
...
...
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/datasets/nuscenes_occ.py
View file @
41b18fd8
import
copy
import
copy
import
os
import
os
import
numpy
as
np
import
random
from
tqdm
import
tqdm
from
mmdet.datasets
import
DATASETS
from
mmdet3d.datasets
import
NuScenesDataset
import
mmcv
import
mmcv
from
os
import
path
as
osp
from
mmdet.datasets
import
DATASETS
import
torch
import
numpy
as
np
import
numpy
as
np
from
nuscenes.eval.common.utils
import
quaternion_yaw
,
Quaternion
import
torch
from
.nuscnes_eval
import
NuScenesEval_custom
from
projects.mmdet3d_plugin.models.utils.visual
import
save_tensor
from
mmcv.parallel
import
DataContainer
as
DC
from
mmcv.parallel
import
DataContainer
as
DC
import
random
from
mmdet3d.datasets
import
NuScenesDataset
from
mmdet.datasets
import
DATASETS
from
nuscenes.eval.common.utils
import
Quaternion
,
quaternion_yaw
from
nuscenes.utils.geometry_utils
import
transform_matrix
from
nuscenes.utils.geometry_utils
import
transform_matrix
from
.occ_metrics
import
Metric_mIoU
,
Metric_FScore
from
tqdm
import
tqdm
from
.occ_metrics
import
Metric_FScore
,
Metric_mIoU
@
DATASETS
.
register_module
()
@
DATASETS
.
register_module
()
...
@@ -209,8 +206,8 @@ class NuSceneOcc(NuScenesDataset):
...
@@ -209,8 +206,8 @@ class NuSceneOcc(NuScenesDataset):
if
not
os
.
path
.
exists
(
show_dir
):
if
not
os
.
path
.
exists
(
show_dir
):
os
.
mkdir
(
show_dir
)
os
.
mkdir
(
show_dir
)
print
(
'
\n
Saving output and gt in {} for visualization.'
.
format
(
show_dir
))
print
(
'
\n
Saving output and gt in {} for visualization.'
.
format
(
show_dir
))
begin
=
eval_kwargs
.
get
(
'begin'
,
None
)
begin
=
eval_kwargs
.
get
(
'begin'
,
None
)
end
=
eval_kwargs
.
get
(
'end'
,
None
)
end
=
eval_kwargs
.
get
(
'end'
,
None
)
self
.
occ_eval_metrics
=
Metric_mIoU
(
self
.
occ_eval_metrics
=
Metric_mIoU
(
num_classes
=
18
,
num_classes
=
18
,
use_lidar_mask
=
False
,
use_lidar_mask
=
False
,
...
@@ -233,15 +230,14 @@ class NuSceneOcc(NuScenesDataset):
...
@@ -233,15 +230,14 @@ class NuSceneOcc(NuScenesDataset):
occ_gt
=
np
.
load
(
os
.
path
.
join
(
self
.
data_root
,
info
[
'occ_gt_path'
]))
occ_gt
=
np
.
load
(
os
.
path
.
join
(
self
.
data_root
,
info
[
'occ_gt_path'
]))
if
show_dir
is
not
None
:
if
show_dir
is
not
None
:
if
begin
is
not
None
and
end
is
not
None
:
if
begin
is
not
None
and
end
is
not
None
:
if
index
>=
begin
and
index
<
end
:
if
index
>=
begin
and
index
<
end
:
sample_token
=
info
[
'token'
]
sample_token
=
info
[
'token'
]
save_path
=
os
.
path
.
join
(
show_dir
,
str
(
index
).
zfill
(
4
))
save_path
=
os
.
path
.
join
(
show_dir
,
str
(
index
).
zfill
(
4
))
np
.
savez_compressed
(
save_path
,
pred
=
occ_pred
,
gt
=
occ_gt
,
sample_token
=
sample_token
)
np
.
savez_compressed
(
save_path
,
pred
=
occ_pred
,
gt
=
occ_gt
,
sample_token
=
sample_token
)
else
:
else
:
sample_token
=
info
[
'token'
]
sample_token
=
info
[
'token'
]
save_path
=
os
.
path
.
join
(
show_dir
,
str
(
index
).
zfill
(
4
))
save_path
=
os
.
path
.
join
(
show_dir
,
str
(
index
).
zfill
(
4
))
np
.
savez_compressed
(
save_path
,
pred
=
occ_pred
,
gt
=
occ_gt
,
sample_token
=
sample_token
)
np
.
savez_compressed
(
save_path
,
pred
=
occ_pred
,
gt
=
occ_gt
,
sample_token
=
sample_token
)
gt_semantics
=
occ_gt
[
'semantics'
]
gt_semantics
=
occ_gt
[
'semantics'
]
mask_lidar
=
occ_gt
[
'mask_lidar'
].
astype
(
bool
)
mask_lidar
=
occ_gt
[
'mask_lidar'
].
astype
(
bool
)
...
@@ -254,6 +250,3 @@ class NuSceneOcc(NuScenesDataset):
...
@@ -254,6 +250,3 @@ class NuSceneOcc(NuScenesDataset):
self
.
occ_eval_metrics
.
count_miou
()
self
.
occ_eval_metrics
.
count_miou
()
if
self
.
eval_fscore
:
if
self
.
eval_fscore
:
self
.
fscore_eval_metrics
.
count_fscore
()
self
.
fscore_eval_metrics
.
count_fscore
()
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/datasets/nuscnes_eval.py
View file @
41b18fd8
...
@@ -3,74 +3,42 @@ import copy
...
@@ -3,74 +3,42 @@ import copy
import
json
import
json
import
os
import
os
import
time
import
time
from
typing
import
Tuple
,
Dict
,
Any
from
typing
import
Any
,
Dict
,
Tuple
import
torch
import
numpy
as
np
import
numpy
as
np
import
tqdm
from
matplotlib
import
pyplot
as
plt
from
nuscenes
import
NuScenes
from
nuscenes
import
NuScenes
from
nuscenes.eval.common.config
import
config_factory
from
nuscenes.eval.common.config
import
config_factory
from
nuscenes.eval.common.data_classes
import
EvalBoxes
from
nuscenes.eval.common.data_classes
import
EvalBoxes
from
nuscenes.eval.detection.data_classes
import
DetectionConfig
from
nuscenes.eval.common.loaders
import
(
add_center_dist
,
filter_eval_boxes
,
load_gt
,
load_prediction
)
from
nuscenes.eval.common.render
import
setup_axis
from
nuscenes.eval.detection.algo
import
accumulate
,
calc_ap
,
calc_tp
from
nuscenes.eval.detection.constants
import
(
DETECTION_NAMES
,
PRETTY_DETECTION_NAMES
,
PRETTY_TP_METRICS
,
TP_METRICS
,
TP_METRICS_UNITS
)
from
nuscenes.eval.detection.data_classes
import
(
DetectionBox
,
DetectionConfig
,
DetectionMetricDataList
,
DetectionMetrics
)
from
nuscenes.eval.detection.evaluate
import
NuScenesEval
from
nuscenes.eval.detection.evaluate
import
NuScenesEval
from
pyquaternion
import
Quaternion
from
nuscenes.eval.detection.render
import
(
class_pr_curve
,
dist_pr_curve
,
summary_plot
)
from
nuscenes
import
NuScenes
from
nuscenes.eval.common.data_classes
import
EvalBoxes
from
nuscenes.eval.detection.data_classes
import
DetectionBox
from
nuscenes.eval.detection.utils
import
category_to_detection_name
from
nuscenes.eval.detection.utils
import
category_to_detection_name
from
nuscenes.eval.tracking.data_classes
import
TrackingBox
from
nuscenes.eval.tracking.data_classes
import
TrackingBox
from
nuscenes.utils.data_classes
import
Box
from
nuscenes.utils.data_classes
import
Box
from
nuscenes.utils.geometry_utils
import
points_in_box
from
nuscenes.utils.geometry_utils
import
(
BoxVisibility
,
transform_matrix
,
view_points
)
from
nuscenes.utils.splits
import
create_splits_scenes
from
nuscenes.utils.splits
import
create_splits_scenes
from
nuscenes.eval.common.loaders
import
load_prediction
,
add_center_dist
,
filter_eval_boxes
from
pyquaternion
import
Quaternion
import
tqdm
from
nuscenes.utils.geometry_utils
import
view_points
,
box_in_image
,
BoxVisibility
,
transform_matrix
from
torchvision.transforms.functional
import
rotate
import
pycocotools.mask
as
mask_util
# from projects.mmdet3d_plugin.models.utils.visual import save_tensor
from
torchvision.transforms.functional
import
rotate
import
cv2
import
argparse
import
json
import
os
import
random
import
time
from
typing
import
Tuple
,
Dict
,
Any
import
numpy
as
np
from
nuscenes
import
NuScenes
from
nuscenes.eval.common.config
import
config_factory
from
nuscenes.eval.common.data_classes
import
EvalBoxes
from
nuscenes.eval.common.loaders
import
load_prediction
,
load_gt
,
add_center_dist
,
filter_eval_boxes
from
nuscenes.eval.detection.algo
import
accumulate
,
calc_ap
,
calc_tp
from
nuscenes.eval.detection.constants
import
TP_METRICS
from
nuscenes.eval.detection.data_classes
import
DetectionConfig
,
DetectionMetrics
,
DetectionBox
,
\
DetectionMetricDataList
from
nuscenes.eval.detection.render
import
summary_plot
,
class_pr_curve
,
dist_pr_curve
,
visualize_sample
from
nuscenes.eval.common.utils
import
quaternion_yaw
,
Quaternion
from
mmdet3d.core.bbox.iou_calculators
import
BboxOverlaps3D
from
IPython
import
embed
import
json
from
typing
import
Any
import
numpy
as
np
from
matplotlib
import
pyplot
as
plt
from
nuscenes
import
NuScenes
from
nuscenes.eval.common.data_classes
import
EvalBoxes
from
nuscenes.eval.common.render
import
setup_axis
from
nuscenes.eval.common.utils
import
boxes_to_sensor
from
nuscenes.eval.detection.constants
import
TP_METRICS
,
DETECTION_NAMES
,
DETECTION_COLORS
,
TP_METRICS_UNITS
,
\
PRETTY_DETECTION_NAMES
,
PRETTY_TP_METRICS
from
nuscenes.eval.detection.data_classes
import
DetectionMetrics
,
DetectionMetricData
,
DetectionMetricDataList
from
nuscenes.utils.data_classes
import
LidarPointCloud
from
nuscenes.utils.geometry_utils
import
view_points
# from projects.mmdet3d_plugin.models.utils.visual import save_tensor
Axis
=
Any
Axis
=
Any
def
class_tp_curve
(
md_list
:
DetectionMetricDataList
,
def
class_tp_curve
(
md_list
:
DetectionMetricDataList
,
metrics
:
DetectionMetrics
,
metrics
:
DetectionMetrics
,
detection_name
:
str
,
detection_name
:
str
,
...
@@ -124,7 +92,7 @@ def class_tp_curve(md_list: DetectionMetricDataList,
...
@@ -124,7 +92,7 @@ def class_tp_curve(md_list: DetectionMetricDataList,
label
=
'{}: {:.2f} ({})'
.
format
(
PRETTY_TP_METRICS
[
metric
],
tp
,
TP_METRICS_UNITS
[
metric
])
label
=
'{}: {:.2f} ({})'
.
format
(
PRETTY_TP_METRICS
[
metric
],
tp
,
TP_METRICS_UNITS
[
metric
])
if
metric
==
'trans_err'
:
if
metric
==
'trans_err'
:
label
+=
f
' (
{
md
.
max_recall_ind
}
)'
# add recall
label
+=
f
' (
{
md
.
max_recall_ind
}
)'
# add recall
print
(
f
'Recall:
{
detection_name
}
:
{
md
.
max_recall_ind
/
100
}
'
)
print
(
f
'Recall:
{
detection_name
}
:
{
md
.
max_recall_ind
/
100
}
'
)
ax
.
plot
(
recall
,
error
,
label
=
label
)
ax
.
plot
(
recall
,
error
,
label
=
label
)
ax
.
axvline
(
x
=
md
.
max_recall
,
linestyle
=
'-.'
,
color
=
(
0
,
0
,
0
,
0.3
))
ax
.
axvline
(
x
=
md
.
max_recall
,
linestyle
=
'-.'
,
color
=
(
0
,
0
,
0
,
0.3
))
ax
.
legend
(
loc
=
'best'
)
ax
.
legend
(
loc
=
'best'
)
...
@@ -211,7 +179,7 @@ def center_in_image(box, intrinsic: np.ndarray, imsize: Tuple[int, int], vis_lev
...
@@ -211,7 +179,7 @@ def center_in_image(box, intrinsic: np.ndarray, imsize: Tuple[int, int], vis_lev
elif
vis_level
==
BoxVisibility
.
NONE
:
elif
vis_level
==
BoxVisibility
.
NONE
:
return
True
return
True
else
:
else
:
raise
ValueError
(
"
vis_level: {} not valid
"
.
format
(
vis_level
))
raise
ValueError
(
'
vis_level: {} not valid
'
.
format
(
vis_level
))
def
exist_corners_in_image_but_not_all
(
box
,
intrinsic
:
np
.
ndarray
,
imsize
:
Tuple
[
int
,
int
],
def
exist_corners_in_image_but_not_all
(
box
,
intrinsic
:
np
.
ndarray
,
imsize
:
Tuple
[
int
,
int
],
...
@@ -259,7 +227,7 @@ def load_gt(nusc: NuScenes, eval_split: str, box_cls, verbose: bool = False):
...
@@ -259,7 +227,7 @@ def load_gt(nusc: NuScenes, eval_split: str, box_cls, verbose: bool = False):
print
(
'Loading annotations for {} split from nuScenes version: {}'
.
format
(
eval_split
,
nusc
.
version
))
print
(
'Loading annotations for {} split from nuScenes version: {}'
.
format
(
eval_split
,
nusc
.
version
))
# Read out all sample_tokens in DB.
# Read out all sample_tokens in DB.
sample_tokens_all
=
[
s
[
'token'
]
for
s
in
nusc
.
sample
]
sample_tokens_all
=
[
s
[
'token'
]
for
s
in
nusc
.
sample
]
assert
len
(
sample_tokens_all
)
>
0
,
"
Error: Database has no samples!
"
assert
len
(
sample_tokens_all
)
>
0
,
'
Error: Database has no samples!
'
# Only keep samples from this split.
# Only keep samples from this split.
splits
=
create_splits_scenes
()
splits
=
create_splits_scenes
()
...
@@ -354,7 +322,7 @@ def load_gt(nusc: NuScenes, eval_split: str, box_cls, verbose: bool = False):
...
@@ -354,7 +322,7 @@ def load_gt(nusc: NuScenes, eval_split: str, box_cls, verbose: bool = False):
all_annotations
.
add_boxes
(
sample_token
,
sample_boxes
)
all_annotations
.
add_boxes
(
sample_token
,
sample_boxes
)
if
verbose
:
if
verbose
:
print
(
"
Loaded ground truth annotations for {} samples.
"
.
format
(
len
(
all_annotations
.
sample_tokens
)))
print
(
'
Loaded ground truth annotations for {} samples.
'
.
format
(
len
(
all_annotations
.
sample_tokens
)))
return
all_annotations
return
all_annotations
...
@@ -385,8 +353,8 @@ def filter_eval_boxes_by_id(nusc: NuScenes,
...
@@ -385,8 +353,8 @@ def filter_eval_boxes_by_id(nusc: NuScenes,
eval_boxes
.
boxes
[
sample_token
]
=
filtered_boxes
eval_boxes
.
boxes
[
sample_token
]
=
filtered_boxes
if
verbose
:
if
verbose
:
print
(
"
=> Original number of boxes: %d
"
%
total
)
print
(
'
=> Original number of boxes: %d
'
%
total
)
print
(
"
=> After anns based filtering: %d
"
%
anns_filter
)
print
(
'
=> After anns based filtering: %d
'
%
anns_filter
)
return
eval_boxes
return
eval_boxes
...
@@ -417,13 +385,13 @@ def filter_eval_boxes_by_visibility(
...
@@ -417,13 +385,13 @@ def filter_eval_boxes_by_visibility(
eval_boxes
.
boxes
[
sample_token
]
=
filtered_boxes
eval_boxes
.
boxes
[
sample_token
]
=
filtered_boxes
if
verbose
:
if
verbose
:
print
(
"
=> Original number of boxes: %d
"
%
total
)
print
(
'
=> Original number of boxes: %d
'
%
total
)
print
(
"
=> After visibility based filtering: %d
"
%
anns_filter
)
print
(
'
=> After visibility based filtering: %d
'
%
anns_filter
)
return
eval_boxes
return
eval_boxes
def
filter_by_sample_token
(
ori_eval_boxes
,
valid_sample_tokens
=
[],
verbose
=
False
):
def
filter_by_sample_token
(
ori_eval_boxes
,
valid_sample_tokens
=
[],
verbose
=
False
):
eval_boxes
=
copy
.
deepcopy
(
ori_eval_boxes
)
eval_boxes
=
copy
.
deepcopy
(
ori_eval_boxes
)
for
sample_token
in
eval_boxes
.
sample_tokens
:
for
sample_token
in
eval_boxes
.
sample_tokens
:
if
sample_token
not
in
valid_sample_tokens
:
if
sample_token
not
in
valid_sample_tokens
:
...
@@ -498,8 +466,8 @@ def filter_eval_boxes_by_overlap(nusc: NuScenes,
...
@@ -498,8 +466,8 @@ def filter_eval_boxes_by_overlap(nusc: NuScenes,
verbose
=
True
verbose
=
True
if
verbose
:
if
verbose
:
print
(
"
=> Original number of boxes: %d
"
%
total
)
print
(
'
=> Original number of boxes: %d
'
%
total
)
print
(
"
=> After anns based filtering: %d
"
%
anns_filter
)
print
(
'
=> After anns based filtering: %d
'
%
anns_filter
)
return
eval_boxes
return
eval_boxes
...
@@ -620,7 +588,6 @@ class NuScenesEval_custom(NuScenesEval):
...
@@ -620,7 +588,6 @@ class NuScenesEval_custom(NuScenesEval):
self
.
pred_boxes
=
filter_by_sample_token
(
self
.
all_preds
,
valid_tokens
)
self
.
pred_boxes
=
filter_by_sample_token
(
self
.
all_preds
,
valid_tokens
)
self
.
sample_tokens
=
self
.
gt_boxes
.
sample_tokens
self
.
sample_tokens
=
self
.
gt_boxes
.
sample_tokens
def
evaluate
(
self
)
->
Tuple
[
DetectionMetrics
,
DetectionMetricDataList
]:
def
evaluate
(
self
)
->
Tuple
[
DetectionMetrics
,
DetectionMetricDataList
]:
"""
"""
Performs the actual evaluation.
Performs the actual evaluation.
...
@@ -698,7 +665,7 @@ class NuScenesEval_custom(NuScenesEval):
...
@@ -698,7 +665,7 @@ class NuScenesEval_custom(NuScenesEval):
savepath
=
savepath
(
'dist_pr_'
+
str
(
dist_th
)))
savepath
=
savepath
(
'dist_pr_'
+
str
(
dist_th
)))
if
__name__
==
"
__main__
"
:
if
__name__
==
'
__main__
'
:
# Settings.
# Settings.
parser
=
argparse
.
ArgumentParser
(
description
=
'Evaluate nuScenes detection results.'
,
parser
=
argparse
.
ArgumentParser
(
description
=
'Evaluate nuScenes detection results.'
,
...
@@ -746,6 +713,6 @@ if __name__ == "__main__":
...
@@ -746,6 +713,6 @@ if __name__ == "__main__":
nusc_eval
.
update_gt
(
type_
=
'vis'
,
visibility
=
vis
)
nusc_eval
.
update_gt
(
type_
=
'vis'
,
visibility
=
vis
)
print
(
f
'================
{
vis
}
==============='
)
print
(
f
'================
{
vis
}
==============='
)
nusc_eval
.
main
(
plot_examples
=
plot_examples_
,
render_curves
=
render_curves_
)
nusc_eval
.
main
(
plot_examples
=
plot_examples_
,
render_curves
=
render_curves_
)
#for index in range(1, 41):
#
for index in range(1, 41):
# nusc_eval.update_gt(type_='ord', index=index)
# nusc_eval.update_gt(type_='ord', index=index)
#
#
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/datasets/occ_metrics.py
View file @
41b18fd8
import
numpy
as
np
import
os
import
os
from
functools
import
reduce
from
pathlib
import
Path
from
tqdm
import
tqdm
import
numpy
as
np
import
pickle
as
pkl
from
sklearn.neighbors
import
KDTree
import
argparse
from
termcolor
import
colored
import
time
import
torch
np
.
seterr
(
divide
=
'ignore'
,
invalid
=
'ignore'
)
import
sys
,
platform
os
.
environ
[
'KMP_DUPLICATE_LIB_OK'
]
=
'TRUE'
from
sklearn.neighbors
import
KDTree
from
termcolor
import
colored
from
pathlib
import
Path
def
pcolor
(
string
,
color
,
on_color
=
None
,
attrs
=
None
):
from
copy
import
deepcopy
"""
from
functools
import
reduce
Produces a colored string for printing
np
.
seterr
(
divide
=
'ignore'
,
invalid
=
'ignore'
)
Parameters
os
.
environ
[
"KMP_DUPLICATE_LIB_OK"
]
=
"TRUE"
----------
string : str
String that will be colored
def
pcolor
(
string
,
color
,
on_color
=
None
,
attrs
=
None
):
color : str
"""
Color to use
Produces a colored string for printing
on_color : str
Background color to use
Parameters
attrs : list of str
----------
Different attributes for the string
string : str
String that will be colored
Returns
color : str
-------
Color to use
string: str
on_color : str
Colored string
Background color to use
"""
attrs : list of str
return
colored
(
string
,
color
,
on_color
,
attrs
)
Different attributes for the string
Returns
def
getCellCoordinates
(
points
,
voxelSize
):
-------
return
(
points
/
voxelSize
).
astype
(
np
.
int
)
string: str
Colored string
"""
def
getNumUniqueCells
(
cells
):
return
colored
(
string
,
color
,
on_color
,
attrs
)
M
=
cells
.
max
()
+
1
return
np
.
unique
(
cells
[:,
0
]
+
M
*
cells
[:,
1
]
+
M
**
2
*
cells
[:,
2
]).
shape
[
0
]
def
getCellCoordinates
(
points
,
voxelSize
):
return
(
points
/
voxelSize
).
astype
(
np
.
int
)
class
Metric_mIoU
():
def
__init__
(
self
,
save_dir
=
'.'
,
def
getNumUniqueCells
(
cells
):
num_classes
=
18
,
M
=
cells
.
max
()
+
1
use_lidar_mask
=
False
,
return
np
.
unique
(
cells
[:,
0
]
+
M
*
cells
[:,
1
]
+
M
**
2
*
cells
[:,
2
]).
shape
[
0
]
use_image_mask
=
False
,
):
self
.
class_names
=
[
'others'
,
'barrier'
,
'bicycle'
,
'bus'
,
'car'
,
'construction_vehicle'
,
class
Metric_mIoU
():
'motorcycle'
,
'pedestrian'
,
'traffic_cone'
,
'trailer'
,
'truck'
,
def
__init__
(
self
,
'driveable_surface'
,
'other_flat'
,
'sidewalk'
,
save_dir
=
'.'
,
'terrain'
,
'manmade'
,
'vegetation'
,
'free'
]
num_classes
=
18
,
self
.
save_dir
=
save_dir
use_lidar_mask
=
False
,
self
.
use_lidar_mask
=
use_lidar_mask
use_image_mask
=
False
,
self
.
use_image_mask
=
use_image_mask
):
self
.
num_classes
=
num_classes
self
.
class_names
=
[
'others'
,
'barrier'
,
'bicycle'
,
'bus'
,
'car'
,
'construction_vehicle'
,
'motorcycle'
,
'pedestrian'
,
'traffic_cone'
,
'trailer'
,
'truck'
,
self
.
point_cloud_range
=
[
-
40.0
,
-
40.0
,
-
1.0
,
40.0
,
40.0
,
5.4
]
'driveable_surface'
,
'other_flat'
,
'sidewalk'
,
self
.
occupancy_size
=
[
0.4
,
0.4
,
0.4
]
'terrain'
,
'manmade'
,
'vegetation'
,
'free'
]
self
.
voxel_size
=
0.4
self
.
save_dir
=
save_dir
self
.
occ_xdim
=
int
((
self
.
point_cloud_range
[
3
]
-
self
.
point_cloud_range
[
0
])
/
self
.
occupancy_size
[
0
])
self
.
use_lidar_mask
=
use_lidar_mask
self
.
occ_ydim
=
int
((
self
.
point_cloud_range
[
4
]
-
self
.
point_cloud_range
[
1
])
/
self
.
occupancy_size
[
1
])
self
.
use_image_mask
=
use_image_mask
self
.
occ_zdim
=
int
((
self
.
point_cloud_range
[
5
]
-
self
.
point_cloud_range
[
2
])
/
self
.
occupancy_size
[
2
])
self
.
num_classes
=
num_classes
self
.
voxel_num
=
self
.
occ_xdim
*
self
.
occ_ydim
*
self
.
occ_zdim
self
.
hist
=
np
.
zeros
((
self
.
num_classes
,
self
.
num_classes
))
self
.
point_cloud_range
=
[
-
40.0
,
-
40.0
,
-
1.0
,
40.0
,
40.0
,
5.4
]
self
.
cnt
=
0
self
.
occupancy_size
=
[
0.4
,
0.4
,
0.4
]
self
.
voxel_size
=
0.4
def
hist_info
(
self
,
n_cl
,
pred
,
gt
):
self
.
occ_xdim
=
int
((
self
.
point_cloud_range
[
3
]
-
self
.
point_cloud_range
[
0
])
/
self
.
occupancy_size
[
0
])
"""
self
.
occ_ydim
=
int
((
self
.
point_cloud_range
[
4
]
-
self
.
point_cloud_range
[
1
])
/
self
.
occupancy_size
[
1
])
build confusion matrix
self
.
occ_zdim
=
int
((
self
.
point_cloud_range
[
5
]
-
self
.
point_cloud_range
[
2
])
/
self
.
occupancy_size
[
2
])
# empty classes:0
self
.
voxel_num
=
self
.
occ_xdim
*
self
.
occ_ydim
*
self
.
occ_zdim
non-empty class: 0-16
self
.
hist
=
np
.
zeros
((
self
.
num_classes
,
self
.
num_classes
))
free voxel class: 17
self
.
cnt
=
0
Args:
def
hist_info
(
self
,
n_cl
,
pred
,
gt
):
n_cl (int): num_classes_occupancy
"""
pred (1-d array): pred_occupancy_label
build confusion matrix
gt (1-d array): gt_occupancu_label
# empty classes:0
non-empty class: 0-16
Returns:
free voxel class: 17
tuple:(hist, correctly number_predicted_labels, num_labelled_sample)
"""
Args:
assert
pred
.
shape
==
gt
.
shape
n_cl (int): num_classes_occupancy
k
=
(
gt
>=
0
)
&
(
gt
<
n_cl
)
# exclude 255
pred (1-d array): pred_occupancy_label
labeled
=
np
.
sum
(
k
)
gt (1-d array): gt_occupancu_label
correct
=
np
.
sum
((
pred
[
k
]
==
gt
[
k
]))
Returns:
return
(
tuple:(hist, correctly number_predicted_labels, num_labelled_sample)
np
.
bincount
(
"""
n_cl
*
gt
[
k
].
astype
(
int
)
+
pred
[
k
].
astype
(
int
),
minlength
=
n_cl
**
2
assert
pred
.
shape
==
gt
.
shape
).
reshape
(
n_cl
,
n_cl
),
k
=
(
gt
>=
0
)
&
(
gt
<
n_cl
)
# exclude 255
correct
,
labeled
=
np
.
sum
(
k
)
labeled
,
correct
=
np
.
sum
((
pred
[
k
]
==
gt
[
k
]))
)
return
(
def
per_class_iu
(
self
,
hist
):
np
.
bincount
(
n_cl
*
gt
[
k
].
astype
(
int
)
+
pred
[
k
].
astype
(
int
),
minlength
=
n_cl
**
2
return
np
.
diag
(
hist
)
/
(
hist
.
sum
(
1
)
+
hist
.
sum
(
0
)
-
np
.
diag
(
hist
))
).
reshape
(
n_cl
,
n_cl
),
correct
,
def
compute_mIoU
(
self
,
pred
,
label
,
n_classes
):
labeled
,
hist
=
np
.
zeros
((
n_classes
,
n_classes
))
)
new_hist
,
correct
,
labeled
=
self
.
hist_info
(
n_classes
,
pred
.
flatten
(),
label
.
flatten
())
hist
+=
new_hist
def
per_class_iu
(
self
,
hist
):
mIoUs
=
self
.
per_class_iu
(
hist
)
# for ind_class in range(n_classes):
return
np
.
diag
(
hist
)
/
(
hist
.
sum
(
1
)
+
hist
.
sum
(
0
)
-
np
.
diag
(
hist
))
# print(str(round(mIoUs[ind_class] * 100, 2)))
# print('===> mIoU: ' + str(round(np.nanmean(mIoUs) * 100, 2)))
def
compute_mIoU
(
self
,
pred
,
label
,
n_classes
):
return
round
(
np
.
nanmean
(
mIoUs
)
*
100
,
2
),
hist
hist
=
np
.
zeros
((
n_classes
,
n_classes
))
new_hist
,
correct
,
labeled
=
self
.
hist_info
(
n_classes
,
pred
.
flatten
(),
label
.
flatten
())
def
add_batch
(
self
,
semantics_pred
,
semantics_gt
,
mask_lidar
,
mask_camera
):
hist
+=
new_hist
self
.
cnt
+=
1
mIoUs
=
self
.
per_class_iu
(
hist
)
if
self
.
use_image_mask
:
# for ind_class in range(n_classes):
masked_semantics_gt
=
semantics_gt
[
mask_camera
]
# print(str(round(mIoUs[ind_class] * 100, 2)))
masked_semantics_pred
=
semantics_pred
[
mask_camera
]
# print('===> mIoU: ' + str(round(np.nanmean(mIoUs) * 100, 2)))
elif
self
.
use_lidar_mask
:
return
round
(
np
.
nanmean
(
mIoUs
)
*
100
,
2
),
hist
masked_semantics_gt
=
semantics_gt
[
mask_lidar
]
masked_semantics_pred
=
semantics_pred
[
mask_lidar
]
else
:
def
add_batch
(
self
,
semantics_pred
,
semantics_gt
,
mask_lidar
,
mask_camera
):
masked_semantics_gt
=
semantics_gt
self
.
cnt
+=
1
masked_semantics_pred
=
semantics_pred
if
self
.
use_image_mask
:
masked_semantics_gt
=
semantics_gt
[
mask_camera
]
# # pred = np.random.randint(low=0, high=17, size=masked_semantics.shape)
masked_semantics_pred
=
semantics_pred
[
mask_camera
]
_
,
_hist
=
self
.
compute_mIoU
(
masked_semantics_pred
,
masked_semantics_gt
,
self
.
num_classes
)
elif
self
.
use_lidar_mask
:
self
.
hist
+=
_hist
masked_semantics_gt
=
semantics_gt
[
mask_lidar
]
masked_semantics_pred
=
semantics_pred
[
mask_lidar
]
def
count_miou
(
self
):
else
:
mIoU
=
self
.
per_class_iu
(
self
.
hist
)
masked_semantics_gt
=
semantics_gt
# assert cnt == num_samples, 'some samples are not included in the miou calculation'
masked_semantics_pred
=
semantics_pred
print
(
f
'===> per class IoU of
{
self
.
cnt
}
samples:'
)
for
ind_class
in
range
(
self
.
num_classes
-
1
):
# # pred = np.random.randint(low=0, high=17, size=masked_semantics.shape)
print
(
f
'===>
{
self
.
class_names
[
ind_class
]
}
- IoU = '
+
str
(
round
(
mIoU
[
ind_class
]
*
100
,
2
)))
_
,
_hist
=
self
.
compute_mIoU
(
masked_semantics_pred
,
masked_semantics_gt
,
self
.
num_classes
)
self
.
hist
+=
_hist
print
(
f
'===> mIoU of
{
self
.
cnt
}
samples: '
+
str
(
round
(
np
.
nanmean
(
mIoU
[:
self
.
num_classes
-
1
])
*
100
,
2
)))
# print(f'===> sample-wise averaged mIoU of {cnt} samples: ' + str(round(np.nanmean(mIoU_avg), 2)))
def
count_miou
(
self
):
mIoU
=
self
.
per_class_iu
(
self
.
hist
)
# return mIoU
# assert cnt == num_samples, 'some samples are not included in the miou calculation'
print
(
f
'===> per class IoU of
{
self
.
cnt
}
samples:'
)
for
ind_class
in
range
(
self
.
num_classes
-
1
):
class
Metric_FScore
():
print
(
f
'===>
{
self
.
class_names
[
ind_class
]
}
- IoU = '
+
str
(
round
(
mIoU
[
ind_class
]
*
100
,
2
)))
def
__init__
(
self
,
print
(
f
'===> mIoU of
{
self
.
cnt
}
samples: '
+
str
(
round
(
np
.
nanmean
(
mIoU
[:
self
.
num_classes
-
1
])
*
100
,
2
)))
leaf_size
=
10
,
# print(f'===> sample-wise averaged mIoU of {cnt} samples: ' + str(round(np.nanmean(mIoU_avg), 2)))
threshold_acc
=
0.6
,
threshold_complete
=
0.6
,
# return mIoU
voxel_size
=
[
0.4
,
0.4
,
0.4
],
range
=
[
-
40
,
-
40
,
-
1
,
40
,
40
,
5.4
],
void
=
[
17
,
255
],
class
Metric_FScore
():
use_lidar_mask
=
False
,
def
__init__
(
self
,
use_image_mask
=
False
,
)
->
None
:
leaf_size
=
10
,
self
.
leaf_size
=
leaf_size
threshold_acc
=
0.6
,
self
.
threshold_acc
=
threshold_acc
threshold_complete
=
0.6
,
self
.
threshold_complete
=
threshold_complete
voxel_size
=
[
0.4
,
0.4
,
0.4
],
self
.
voxel_size
=
voxel_size
range
=
[
-
40
,
-
40
,
-
1
,
40
,
40
,
5.4
],
self
.
range
=
range
void
=
[
17
,
255
],
self
.
void
=
void
use_lidar_mask
=
False
,
self
.
use_lidar_mask
=
use_lidar_mask
use_image_mask
=
False
,
)
->
None
:
self
.
use_image_mask
=
use_image_mask
self
.
cnt
=
0
self
.
leaf_size
=
leaf_size
self
.
tot_acc
=
0.
self
.
threshold_acc
=
threshold_acc
self
.
tot_cmpl
=
0.
self
.
threshold_complete
=
threshold_complete
self
.
tot_f1_mean
=
0.
self
.
voxel_size
=
voxel_size
self
.
eps
=
1e-8
self
.
range
=
range
self
.
void
=
void
def
voxel2points
(
self
,
voxel
):
self
.
use_lidar_mask
=
use_lidar_mask
# occIdx = torch.where(torch.logical_and(voxel != FREE, voxel != NOT_OBSERVED))
self
.
use_image_mask
=
use_image_mask
# if isinstance(voxel, np.ndarray): voxel = torch.from_numpy(voxel)
self
.
cnt
=
0
mask
=
np
.
logical_not
(
reduce
(
np
.
logical_or
,
[
voxel
==
self
.
void
[
i
]
for
i
in
range
(
len
(
self
.
void
))]))
self
.
tot_acc
=
0.
occIdx
=
np
.
where
(
mask
)
self
.
tot_cmpl
=
0.
self
.
tot_f1_mean
=
0.
points
=
np
.
concatenate
((
occIdx
[
0
][:,
None
]
*
self
.
voxel_size
[
0
]
+
self
.
voxel_size
[
0
]
/
2
+
self
.
range
[
0
],
\
self
.
eps
=
1e-8
occIdx
[
1
][:,
None
]
*
self
.
voxel_size
[
1
]
+
self
.
voxel_size
[
1
]
/
2
+
self
.
range
[
1
],
\
occIdx
[
2
][:,
None
]
*
self
.
voxel_size
[
2
]
+
self
.
voxel_size
[
2
]
/
2
+
self
.
range
[
2
]),
axis
=
1
)
return
points
def
voxel2points
(
self
,
voxel
):
# occIdx = torch.where(torch.logical_and(voxel != FREE, voxel != NOT_OBSERVED))
def
add_batch
(
self
,
semantics_pred
,
semantics_gt
,
mask_lidar
,
mask_camera
):
# if isinstance(voxel, np.ndarray): voxel = torch.from_numpy(voxel)
mask
=
np
.
logical_not
(
reduce
(
np
.
logical_or
,
[
voxel
==
self
.
void
[
i
]
for
i
in
range
(
len
(
self
.
void
))]))
# for scene_token in tqdm(preds_dict.keys()):
occIdx
=
np
.
where
(
mask
)
self
.
cnt
+=
1
points
=
np
.
concatenate
((
occIdx
[
0
][:,
None
]
*
self
.
voxel_size
[
0
]
+
self
.
voxel_size
[
0
]
/
2
+
self
.
range
[
0
],
\
if
self
.
use_image_mask
:
occIdx
[
1
][:,
None
]
*
self
.
voxel_size
[
1
]
+
self
.
voxel_size
[
1
]
/
2
+
self
.
range
[
1
],
\
semantics_gt
[
mask_camera
==
False
]
=
255
occIdx
[
2
][:,
None
]
*
self
.
voxel_size
[
2
]
+
self
.
voxel_size
[
2
]
/
2
+
self
.
range
[
2
]),
semantics_pred
[
mask_camera
==
False
]
=
255
axis
=
1
)
elif
self
.
use_lidar_mask
:
return
points
semantics_gt
[
mask_lidar
==
False
]
=
255
semantics_pred
[
mask_lidar
==
False
]
=
255
def
add_batch
(
self
,
semantics_pred
,
semantics_gt
,
mask_lidar
,
mask_camera
):
else
:
pass
# for scene_token in tqdm(preds_dict.keys()):
self
.
cnt
+=
1
ground_truth
=
self
.
voxel2points
(
semantics_gt
)
prediction
=
self
.
voxel2points
(
semantics_pred
)
if
self
.
use_image_mask
:
if
prediction
.
shape
[
0
]
==
0
:
accuracy
=
0
semantics_gt
[
mask_camera
==
False
]
=
255
completeness
=
0
semantics_pred
[
mask_camera
==
False
]
=
255
fmean
=
0
elif
self
.
use_lidar_mask
:
semantics_gt
[
mask_lidar
==
False
]
=
255
else
:
semantics_pred
[
mask_lidar
==
False
]
=
255
prediction_tree
=
KDTree
(
prediction
,
leaf_size
=
self
.
leaf_size
)
else
:
ground_truth_tree
=
KDTree
(
ground_truth
,
leaf_size
=
self
.
leaf_size
)
pass
complete_distance
,
_
=
prediction_tree
.
query
(
ground_truth
)
complete_distance
=
complete_distance
.
flatten
()
ground_truth
=
self
.
voxel2points
(
semantics_gt
)
prediction
=
self
.
voxel2points
(
semantics_pred
)
accuracy_distance
,
_
=
ground_truth_tree
.
query
(
prediction
)
if
prediction
.
shape
[
0
]
==
0
:
accuracy_distance
=
accuracy_distance
.
flatten
()
accuracy
=
0
completeness
=
0
# evaluate completeness
fmean
=
0
complete_mask
=
complete_distance
<
self
.
threshold_complete
completeness
=
complete_mask
.
mean
()
else
:
prediction_tree
=
KDTree
(
prediction
,
leaf_size
=
self
.
leaf_size
)
# evalute accuracy
ground_truth_tree
=
KDTree
(
ground_truth
,
leaf_size
=
self
.
leaf_size
)
accuracy_mask
=
accuracy_distance
<
self
.
threshold_acc
complete_distance
,
_
=
prediction_tree
.
query
(
ground_truth
)
accuracy
=
accuracy_mask
.
mean
()
complete_distance
=
complete_distance
.
flatten
()
fmean
=
2.0
/
(
1
/
(
accuracy
+
self
.
eps
)
+
1
/
(
completeness
+
self
.
eps
))
accuracy_distance
,
_
=
ground_truth_tree
.
query
(
prediction
)
accuracy_distance
=
accuracy_distance
.
flatten
()
self
.
tot_acc
+=
accuracy
self
.
tot_cmpl
+=
completeness
# evaluate completeness
self
.
tot_f1_mean
+=
fmean
complete_mask
=
complete_distance
<
self
.
threshold_complete
completeness
=
complete_mask
.
mean
()
def
count_fscore
(
self
,
):
base_color
,
attrs
=
'red'
,
[
'bold'
,
'dark'
]
# evalute accuracy
print
(
pcolor
(
'
\n
######## F score: {} #######'
.
format
(
self
.
tot_f1_mean
/
self
.
cnt
),
base_color
,
attrs
=
attrs
))
accuracy_mask
=
accuracy_distance
<
self
.
threshold_acc
accuracy
=
accuracy_mask
.
mean
()
fmean
=
2.0
/
(
1
/
(
accuracy
+
self
.
eps
)
+
1
/
(
completeness
+
self
.
eps
))
self
.
tot_acc
+=
accuracy
self
.
tot_cmpl
+=
completeness
self
.
tot_f1_mean
+=
fmean
def
count_fscore
(
self
,):
base_color
,
attrs
=
'red'
,
[
'bold'
,
'dark'
]
print
(
pcolor
(
'
\n
######## F score: {} #######'
.
format
(
self
.
tot_f1_mean
/
self
.
cnt
),
base_color
,
attrs
=
attrs
))
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/datasets/pipelines/__init__.py
View file @
41b18fd8
from
.transform_3d
import
(
PadMultiViewImage
,
NormalizeMultiviewImage
,
PhotoMetricDistortionMultiViewImage
,
CustomCollect3D
,
RandomScaleImageMultiViewImage
)
from
.formating
import
CustomDefaultFormatBundle3D
from
.formating
import
CustomDefaultFormatBundle3D
from
.loading
import
LoadOccGTFromFile
from
.loading
import
LoadOccGTFromFile
from
.transform_3d
import
(
CustomCollect3D
,
NormalizeMultiviewImage
,
PadMultiViewImage
,
PhotoMetricDistortionMultiViewImage
,
RandomScaleImageMultiViewImage
)
__all__
=
[
__all__
=
[
'PadMultiViewImage'
,
'NormalizeMultiviewImage'
,
'PadMultiViewImage'
,
'NormalizeMultiviewImage'
,
'PhotoMetricDistortionMultiViewImage'
,
'CustomDefaultFormatBundle3D'
,
'CustomCollect3D'
,
'RandomScaleImageMultiViewImage'
'PhotoMetricDistortionMultiViewImage'
,
'CustomDefaultFormatBundle3D'
,
'CustomCollect3D'
,
]
'RandomScaleImageMultiViewImage'
\ No newline at end of file
]
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/datasets/pipelines/formating.py
View file @
41b18fd8
# Copyright (c) OpenMMLab. All rights reserved.
# Copyright (c) OpenMMLab. All rights reserved.
from
mmcv.parallel
import
DataContainer
as
DC
import
numpy
as
np
from
mmdet3d.datasets.pipelines
import
DefaultFormatBundle3D
from
mmcv.parallel
import
DataContainer
as
DC
from
mmdet.datasets.builder
import
PIPELINES
from
mmdet.datasets.pipelines
import
to_tensor
from
mmdet3d.core.bbox
import
BaseInstance3DBoxes
from
mmdet3d.core.points
import
BasePoints
from
mmdet.datasets.builder
import
PIPELINES
@
PIPELINES
.
register_module
()
from
mmdet.datasets.pipelines
import
to_tensor
class
CustomDefaultFormatBundle3D
(
DefaultFormatBundle3D
):
from
mmdet3d.datasets.pipelines
import
DefaultFormatBundle3D
"""Default formatting bundle.
It simplifies the pipeline of formatting common fields for voxels,
@
PIPELINES
.
register_module
()
including "proposals", "gt_bboxes", "gt_labels", "gt_masks" and
class
CustomDefaultFormatBundle3D
(
DefaultFormatBundle3D
):
"gt_semantic_seg".
"""Default formatting bundle.
These fields are formatted as follows.
It simplifies the pipeline of formatting common fields for voxels,
- img: (1)transpose, (2)to tensor, (3)to DataContainer (stack=True)
including "proposals", "gt_bboxes", "gt_labels", "gt_masks" and
- proposals: (1)to tensor, (2)to DataContainer
"gt_semantic_seg".
- gt_bboxes: (1)to tensor, (2)to DataContainer
These fields are formatted as follows.
- gt_bboxes_ignore: (1)to tensor, (2)to DataContainer
- img: (1)transpose, (2)to tensor, (3)to DataContainer (stack=True)
- gt_labels: (1)to tensor, (2)to DataContainer
- proposals: (1)to tensor, (2)to DataContainer
"""
- gt_bboxes: (1)to tensor, (2)to DataContainer
- gt_bboxes_ignore: (1)to tensor, (2)to DataContainer
def
__call__
(
self
,
results
):
- gt_labels: (1)to tensor, (2)to DataContainer
"""Call function to transform and format common fields in results.
"""
Args:
results (dict): Result dict contains the data to convert.
def
__call__
(
self
,
results
):
Returns:
"""Call function to transform and format common fields in results.
dict: The result dict contains the data that is formatted with
Args:
default bundle.
results (dict): Result dict contains the data to convert.
"""
Returns:
# Format 3D data
dict: The result dict contains the data that is formatted with
results
=
super
(
CustomDefaultFormatBundle3D
,
self
).
__call__
(
results
)
default bundle.
results
[
'gt_map_masks'
]
=
DC
(
"""
to_tensor
(
results
[
'gt_map_masks'
]),
stack
=
True
)
# Format 3D data
results
=
super
(
CustomDefaultFormatBundle3D
,
self
).
__call__
(
results
)
return
results
results
[
'gt_map_masks'
]
=
DC
(
to_tensor
(
results
[
'gt_map_masks'
]),
stack
=
True
)
return
results
\ No newline at end of file
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/datasets/pipelines/loading.py
View file @
41b18fd8
import
numpy
as
np
import
os
from
numpy
import
random
import
mmcv
import
numpy
as
np
from
mmdet.datasets.builder
import
PIPELINES
from
mmdet.datasets.builder
import
PIPELINES
from
mmcv.parallel
import
DataContainer
as
DC
import
os
@
PIPELINES
.
register_module
()
@
PIPELINES
.
register_module
()
class
LoadOccGTFromFile
(
object
):
class
LoadOccGTFromFile
(
object
):
"""Load multi channel images from a list of separate channel files.
"""Load multi channel images from a list of separate channel files.
Expects results['img_filename'] to be a list of filenames.
Expects results['img_filename'] to be a list of filenames.
note that we read image in BGR style to align with opencv.imread
note that we read image in BGR style to align with opencv.imread
Args:
Args:
to_float32 (bool): Whether to convert the img to float32.
to_float32 (bool): Whether to convert the img to float32.
Defaults to False.
Defaults to False.
color_type (str): Color type of the file. Defaults to 'unchanged'.
color_type (str): Color type of the file. Defaults to 'unchanged'.
"""
"""
def
__init__
(
def
__init__
(
self
,
self
,
data_root
,
data_root
,
):
):
self
.
data_root
=
data_root
self
.
data_root
=
data_root
def
__call__
(
self
,
results
):
def
__call__
(
self
,
results
):
# print(results.keys())
# print(results.keys())
occ_gt_path
=
results
[
'occ_gt_path'
]
occ_gt_path
=
results
[
'occ_gt_path'
]
occ_gt_path
=
os
.
path
.
join
(
self
.
data_root
,
occ_gt_path
)
occ_gt_path
=
os
.
path
.
join
(
self
.
data_root
,
occ_gt_path
)
occ_labels
=
np
.
load
(
occ_gt_path
)
occ_labels
=
np
.
load
(
occ_gt_path
)
semantics
=
occ_labels
[
'semantics'
]
semantics
=
occ_labels
[
'semantics'
]
mask_lidar
=
occ_labels
[
'mask_lidar'
]
mask_lidar
=
occ_labels
[
'mask_lidar'
]
mask_camera
=
occ_labels
[
'mask_camera'
]
mask_camera
=
occ_labels
[
'mask_camera'
]
results
[
'voxel_semantics'
]
=
semantics
results
[
'voxel_semantics'
]
=
semantics
results
[
'mask_lidar'
]
=
mask_lidar
results
[
'mask_lidar'
]
=
mask_lidar
results
[
'mask_camera'
]
=
mask_camera
results
[
'mask_camera'
]
=
mask_camera
return
results
return
results
def
__repr__
(
self
):
"""str: Return a string that describes the module."""
def
__repr__
(
self
):
return
"{} (data_root={}')"
.
format
(
"""str: Return a string that describes the module."""
self
.
__class__
.
__name__
,
self
.
data_root
)
return
"{} (data_root={}')"
.
format
(
self
.
__class__
.
__name__
,
self
.
data_root
)
\ No newline at end of file
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/datasets/pipelines/transform_3d.py
View file @
41b18fd8
import
numpy
as
np
from
numpy
import
random
import
mmcv
import
mmcv
from
mmdet.datasets.builder
import
PIPELINES
import
numpy
as
np
from
mmcv.parallel
import
DataContainer
as
DC
from
mmcv.parallel
import
DataContainer
as
DC
import
os
from
mmdet.datasets.builder
import
PIPELINES
from
numpy
import
random
@
PIPELINES
.
register_module
()
@
PIPELINES
.
register_module
()
...
@@ -36,7 +33,7 @@ class PadMultiViewImage(object):
...
@@ -36,7 +33,7 @@ class PadMultiViewImage(object):
elif
self
.
size_divisor
is
not
None
:
elif
self
.
size_divisor
is
not
None
:
padded_img
=
[
mmcv
.
impad_to_multiple
(
padded_img
=
[
mmcv
.
impad_to_multiple
(
img
,
self
.
size_divisor
,
pad_val
=
self
.
pad_val
)
for
img
in
results
[
'img'
]]
img
,
self
.
size_divisor
,
pad_val
=
self
.
pad_val
)
for
img
in
results
[
'img'
]]
results
[
'ori_shape'
]
=
[
img
.
shape
for
img
in
results
[
'img'
]]
results
[
'ori_shape'
]
=
[
img
.
shape
for
img
in
results
[
'img'
]]
results
[
'img'
]
=
padded_img
results
[
'img'
]
=
padded_img
results
[
'img_shape'
]
=
[
img
.
shape
for
img
in
padded_img
]
results
[
'img_shape'
]
=
[
img
.
shape
for
img
in
padded_img
]
...
@@ -78,7 +75,6 @@ class NormalizeMultiviewImage(object):
...
@@ -78,7 +75,6 @@ class NormalizeMultiviewImage(object):
self
.
std
=
np
.
array
(
std
,
dtype
=
np
.
float32
)
self
.
std
=
np
.
array
(
std
,
dtype
=
np
.
float32
)
self
.
to_rgb
=
to_rgb
self
.
to_rgb
=
to_rgb
def
__call__
(
self
,
results
):
def
__call__
(
self
,
results
):
"""Call function to normalize images.
"""Call function to normalize images.
Args:
Args:
...
@@ -140,12 +136,12 @@ class PhotoMetricDistortionMultiViewImage:
...
@@ -140,12 +136,12 @@ class PhotoMetricDistortionMultiViewImage:
new_imgs
=
[]
new_imgs
=
[]
for
img
in
imgs
:
for
img
in
imgs
:
assert
img
.
dtype
==
np
.
float32
,
\
assert
img
.
dtype
==
np
.
float32
,
\
'PhotoMetricDistortion needs the input image of dtype np.float32,'
\
'PhotoMetricDistortion needs the input image of dtype np.float32,'
\
' please set "to_float32=True" in "LoadImageFromFile" pipeline'
' please set "to_float32=True" in "LoadImageFromFile" pipeline'
# random brightness
# random brightness
if
random
.
randint
(
2
):
if
random
.
randint
(
2
):
delta
=
random
.
uniform
(
-
self
.
brightness_delta
,
delta
=
random
.
uniform
(
-
self
.
brightness_delta
,
self
.
brightness_delta
)
self
.
brightness_delta
)
img
+=
delta
img
+=
delta
# mode == 0 --> do random contrast first
# mode == 0 --> do random contrast first
...
@@ -154,7 +150,7 @@ class PhotoMetricDistortionMultiViewImage:
...
@@ -154,7 +150,7 @@ class PhotoMetricDistortionMultiViewImage:
if
mode
==
1
:
if
mode
==
1
:
if
random
.
randint
(
2
):
if
random
.
randint
(
2
):
alpha
=
random
.
uniform
(
self
.
contrast_lower
,
alpha
=
random
.
uniform
(
self
.
contrast_lower
,
self
.
contrast_upper
)
self
.
contrast_upper
)
img
*=
alpha
img
*=
alpha
# convert color from BGR to HSV
# convert color from BGR to HSV
...
@@ -163,7 +159,7 @@ class PhotoMetricDistortionMultiViewImage:
...
@@ -163,7 +159,7 @@ class PhotoMetricDistortionMultiViewImage:
# random saturation
# random saturation
if
random
.
randint
(
2
):
if
random
.
randint
(
2
):
img
[...,
1
]
*=
random
.
uniform
(
self
.
saturation_lower
,
img
[...,
1
]
*=
random
.
uniform
(
self
.
saturation_lower
,
self
.
saturation_upper
)
self
.
saturation_upper
)
# random hue
# random hue
if
random
.
randint
(
2
):
if
random
.
randint
(
2
):
...
@@ -178,7 +174,7 @@ class PhotoMetricDistortionMultiViewImage:
...
@@ -178,7 +174,7 @@ class PhotoMetricDistortionMultiViewImage:
if
mode
==
0
:
if
mode
==
0
:
if
random
.
randint
(
2
):
if
random
.
randint
(
2
):
alpha
=
random
.
uniform
(
self
.
contrast_lower
,
alpha
=
random
.
uniform
(
self
.
contrast_lower
,
self
.
contrast_upper
)
self
.
contrast_upper
)
img
*=
alpha
img
*=
alpha
# randomly swap channels
# randomly swap channels
...
@@ -199,7 +195,6 @@ class PhotoMetricDistortionMultiViewImage:
...
@@ -199,7 +195,6 @@ class PhotoMetricDistortionMultiViewImage:
return
repr_str
return
repr_str
@
PIPELINES
.
register_module
()
@
PIPELINES
.
register_module
()
class
CustomCollect3D
(
object
):
class
CustomCollect3D
(
object
):
"""Collect data from the loader relevant to the specific task.
"""Collect data from the loader relevant to the specific task.
...
@@ -247,7 +242,7 @@ class CustomCollect3D(object):
...
@@ -247,7 +242,7 @@ class CustomCollect3D(object):
def
__init__
(
self
,
def
__init__
(
self
,
keys
,
keys
,
meta_keys
=
(
'filename'
,
'ori_shape'
,
'img_shape'
,
'lidar2img'
,
'ego2lidar'
,
meta_keys
=
(
'filename'
,
'ori_shape'
,
'img_shape'
,
'lidar2img'
,
'ego2lidar'
,
'depth2img'
,
'cam2img'
,
'pad_shape'
,
'depth2img'
,
'cam2img'
,
'pad_shape'
,
'scale_factor'
,
'flip'
,
'pcd_horizontal_flip'
,
'scale_factor'
,
'flip'
,
'pcd_horizontal_flip'
,
'pcd_vertical_flip'
,
'box_mode_3d'
,
'box_type_3d'
,
'pcd_vertical_flip'
,
'box_mode_3d'
,
'box_type_3d'
,
...
@@ -269,10 +264,10 @@ class CustomCollect3D(object):
...
@@ -269,10 +264,10 @@ class CustomCollect3D(object):
- keys in ``self.keys``
- keys in ``self.keys``
- ``img_metas``
- ``img_metas``
"""
"""
data
=
{}
data
=
{}
img_metas
=
{}
img_metas
=
{}
for
key
in
self
.
meta_keys
:
for
key
in
self
.
meta_keys
:
if
key
in
results
:
if
key
in
results
:
img_metas
[
key
]
=
results
[
key
]
img_metas
[
key
]
=
results
[
key
]
...
@@ -285,8 +280,7 @@ class CustomCollect3D(object):
...
@@ -285,8 +280,7 @@ class CustomCollect3D(object):
def
__repr__
(
self
):
def
__repr__
(
self
):
"""str: Return a string that describes the module."""
"""str: Return a string that describes the module."""
return
self
.
__class__
.
__name__
+
\
return
self
.
__class__
.
__name__
+
\
f
'(keys=
{
self
.
keys
}
, meta_keys=
{
self
.
meta_keys
}
)'
f
'(keys=
{
self
.
keys
}
, meta_keys=
{
self
.
meta_keys
}
)'
@
PIPELINES
.
register_module
()
@
PIPELINES
.
register_module
()
...
@@ -298,7 +292,7 @@ class RandomScaleImageMultiViewImage(object):
...
@@ -298,7 +292,7 @@ class RandomScaleImageMultiViewImage(object):
def
__init__
(
self
,
scales
=
[]):
def
__init__
(
self
,
scales
=
[]):
self
.
scales
=
scales
self
.
scales
=
scales
assert
len
(
self
.
scales
)
==
1
assert
len
(
self
.
scales
)
==
1
def
__call__
(
self
,
results
):
def
__call__
(
self
,
results
):
"""Call function to pad images, masks, semantic segmentation maps.
"""Call function to pad images, masks, semantic segmentation maps.
...
@@ -324,8 +318,7 @@ class RandomScaleImageMultiViewImage(object):
...
@@ -324,8 +318,7 @@ class RandomScaleImageMultiViewImage(object):
return
results
return
results
def
__repr__
(
self
):
def
__repr__
(
self
):
repr_str
=
self
.
__class__
.
__name__
repr_str
=
self
.
__class__
.
__name__
repr_str
+=
f
'(size=
{
self
.
scales
}
, '
repr_str
+=
f
'(size=
{
self
.
scales
}
, '
return
repr_str
return
repr_str
\ No newline at end of file
autonomous_driving/occupancy_prediction/projects/mmdet3d_plugin/datasets/samplers/__init__.py
View file @
41b18fd8
from
.group_sampler
import
DistributedGroupSampler
from
.distributed_sampler
import
DistributedSampler
from
.distributed_sampler
import
DistributedSampler
from
.group_sampler
import
DistributedGroupSampler
from
.sampler
import
SAMPLER
,
build_sampler
from
.sampler
import
SAMPLER
,
build_sampler
Prev
1
2
3
4
5
6
7
8
9
10
…
20
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