Saurabh1105's picture
MMdet Model for Image Segmentation
6c9ac8f
# Copyright (c) OpenMMLab. All rights reserved.
import copy
import os
import os.path as osp
import sys
import unittest
from unittest.mock import MagicMock, Mock, patch
import mmcv
import numpy as np
from mmdet.datasets.transforms import (FilterAnnotations, LoadAnnotations,
LoadEmptyAnnotations,
LoadImageFromNDArray,
LoadMultiChannelImageFromFiles,
LoadProposals)
from mmdet.evaluation import INSTANCE_OFFSET
from mmdet.structures.mask import BitmapMasks, PolygonMasks
try:
import panopticapi
except ImportError:
panopticapi = None
class TestLoadAnnotations(unittest.TestCase):
def setUp(self):
"""Setup the model and optimizer which are used in every test method.
TestCase calls functions in this order: setUp() -> testMethod() ->
tearDown() -> cleanUp()
"""
data_prefix = osp.join(osp.dirname(__file__), '../../data')
seg_map = osp.join(data_prefix, 'gray.jpg')
self.results = {
'ori_shape': (300, 400),
'seg_map_path':
seg_map,
'instances': [{
'bbox': [0, 0, 10, 20],
'bbox_label': 1,
'mask': [[0, 0, 0, 20, 10, 20, 10, 0]],
'ignore_flag': 0
}, {
'bbox': [10, 10, 110, 120],
'bbox_label': 2,
'mask': [[10, 10, 110, 10, 110, 120, 110, 10]],
'ignore_flag': 0
}, {
'bbox': [50, 50, 60, 80],
'bbox_label': 2,
'mask': [[50, 50, 60, 50, 60, 80, 50, 80]],
'ignore_flag': 1
}]
}
def test_load_bboxes(self):
transform = LoadAnnotations(
with_bbox=True,
with_label=False,
with_seg=False,
with_mask=False,
box_type=None)
results = transform(copy.deepcopy(self.results))
self.assertIn('gt_bboxes', results)
self.assertTrue((results['gt_bboxes'] == np.array([[0, 0, 10, 20],
[10, 10, 110, 120],
[50, 50, 60,
80]])).all())
self.assertEqual(results['gt_bboxes'].dtype, np.float32)
self.assertTrue((results['gt_ignore_flags'] == np.array([0, 0,
1])).all())
self.assertEqual(results['gt_ignore_flags'].dtype, bool)
def test_load_labels(self):
transform = LoadAnnotations(
with_bbox=False,
with_label=True,
with_seg=False,
with_mask=False,
)
results = transform(copy.deepcopy(self.results))
self.assertIn('gt_bboxes_labels', results)
self.assertTrue((results['gt_bboxes_labels'] == np.array([1, 2,
2])).all())
self.assertEqual(results['gt_bboxes_labels'].dtype, np.int64)
def test_load_mask(self):
transform = LoadAnnotations(
with_bbox=False,
with_label=False,
with_seg=False,
with_mask=True,
poly2mask=False)
results = transform(copy.deepcopy(self.results))
self.assertIn('gt_masks', results)
self.assertEqual(len(results['gt_masks']), 3)
self.assertIsInstance(results['gt_masks'], PolygonMasks)
def test_load_mask_poly2mask(self):
transform = LoadAnnotations(
with_bbox=False,
with_label=False,
with_seg=False,
with_mask=True,
poly2mask=True)
results = transform(copy.deepcopy(self.results))
self.assertIn('gt_masks', results)
self.assertEqual(len(results['gt_masks']), 3)
self.assertIsInstance(results['gt_masks'], BitmapMasks)
def test_repr(self):
transform = LoadAnnotations(
with_bbox=True,
with_label=False,
with_seg=False,
with_mask=False,
)
self.assertEqual(
repr(transform), ('LoadAnnotations(with_bbox=True, '
'with_label=False, with_mask=False, '
'with_seg=False, poly2mask=True, '
"imdecode_backend='cv2', "
'backend_args=None)'))
class TestFilterAnnotations(unittest.TestCase):
def setUp(self):
"""Setup the model and optimizer which are used in every test method.
TestCase calls functions in this order: setUp() -> testMethod() ->
tearDown() -> cleanUp()
"""
rng = np.random.RandomState(0)
self.results = {
'img':
np.random.random((224, 224, 3)),
'img_shape': (224, 224),
'gt_bboxes_labels':
np.array([1, 2, 3], dtype=np.int64),
'gt_bboxes':
np.array([[10, 10, 20, 20], [20, 20, 40, 40], [40, 40, 80, 80]]),
'gt_ignore_flags':
np.array([0, 0, 1], dtype=np.bool8),
'gt_masks':
BitmapMasks(rng.rand(3, 224, 224), height=224, width=224),
}
def test_transform(self):
# test keep_empty = True
transform = FilterAnnotations(
min_gt_bbox_wh=(50, 50),
keep_empty=True,
)
results = transform(copy.deepcopy(self.results))
self.assertIsNone(results)
# test keep_empty = False
transform = FilterAnnotations(
min_gt_bbox_wh=(50, 50),
keep_empty=False,
)
results = transform(copy.deepcopy(self.results))
self.assertTrue(isinstance(results, dict))
# test filter annotations
transform = FilterAnnotations(min_gt_bbox_wh=(15, 15), )
results = transform(copy.deepcopy(self.results))
self.assertIsInstance(results, dict)
self.assertTrue((results['gt_bboxes_labels'] == np.array([2,
3])).all())
self.assertTrue((results['gt_bboxes'] == np.array([[20, 20, 40, 40],
[40, 40, 80,
80]])).all())
self.assertEqual(len(results['gt_masks']), 2)
self.assertEqual(len(results['gt_ignore_flags']), 2)
def test_repr(self):
transform = FilterAnnotations(
min_gt_bbox_wh=(1, 1),
keep_empty=False,
)
self.assertEqual(
repr(transform), ('FilterAnnotations(min_gt_bbox_wh=(1, 1), '
'keep_empty=False)'))
class TestLoadPanopticAnnotations(unittest.TestCase):
def setUp(self):
seg_map = np.zeros((10, 10), dtype=np.int32)
seg_map[:5, :10] = 1 + 10 * INSTANCE_OFFSET
seg_map[5:10, :5] = 4 + 11 * INSTANCE_OFFSET
seg_map[5:10, 5:10] = 6 + 0 * INSTANCE_OFFSET
rgb_seg_map = np.zeros((10, 10, 3), dtype=np.uint8)
rgb_seg_map[:, :, 0] = seg_map / (256 * 256)
rgb_seg_map[:, :, 1] = seg_map % (256 * 256) / 256
rgb_seg_map[:, :, 2] = seg_map % 256
self.seg_map_path = './1.png'
mmcv.imwrite(rgb_seg_map, self.seg_map_path)
self.seg_map = seg_map
self.rgb_seg_map = rgb_seg_map
self.results = {
'ori_shape': (10, 10),
'instances': [{
'bbox': [0, 0, 10, 5],
'bbox_label': 0,
'ignore_flag': 0,
}, {
'bbox': [0, 5, 5, 10],
'bbox_label': 1,
'ignore_flag': 1,
}],
'segments_info': [
{
'id': 1 + 10 * INSTANCE_OFFSET,
'category': 0,
'is_thing': True,
},
{
'id': 4 + 11 * INSTANCE_OFFSET,
'category': 1,
'is_thing': True,
},
{
'id': 6 + 0 * INSTANCE_OFFSET,
'category': 2,
'is_thing': False,
},
],
'seg_map_path':
self.seg_map_path
}
self.gt_mask = BitmapMasks([
(seg_map == 1 + 10 * INSTANCE_OFFSET).astype(np.uint8),
(seg_map == 4 + 11 * INSTANCE_OFFSET).astype(np.uint8),
], 10, 10)
self.gt_bboxes = np.array([[0, 0, 10, 5], [0, 5, 5, 10]],
dtype=np.float32)
self.gt_bboxes_labels = np.array([0, 1], dtype=np.int64)
self.gt_ignore_flags = np.array([0, 1], dtype=bool)
self.gt_seg_map = np.zeros((10, 10), dtype=np.int32)
self.gt_seg_map[:5, :10] = 0
self.gt_seg_map[5:10, :5] = 1
self.gt_seg_map[5:10, 5:10] = 2
def tearDown(self):
os.remove(self.seg_map_path)
@unittest.skipIf(panopticapi is not None, 'panopticapi is installed')
def test_init_without_panopticapi(self):
# test if panopticapi is not installed
from mmdet.datasets.transforms import LoadPanopticAnnotations
with self.assertRaisesRegex(
ImportError,
'panopticapi is not installed, please install it by'):
LoadPanopticAnnotations()
def test_transform(self):
sys.modules['panopticapi'] = MagicMock()
sys.modules['panopticapi.utils'] = MagicMock()
from mmdet.datasets.transforms import LoadPanopticAnnotations
mock_rgb2id = Mock(return_value=self.seg_map)
with patch('panopticapi.utils.rgb2id', mock_rgb2id):
# test with all False
transform = LoadPanopticAnnotations(
with_bbox=False,
with_label=False,
with_mask=False,
with_seg=False)
results = transform(copy.deepcopy(self.results))
self.assertDictEqual(results, self.results)
# test with with_mask=True
transform = LoadPanopticAnnotations(
with_bbox=False,
with_label=False,
with_mask=True,
with_seg=False)
results = transform(copy.deepcopy(self.results))
self.assertTrue(
(results['gt_masks'].masks == self.gt_mask.masks).all())
# test with with_seg=True
transform = LoadPanopticAnnotations(
with_bbox=False,
with_label=False,
with_mask=False,
with_seg=True)
results = transform(copy.deepcopy(self.results))
self.assertNotIn('gt_masks', results)
self.assertTrue((results['gt_seg_map'] == self.gt_seg_map).all())
# test with all True
transform = LoadPanopticAnnotations(
with_bbox=True,
with_label=True,
with_mask=True,
with_seg=True,
box_type=None)
results = transform(copy.deepcopy(self.results))
self.assertTrue(
(results['gt_masks'].masks == self.gt_mask.masks).all())
self.assertTrue((results['gt_bboxes'] == self.gt_bboxes).all())
self.assertTrue(
(results['gt_bboxes_labels'] == self.gt_bboxes_labels).all())
self.assertTrue(
(results['gt_ignore_flags'] == self.gt_ignore_flags).all())
self.assertTrue((results['gt_seg_map'] == self.gt_seg_map).all())
class TestLoadImageFromNDArray(unittest.TestCase):
def setUp(self):
"""Setup the model and optimizer which are used in every test method.
TestCase calls functions in this order: setUp() -> testMethod() ->
tearDown() -> cleanUp()
"""
self.results = {'img': np.zeros((256, 256, 3), dtype=np.uint8)}
def test_transform(self):
transform = LoadImageFromNDArray()
results = transform(copy.deepcopy(self.results))
self.assertEqual(results['img'].shape, (256, 256, 3))
self.assertEqual(results['img'].dtype, np.uint8)
self.assertEqual(results['img_shape'], (256, 256))
self.assertEqual(results['ori_shape'], (256, 256))
# to_float32
transform = LoadImageFromNDArray(to_float32=True)
results = transform(copy.deepcopy(results))
self.assertEqual(results['img'].dtype, np.float32)
def test_repr(self):
transform = LoadImageFromNDArray()
self.assertEqual(
repr(transform), ('LoadImageFromNDArray('
'ignore_empty=False, '
'to_float32=False, '
"color_type='color', "
"imdecode_backend='cv2', "
'backend_args=None)'))
class TestLoadMultiChannelImageFromFiles(unittest.TestCase):
def setUp(self):
"""Setup the model and optimizer which are used in every test method.
TestCase calls functions in this order: setUp() -> testMethod() ->
tearDown() -> cleanUp()
"""
self.img_path = []
for i in range(4):
img_channel_path = f'./part_{i}.jpg'
img_channel = np.zeros((10, 10), dtype=np.uint8)
mmcv.imwrite(img_channel, img_channel_path)
self.img_path.append(img_channel_path)
self.results = {'img_path': self.img_path}
def tearDown(self):
for filename in self.img_path:
os.remove(filename)
def test_transform(self):
transform = LoadMultiChannelImageFromFiles()
results = transform(copy.deepcopy(self.results))
self.assertEqual(results['img'].shape, (10, 10, 4))
self.assertEqual(results['img'].dtype, np.uint8)
self.assertEqual(results['img_shape'], (10, 10))
self.assertEqual(results['ori_shape'], (10, 10))
# to_float32
transform = LoadMultiChannelImageFromFiles(to_float32=True)
results = transform(copy.deepcopy(results))
self.assertEqual(results['img'].dtype, np.float32)
def test_rper(self):
transform = LoadMultiChannelImageFromFiles()
self.assertEqual(
repr(transform), ('LoadMultiChannelImageFromFiles('
'to_float32=False, '
"color_type='unchanged', "
"imdecode_backend='cv2', "
'backend_args=None)'))
class TestLoadProposals(unittest.TestCase):
def test_transform(self):
transform = LoadProposals()
results = {
'proposals':
dict(
bboxes=np.zeros((5, 4), dtype=np.int64),
scores=np.zeros((5, ), dtype=np.int64))
}
results = transform(results)
self.assertEqual(results['proposals'].dtype, np.float32)
self.assertEqual(results['proposals'].shape[-1], 4)
self.assertEqual(results['proposals_scores'].dtype, np.float32)
# bboxes.shape[1] should be 4
results = {'proposals': dict(bboxes=np.zeros((5, 5), dtype=np.int64))}
with self.assertRaises(AssertionError):
transform(results)
# bboxes.shape[0] should equal to scores.shape[0]
results = {
'proposals':
dict(
bboxes=np.zeros((5, 4), dtype=np.int64),
scores=np.zeros((3, ), dtype=np.int64))
}
with self.assertRaises(AssertionError):
transform(results)
# empty bboxes
results = {
'proposals': dict(bboxes=np.zeros((0, 4), dtype=np.float32))
}
results = transform(results)
excepted_proposals = np.zeros((0, 4), dtype=np.float32)
excepted_proposals_scores = np.zeros(0, dtype=np.float32)
self.assertTrue((results['proposals'] == excepted_proposals).all())
self.assertTrue(
(results['proposals_scores'] == excepted_proposals_scores).all())
transform = LoadProposals(num_max_proposals=2)
results = {
'proposals':
dict(
bboxes=np.zeros((5, 4), dtype=np.int64),
scores=np.zeros((5, ), dtype=np.int64))
}
results = transform(results)
self.assertEqual(results['proposals'].shape[0], 2)
def test_repr(self):
transform = LoadProposals()
self.assertEqual(
repr(transform), 'LoadProposals(num_max_proposals=None)')
class TestLoadEmptyAnnotations(unittest.TestCase):
def test_transform(self):
transform = LoadEmptyAnnotations(
with_bbox=True, with_label=True, with_mask=True, with_seg=True)
results = {'img_shape': (224, 224)}
results = transform(results)
self.assertEqual(results['gt_bboxes'].dtype, np.float32)
self.assertEqual(results['gt_bboxes'].shape[-1], 4)
self.assertEqual(results['gt_ignore_flags'].dtype, bool)
self.assertEqual(results['gt_bboxes_labels'].dtype, np.int64)
self.assertEqual(results['gt_masks'].masks.dtype, np.uint8)
self.assertEqual(results['gt_masks'].masks.shape[-2:],
results['img_shape'])
self.assertEqual(results['gt_seg_map'].dtype, np.uint8)
self.assertEqual(results['gt_seg_map'].shape, results['img_shape'])
def test_repr(self):
transform = LoadEmptyAnnotations()
self.assertEqual(
repr(transform), 'LoadEmptyAnnotations(with_bbox=True, '
'with_label=True, '
'with_mask=False, '
'with_seg=False, '
'seg_ignore_label=255)')