mirror of
https://github.com/open-mmlab/mmsegmentation.git
synced 2025-06-03 22:03:48 +08:00
## Motivation This fixes #2493. When the `label_map` is created, the index for ignored classes was being set to -1, whereas the index that is actually ignored is 255. This worked indirectly since -1 was underflowed to 255 when converting to uint8. The same fix was made in the 1.x by #2332 but this fix was never made to `master`. ## Modification The only small modification is setting the index of ignored classes to 255 instead of -1. ## Checklist - [x] Pre-commit or other linting tools are used to fix the potential lint issues. - _I've fixed all linting/pre-commit errors._ - [x] The modification is covered by complete unit tests. If not, please add more unit test to ensure the correctness. - _No unit tests need to be added. Unit tests that are affected were modified. - [x] If the modification has potential influence on downstream projects, this PR should be tested with downstream projects, like MMDet or MMDet3D. - _I don't think this change affects MMDet or MMDet3D._ - [x] The documentation has been modified accordingly, like docstring or example tutorials. - _This change fixes an existing bug and doesn't require modifying any documentation/docstring._
255 lines
8.9 KiB
Python
255 lines
8.9 KiB
Python
# Copyright (c) OpenMMLab. All rights reserved.
|
|
import copy
|
|
import os.path as osp
|
|
import tempfile
|
|
|
|
import mmcv
|
|
import numpy as np
|
|
|
|
from mmseg.datasets.pipelines import LoadAnnotations, LoadImageFromFile
|
|
|
|
|
|
class TestLoading(object):
|
|
|
|
@classmethod
|
|
def setup_class(cls):
|
|
cls.data_prefix = osp.join(osp.dirname(__file__), '../data')
|
|
|
|
def test_load_img(self):
|
|
results = dict(
|
|
img_prefix=self.data_prefix, img_info=dict(filename='color.jpg'))
|
|
transform = LoadImageFromFile()
|
|
results = transform(copy.deepcopy(results))
|
|
assert results['filename'] == osp.join(self.data_prefix, 'color.jpg')
|
|
assert results['ori_filename'] == 'color.jpg'
|
|
assert results['img'].shape == (288, 512, 3)
|
|
assert results['img'].dtype == np.uint8
|
|
assert results['img_shape'] == (288, 512, 3)
|
|
assert results['ori_shape'] == (288, 512, 3)
|
|
assert results['pad_shape'] == (288, 512, 3)
|
|
assert results['scale_factor'] == 1.0
|
|
np.testing.assert_equal(results['img_norm_cfg']['mean'],
|
|
np.zeros(3, dtype=np.float32))
|
|
assert repr(transform) == transform.__class__.__name__ + \
|
|
"(to_float32=False,color_type='color',imdecode_backend='cv2')"
|
|
|
|
# no img_prefix
|
|
results = dict(
|
|
img_prefix=None, img_info=dict(filename='tests/data/color.jpg'))
|
|
transform = LoadImageFromFile()
|
|
results = transform(copy.deepcopy(results))
|
|
assert results['filename'] == 'tests/data/color.jpg'
|
|
assert results['ori_filename'] == 'tests/data/color.jpg'
|
|
assert results['img'].shape == (288, 512, 3)
|
|
|
|
# to_float32
|
|
transform = LoadImageFromFile(to_float32=True)
|
|
results = transform(copy.deepcopy(results))
|
|
assert results['img'].dtype == np.float32
|
|
|
|
# gray image
|
|
results = dict(
|
|
img_prefix=self.data_prefix, img_info=dict(filename='gray.jpg'))
|
|
transform = LoadImageFromFile()
|
|
results = transform(copy.deepcopy(results))
|
|
assert results['img'].shape == (288, 512, 3)
|
|
assert results['img'].dtype == np.uint8
|
|
|
|
transform = LoadImageFromFile(color_type='unchanged')
|
|
results = transform(copy.deepcopy(results))
|
|
assert results['img'].shape == (288, 512)
|
|
assert results['img'].dtype == np.uint8
|
|
np.testing.assert_equal(results['img_norm_cfg']['mean'],
|
|
np.zeros(1, dtype=np.float32))
|
|
|
|
def test_load_seg(self):
|
|
results = dict(
|
|
seg_prefix=self.data_prefix,
|
|
ann_info=dict(seg_map='seg.png'),
|
|
seg_fields=[])
|
|
transform = LoadAnnotations()
|
|
results = transform(copy.deepcopy(results))
|
|
assert results['seg_fields'] == ['gt_semantic_seg']
|
|
assert results['gt_semantic_seg'].shape == (288, 512)
|
|
assert results['gt_semantic_seg'].dtype == np.uint8
|
|
assert repr(transform) == transform.__class__.__name__ + \
|
|
"(reduce_zero_label=False,imdecode_backend='pillow')"
|
|
|
|
# no img_prefix
|
|
results = dict(
|
|
seg_prefix=None,
|
|
ann_info=dict(seg_map='tests/data/seg.png'),
|
|
seg_fields=[])
|
|
transform = LoadAnnotations()
|
|
results = transform(copy.deepcopy(results))
|
|
assert results['gt_semantic_seg'].shape == (288, 512)
|
|
assert results['gt_semantic_seg'].dtype == np.uint8
|
|
|
|
# reduce_zero_label
|
|
transform = LoadAnnotations(reduce_zero_label=True)
|
|
results = transform(copy.deepcopy(results))
|
|
assert results['gt_semantic_seg'].shape == (288, 512)
|
|
assert results['gt_semantic_seg'].dtype == np.uint8
|
|
|
|
# mmcv backend
|
|
results = dict(
|
|
seg_prefix=self.data_prefix,
|
|
ann_info=dict(seg_map='seg.png'),
|
|
seg_fields=[])
|
|
transform = LoadAnnotations(imdecode_backend='pillow')
|
|
results = transform(copy.deepcopy(results))
|
|
# this image is saved by PIL
|
|
assert results['gt_semantic_seg'].shape == (288, 512)
|
|
assert results['gt_semantic_seg'].dtype == np.uint8
|
|
|
|
def test_load_seg_custom_classes(self):
|
|
|
|
test_img = np.random.rand(10, 10)
|
|
test_gt = np.zeros_like(test_img)
|
|
test_gt[2:4, 2:4] = 1
|
|
test_gt[2:4, 6:8] = 2
|
|
test_gt[6:8, 2:4] = 3
|
|
test_gt[6:8, 6:8] = 4
|
|
|
|
tmp_dir = tempfile.TemporaryDirectory()
|
|
img_path = osp.join(tmp_dir.name, 'img.jpg')
|
|
gt_path = osp.join(tmp_dir.name, 'gt.png')
|
|
|
|
mmcv.imwrite(test_img, img_path)
|
|
mmcv.imwrite(test_gt, gt_path)
|
|
|
|
# test only train with label with id 3
|
|
results = dict(
|
|
img_info=dict(filename=img_path),
|
|
ann_info=dict(seg_map=gt_path),
|
|
label_map={
|
|
0: 0,
|
|
1: 0,
|
|
2: 0,
|
|
3: 1,
|
|
4: 0
|
|
},
|
|
seg_fields=[])
|
|
|
|
load_imgs = LoadImageFromFile()
|
|
results = load_imgs(copy.deepcopy(results))
|
|
|
|
load_anns = LoadAnnotations()
|
|
results = load_anns(copy.deepcopy(results))
|
|
|
|
gt_array = results['gt_semantic_seg']
|
|
|
|
true_mask = np.zeros_like(gt_array)
|
|
true_mask[6:8, 2:4] = 1
|
|
|
|
assert results['seg_fields'] == ['gt_semantic_seg']
|
|
assert gt_array.shape == (10, 10)
|
|
assert gt_array.dtype == np.uint8
|
|
np.testing.assert_array_equal(gt_array, true_mask)
|
|
|
|
# test only train with label with id 4 and 3
|
|
results = dict(
|
|
img_info=dict(filename=img_path),
|
|
ann_info=dict(seg_map=gt_path),
|
|
label_map={
|
|
0: 0,
|
|
1: 0,
|
|
2: 0,
|
|
3: 2,
|
|
4: 1
|
|
},
|
|
seg_fields=[])
|
|
|
|
load_imgs = LoadImageFromFile()
|
|
results = load_imgs(copy.deepcopy(results))
|
|
|
|
load_anns = LoadAnnotations()
|
|
results = load_anns(copy.deepcopy(results))
|
|
|
|
gt_array = results['gt_semantic_seg']
|
|
|
|
true_mask = np.zeros_like(gt_array)
|
|
true_mask[6:8, 2:4] = 2
|
|
true_mask[6:8, 6:8] = 1
|
|
|
|
assert results['seg_fields'] == ['gt_semantic_seg']
|
|
assert gt_array.shape == (10, 10)
|
|
assert gt_array.dtype == np.uint8
|
|
np.testing.assert_array_equal(gt_array, true_mask)
|
|
|
|
# test with removing a class and reducing zero label simultaneously
|
|
results = dict(
|
|
img_info=dict(filename=img_path),
|
|
ann_info=dict(seg_map=gt_path),
|
|
# since reduce_zero_label is True, there are only 4 real classes.
|
|
# if the full set of classes is ["A", "B", "C", "D"], the
|
|
# following label map simulates the dataset option
|
|
# classes=["A", "C", "D"] which removes class "B".
|
|
label_map={
|
|
0: 0,
|
|
1: 255, # simulate removing class 1
|
|
2: 1,
|
|
3: 2
|
|
},
|
|
seg_fields=[])
|
|
|
|
load_imgs = LoadImageFromFile()
|
|
results = load_imgs(copy.deepcopy(results))
|
|
|
|
# reduce zero label
|
|
load_anns = LoadAnnotations(reduce_zero_label=True)
|
|
results = load_anns(copy.deepcopy(results))
|
|
|
|
gt_array = results['gt_semantic_seg']
|
|
|
|
true_mask = np.ones_like(gt_array) * 255 # all zeros get mapped to 255
|
|
true_mask[2:4, 2:4] = 0 # 1s are reduced to class 0 mapped to class 0
|
|
true_mask[2:4, 6:8] = 255 # 2s are reduced to class 1 which is removed
|
|
true_mask[6:8, 2:4] = 1 # 3s are reduced to class 2 mapped to class 1
|
|
true_mask[6:8, 6:8] = 2 # 4s are reduced to class 3 mapped to class 2
|
|
|
|
assert results['seg_fields'] == ['gt_semantic_seg']
|
|
assert gt_array.shape == (10, 10)
|
|
assert gt_array.dtype == np.uint8
|
|
np.testing.assert_array_equal(gt_array, true_mask)
|
|
|
|
# test no custom classes
|
|
results = dict(
|
|
img_info=dict(filename=img_path),
|
|
ann_info=dict(seg_map=gt_path),
|
|
seg_fields=[])
|
|
|
|
load_imgs = LoadImageFromFile()
|
|
results = load_imgs(copy.deepcopy(results))
|
|
|
|
load_anns = LoadAnnotations()
|
|
results = load_anns(copy.deepcopy(results))
|
|
|
|
gt_array = results['gt_semantic_seg']
|
|
|
|
assert results['seg_fields'] == ['gt_semantic_seg']
|
|
assert gt_array.shape == (10, 10)
|
|
assert gt_array.dtype == np.uint8
|
|
np.testing.assert_array_equal(gt_array, test_gt)
|
|
|
|
# test no custom classes
|
|
results = dict(
|
|
img_info=dict(filename=img_path),
|
|
ann_info=dict(seg_map=gt_path),
|
|
seg_fields=[])
|
|
|
|
load_imgs = LoadImageFromFile()
|
|
results = load_imgs(copy.deepcopy(results))
|
|
|
|
load_anns = LoadAnnotations()
|
|
results = load_anns(copy.deepcopy(results))
|
|
|
|
gt_array = results['gt_semantic_seg']
|
|
|
|
assert results['seg_fields'] == ['gt_semantic_seg']
|
|
assert gt_array.shape == (10, 10)
|
|
assert gt_array.dtype == np.uint8
|
|
np.testing.assert_array_equal(gt_array, test_gt)
|
|
|
|
tmp_dir.cleanup()
|