test_transforms.py 70 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711
  1. # Copyright (c) OpenMMLab. All rights reserved.
  2. import copy
  3. import os.path as osp
  4. import unittest
  5. import mmcv
  6. import numpy as np
  7. import torch
  8. from mmcv.transforms import LoadImageFromFile
  9. # yapf:disable
  10. from mmdet.datasets.transforms import (CopyPaste, CutOut, Expand,
  11. FixShapeResize, MinIoURandomCrop, MixUp,
  12. Mosaic, Pad, PhotoMetricDistortion,
  13. RandomAffine, RandomCenterCropPad,
  14. RandomCrop, RandomErasing, RandomFlip,
  15. RandomShift, Resize, SegRescale,
  16. YOLOXHSVRandomAug)
  17. # yapf:enable
  18. from mmdet.evaluation import bbox_overlaps
  19. from mmdet.registry import TRANSFORMS
  20. from mmdet.structures.bbox import HorizontalBoxes, bbox_project
  21. from mmdet.structures.mask import BitmapMasks
  22. from .utils import construct_toy_data, create_full_masks, create_random_bboxes
  23. try:
  24. import albumentations
  25. from albumentations import Compose
  26. except ImportError:
  27. albumentations = None
  28. Compose = None
  29. # yapf:enable
  30. class TestResize(unittest.TestCase):
  31. def setUp(self):
  32. """Setup the model and optimizer which are used in every test method.
  33. TestCase calls functions in this order: setUp() -> testMethod()
  34. -> tearDown() -> cleanUp()
  35. """
  36. rng = np.random.RandomState(0)
  37. self.data_info1 = dict(
  38. img=np.random.random((1333, 800, 3)),
  39. gt_seg_map=np.random.random((1333, 800, 3)),
  40. gt_bboxes=np.array([[0, 0, 112, 112]], dtype=np.float32),
  41. gt_masks=BitmapMasks(
  42. rng.rand(1, 1333, 800), height=1333, width=800))
  43. self.data_info2 = dict(
  44. img=np.random.random((300, 400, 3)),
  45. gt_bboxes=np.array([[200, 150, 600, 450]], dtype=np.float32),
  46. dtype=np.float32)
  47. self.data_info3 = dict(img=np.random.random((300, 400, 3)))
  48. def test_resize(self):
  49. # test keep_ratio is True
  50. transform = Resize(scale=(2000, 2000), keep_ratio=True)
  51. results = transform(copy.deepcopy(self.data_info1))
  52. self.assertEqual(results['img_shape'], (2000, 1200))
  53. self.assertEqual(results['scale_factor'], (1200 / 800, 2000 / 1333))
  54. # test resize_bboxes/seg/masks
  55. transform = Resize(scale_factor=(1.5, 2))
  56. results = transform(copy.deepcopy(self.data_info1))
  57. self.assertTrue((results['gt_bboxes'] == np.array([[0, 0, 168,
  58. 224]])).all())
  59. self.assertEqual(results['gt_masks'].height, 2666)
  60. self.assertEqual(results['gt_masks'].width, 1200)
  61. self.assertEqual(results['gt_seg_map'].shape[:2], (2666, 1200))
  62. # test clip_object_border = False
  63. transform = Resize(scale=(200, 150), clip_object_border=False)
  64. results = transform(self.data_info2)
  65. self.assertTrue((results['gt_bboxes'] == np.array([100, 75, 300,
  66. 225])).all())
  67. # test only with image
  68. transform = Resize(scale=(200, 150), clip_object_border=False)
  69. results = transform(self.data_info3)
  70. self.assertTupleEqual(results['img'].shape[:2], (150, 200))
  71. # test geometric transformation with homography matrix
  72. transform = Resize(scale_factor=(1.5, 2))
  73. results = transform(copy.deepcopy(self.data_info1))
  74. self.assertTrue((bbox_project(
  75. copy.deepcopy(self.data_info1['gt_bboxes']),
  76. results['homography_matrix']) == results['gt_bboxes']).all())
  77. def test_resize_use_box_type(self):
  78. data_info1 = copy.deepcopy(self.data_info1)
  79. data_info1['gt_bboxes'] = HorizontalBoxes(data_info1['gt_bboxes'])
  80. data_info2 = copy.deepcopy(self.data_info2)
  81. data_info2['gt_bboxes'] = HorizontalBoxes(data_info2['gt_bboxes'])
  82. # test keep_ratio is True
  83. transform = Resize(scale=(2000, 2000), keep_ratio=True)
  84. results = transform(copy.deepcopy(data_info1))
  85. self.assertEqual(results['img_shape'], (2000, 1200))
  86. self.assertEqual(results['scale_factor'], (1200 / 800, 2000 / 1333))
  87. # test resize_bboxes/seg/masks
  88. transform = Resize(scale_factor=(1.5, 2))
  89. results = transform(copy.deepcopy(data_info1))
  90. self.assertTrue(
  91. (results['gt_bboxes'].numpy() == np.array([[0, 0, 168,
  92. 224]])).all())
  93. self.assertEqual(results['gt_masks'].height, 2666)
  94. self.assertEqual(results['gt_masks'].width, 1200)
  95. self.assertEqual(results['gt_seg_map'].shape[:2], (2666, 1200))
  96. # test clip_object_border = False
  97. transform = Resize(scale=(200, 150), clip_object_border=False)
  98. results = transform(data_info2)
  99. self.assertTrue(
  100. (results['gt_bboxes'].numpy() == np.array([100, 75, 300,
  101. 225])).all())
  102. # test geometric transformation with homography matrix
  103. transform = Resize(scale_factor=(1.5, 2))
  104. results = transform(copy.deepcopy(data_info1))
  105. self.assertTrue((bbox_project(
  106. copy.deepcopy(data_info1['gt_bboxes'].numpy()),
  107. results['homography_matrix']) == results['gt_bboxes'].numpy()
  108. ).all())
  109. def test_repr(self):
  110. transform = Resize(scale=(2000, 2000), keep_ratio=True)
  111. self.assertEqual(
  112. repr(transform), ('Resize(scale=(2000, 2000), '
  113. 'scale_factor=None, keep_ratio=True, '
  114. 'clip_object_border=True), backend=cv2), '
  115. 'interpolation=bilinear)'))
  116. class TestFIXShapeResize(unittest.TestCase):
  117. def setUp(self):
  118. """Setup the model and optimizer which are used in every test method.
  119. TestCase calls functions in this order: setUp() -> testMethod() ->
  120. tearDown() -> cleanUp()
  121. """
  122. rng = np.random.RandomState(0)
  123. self.data_info1 = dict(
  124. img=np.random.random((1333, 800, 3)),
  125. gt_seg_map=np.random.random((1333, 800, 3)),
  126. gt_bboxes=np.array([[0, 0, 112, 1333]], dtype=np.float32),
  127. gt_masks=BitmapMasks(
  128. rng.rand(1, 1333, 800), height=1333, width=800))
  129. self.data_info2 = dict(
  130. img=np.random.random((300, 400, 3)),
  131. gt_bboxes=np.array([[200, 150, 600, 450]], dtype=np.float32),
  132. dtype=np.float32)
  133. self.data_info3 = dict(img=np.random.random((300, 400, 3)))
  134. self.data_info4 = dict(
  135. img=np.random.random((600, 800, 3)),
  136. gt_bboxes=np.array([[200, 150, 300, 400]], dtype=np.float32),
  137. dtype=np.float32)
  138. def test_resize(self):
  139. # test keep_ratio is True
  140. transform = FixShapeResize(width=2000, height=800, keep_ratio=True)
  141. results = transform(copy.deepcopy(self.data_info1))
  142. self.assertEqual(results['img_shape'], (800, 2000))
  143. self.assertEqual(results['scale_factor'], (800 / 1333, 800 / 1333))
  144. # test resize_bboxes/seg/masks
  145. transform = FixShapeResize(width=2000, height=800, keep_ratio=False)
  146. results = transform(copy.deepcopy(self.data_info1))
  147. self.assertTrue((results['gt_bboxes'] == np.array([[0, 0, 280,
  148. 800]])).all())
  149. self.assertEqual(results['gt_masks'].height, 800)
  150. self.assertEqual(results['gt_masks'].width, 2000)
  151. self.assertEqual(results['gt_seg_map'].shape[:2], (800, 2000))
  152. # test clip_object_border = False
  153. transform = FixShapeResize(
  154. width=200, height=150, clip_object_border=False)
  155. results = transform(copy.deepcopy(self.data_info2))
  156. self.assertTrue((results['gt_bboxes'] == np.array([100, 75, 300,
  157. 225])).all())
  158. # test only with image
  159. transform = FixShapeResize(
  160. width=200, height=150, clip_object_border=False)
  161. results = transform(self.data_info3)
  162. self.assertTupleEqual(results['img'].shape[:2], (150, 200))
  163. # test geometric transformation with homography matrix
  164. transform = FixShapeResize(width=400, height=300)
  165. results = transform(copy.deepcopy(self.data_info4))
  166. self.assertTrue((bbox_project(
  167. copy.deepcopy(self.data_info4['gt_bboxes']),
  168. results['homography_matrix']) == results['gt_bboxes']).all())
  169. def test_resize_with_boxlist(self):
  170. data_info1 = copy.deepcopy(self.data_info1)
  171. data_info1['gt_bboxes'] = HorizontalBoxes(data_info1['gt_bboxes'])
  172. data_info2 = copy.deepcopy(self.data_info2)
  173. data_info2['gt_bboxes'] = HorizontalBoxes(data_info2['gt_bboxes'])
  174. data_info4 = copy.deepcopy(self.data_info4)
  175. data_info4['gt_bboxes'] = HorizontalBoxes(data_info4['gt_bboxes'])
  176. # test keep_ratio is True
  177. transform = FixShapeResize(width=2000, height=800, keep_ratio=True)
  178. results = transform(copy.deepcopy(data_info1))
  179. self.assertEqual(results['img_shape'], (800, 2000))
  180. self.assertEqual(results['scale_factor'], (800 / 1333, 800 / 1333))
  181. # test resize_bboxes/seg/masks
  182. transform = FixShapeResize(width=2000, height=800, keep_ratio=False)
  183. results = transform(copy.deepcopy(data_info1))
  184. self.assertTrue(
  185. (results['gt_bboxes'].numpy() == np.array([[0, 0, 280,
  186. 800]])).all())
  187. self.assertEqual(results['gt_masks'].height, 800)
  188. self.assertEqual(results['gt_masks'].width, 2000)
  189. self.assertEqual(results['gt_seg_map'].shape[:2], (800, 2000))
  190. # test clip_object_border = False
  191. transform = FixShapeResize(
  192. width=200, height=150, clip_object_border=False)
  193. results = transform(copy.deepcopy(data_info2))
  194. self.assertTrue(
  195. (results['gt_bboxes'].numpy() == np.array([100, 75, 300,
  196. 225])).all())
  197. # test only with image
  198. transform = FixShapeResize(
  199. width=200, height=150, clip_object_border=False)
  200. results = transform(self.data_info3)
  201. self.assertTupleEqual(results['img'].shape[:2], (150, 200))
  202. # test geometric transformation with homography matrix
  203. transform = FixShapeResize(width=400, height=300)
  204. results = transform(copy.deepcopy(data_info4))
  205. self.assertTrue((bbox_project(
  206. copy.deepcopy(self.data_info4['gt_bboxes']),
  207. results['homography_matrix']) == results['gt_bboxes'].numpy()
  208. ).all())
  209. def test_repr(self):
  210. transform = FixShapeResize(width=2000, height=2000, keep_ratio=True)
  211. self.assertEqual(
  212. repr(transform), ('FixShapeResize(width=2000, height=2000, '
  213. 'keep_ratio=True, '
  214. 'clip_object_border=True), backend=cv2), '
  215. 'interpolation=bilinear)'))
  216. class TestRandomFlip(unittest.TestCase):
  217. def setUp(self):
  218. """Setup the model and optimizer which are used in every test method.
  219. TestCase calls functions in this order: setUp() -> testMethod() ->
  220. tearDown() -> cleanUp()
  221. """
  222. rng = np.random.RandomState(0)
  223. self.results1 = {
  224. 'img': np.random.random((224, 224, 3)),
  225. 'gt_bboxes': np.array([[0, 1, 100, 101]], dtype=np.float32),
  226. 'gt_masks':
  227. BitmapMasks(rng.rand(1, 224, 224), height=224, width=224),
  228. 'gt_seg_map': np.random.random((224, 224))
  229. }
  230. self.results2 = {'img': self.results1['img']}
  231. def test_transform(self):
  232. # test with image, gt_bboxes, gt_masks, gt_seg_map
  233. transform = RandomFlip(1.0)
  234. results_update = transform.transform(copy.deepcopy(self.results1))
  235. self.assertTrue(
  236. (results_update['gt_bboxes'] == np.array([[124, 1, 224,
  237. 101]])).all())
  238. # test only with image
  239. transform = RandomFlip(1.0)
  240. results_update = transform.transform(copy.deepcopy(self.results2))
  241. self.assertTrue(
  242. (results_update['img'] == self.results2['img'][:, ::-1]).all())
  243. # test geometric transformation with homography matrix
  244. # (1) Horizontal Flip
  245. transform = RandomFlip(1.0)
  246. results_update = transform.transform(copy.deepcopy(self.results1))
  247. bboxes = copy.deepcopy(self.results1['gt_bboxes'])
  248. self.assertTrue((bbox_project(
  249. bboxes,
  250. results_update['homography_matrix']) == results_update['gt_bboxes']
  251. ).all())
  252. # (2) Vertical Flip
  253. transform = RandomFlip(1.0, direction='vertical')
  254. results_update = transform.transform(copy.deepcopy(self.results1))
  255. bboxes = copy.deepcopy(self.results1['gt_bboxes'])
  256. self.assertTrue((bbox_project(
  257. bboxes,
  258. results_update['homography_matrix']) == results_update['gt_bboxes']
  259. ).all())
  260. # (3) Diagonal Flip
  261. transform = RandomFlip(1.0, direction='diagonal')
  262. results_update = transform.transform(copy.deepcopy(self.results1))
  263. bboxes = copy.deepcopy(self.results1['gt_bboxes'])
  264. self.assertTrue((bbox_project(
  265. bboxes,
  266. results_update['homography_matrix']) == results_update['gt_bboxes']
  267. ).all())
  268. def test_transform_use_box_type(self):
  269. results1 = copy.deepcopy(self.results1)
  270. results1['gt_bboxes'] = HorizontalBoxes(results1['gt_bboxes'])
  271. # test with image, gt_bboxes, gt_masks, gt_seg_map
  272. transform = RandomFlip(1.0)
  273. results_update = transform.transform(copy.deepcopy(results1))
  274. self.assertTrue((results_update['gt_bboxes'].numpy() == np.array(
  275. [[124, 1, 224, 101]])).all())
  276. # test geometric transformation with homography matrix
  277. # (1) Horizontal Flip
  278. transform = RandomFlip(1.0)
  279. results_update = transform.transform(copy.deepcopy(results1))
  280. bboxes = copy.deepcopy(results1['gt_bboxes'].numpy())
  281. self.assertTrue((bbox_project(bboxes,
  282. results_update['homography_matrix']) ==
  283. results_update['gt_bboxes'].numpy()).all())
  284. # (2) Vertical Flip
  285. transform = RandomFlip(1.0, direction='vertical')
  286. results_update = transform.transform(copy.deepcopy(results1))
  287. bboxes = copy.deepcopy(results1['gt_bboxes'].numpy())
  288. self.assertTrue((bbox_project(bboxes,
  289. results_update['homography_matrix']) ==
  290. results_update['gt_bboxes'].numpy()).all())
  291. # (3) Diagonal Flip
  292. transform = RandomFlip(1.0, direction='diagonal')
  293. results_update = transform.transform(copy.deepcopy(results1))
  294. bboxes = copy.deepcopy(results1['gt_bboxes'].numpy())
  295. self.assertTrue((bbox_project(bboxes,
  296. results_update['homography_matrix']) ==
  297. results_update['gt_bboxes'].numpy()).all())
  298. def test_repr(self):
  299. transform = RandomFlip(0.1)
  300. transform_str = str(transform)
  301. self.assertIsInstance(transform_str, str)
  302. class TestPad(unittest.TestCase):
  303. def setUp(self):
  304. """Setup the model and optimizer which are used in every test method.
  305. TestCase calls functions in this order: setUp() -> testMethod() ->
  306. tearDown() -> cleanUp()
  307. """
  308. rng = np.random.RandomState(0)
  309. self.results = {
  310. 'img': np.random.random((1333, 800, 3)),
  311. 'gt_masks':
  312. BitmapMasks(rng.rand(4, 1333, 800), height=1333, width=800)
  313. }
  314. def test_transform(self):
  315. # test pad img/gt_masks with size
  316. transform = Pad(size=(1200, 2000))
  317. results = transform(copy.deepcopy(self.results))
  318. self.assertEqual(results['img'].shape[:2], (2000, 1200))
  319. self.assertEqual(results['gt_masks'].masks.shape[1:], (2000, 1200))
  320. # test pad img/gt_masks with size_divisor
  321. transform = Pad(size_divisor=11)
  322. results = transform(copy.deepcopy(self.results))
  323. self.assertEqual(results['img'].shape[:2], (1342, 803))
  324. self.assertEqual(results['gt_masks'].masks.shape[1:], (1342, 803))
  325. # test pad img/gt_masks with pad_to_square
  326. transform = Pad(pad_to_square=True)
  327. results = transform(copy.deepcopy(self.results))
  328. self.assertEqual(results['img'].shape[:2], (1333, 1333))
  329. self.assertEqual(results['gt_masks'].masks.shape[1:], (1333, 1333))
  330. # test pad img/gt_masks with pad_to_square and size_divisor
  331. transform = Pad(pad_to_square=True, size_divisor=11)
  332. results = transform(copy.deepcopy(self.results))
  333. self.assertEqual(results['img'].shape[:2], (1342, 1342))
  334. self.assertEqual(results['gt_masks'].masks.shape[1:], (1342, 1342))
  335. # test pad img/gt_masks with pad_to_square and size_divisor
  336. transform = Pad(pad_to_square=True, size_divisor=11)
  337. results = transform(copy.deepcopy(self.results))
  338. self.assertEqual(results['img'].shape[:2], (1342, 1342))
  339. self.assertEqual(results['gt_masks'].masks.shape[1:], (1342, 1342))
  340. def test_repr(self):
  341. transform = Pad(
  342. pad_to_square=True, size_divisor=11, padding_mode='edge')
  343. self.assertEqual(
  344. repr(transform),
  345. ('Pad(size=None, size_divisor=11, pad_to_square=True, '
  346. "pad_val={'img': 0, 'seg': 255}), padding_mode=edge)"))
  347. class TestMinIoURandomCrop(unittest.TestCase):
  348. def test_transform(self):
  349. results = dict()
  350. img = mmcv.imread(
  351. osp.join(osp.dirname(__file__), '../../data/color.jpg'), 'color')
  352. results['img'] = img
  353. results['img_shape'] = img.shape[:2]
  354. gt_bboxes = create_random_bboxes(1, results['img_shape'][1],
  355. results['img_shape'][0])
  356. results['gt_labels'] = np.ones(gt_bboxes.shape[0], dtype=np.int64)
  357. results['gt_bboxes'] = gt_bboxes
  358. transform = MinIoURandomCrop()
  359. results = transform.transform(copy.deepcopy(results))
  360. self.assertEqual(results['gt_labels'].shape[0],
  361. results['gt_bboxes'].shape[0])
  362. self.assertEqual(results['gt_labels'].dtype, np.int64)
  363. self.assertEqual(results['gt_bboxes'].dtype, np.float32)
  364. self.assertEqual(results['img_shape'], results['img'].shape[:2])
  365. patch = np.array(
  366. [0, 0, results['img_shape'][1], results['img_shape'][0]])
  367. ious = bbox_overlaps(patch.reshape(-1, 4),
  368. results['gt_bboxes']).reshape(-1)
  369. mode = transform.mode
  370. if mode == 1:
  371. self.assertTrue(np.equal(results['gt_bboxes'], gt_bboxes).all())
  372. else:
  373. self.assertTrue((ious >= mode).all())
  374. def test_transform_use_box_type(self):
  375. results = dict()
  376. img = mmcv.imread(
  377. osp.join(osp.dirname(__file__), '../../data/color.jpg'), 'color')
  378. results['img'] = img
  379. results['img_shape'] = img.shape[:2]
  380. gt_bboxes = create_random_bboxes(1, results['img_shape'][1],
  381. results['img_shape'][0])
  382. results['gt_labels'] = np.ones(gt_bboxes.shape[0], dtype=np.int64)
  383. results['gt_bboxes'] = HorizontalBoxes(gt_bboxes)
  384. transform = MinIoURandomCrop()
  385. results = transform.transform(copy.deepcopy(results))
  386. self.assertEqual(results['gt_labels'].shape[0],
  387. results['gt_bboxes'].shape[0])
  388. self.assertEqual(results['gt_labels'].dtype, np.int64)
  389. self.assertEqual(results['gt_bboxes'].dtype, torch.float32)
  390. patch = np.array(
  391. [0, 0, results['img_shape'][1], results['img_shape'][0]])
  392. ious = bbox_overlaps(
  393. patch.reshape(-1, 4), results['gt_bboxes'].numpy()).reshape(-1)
  394. mode = transform.mode
  395. if mode == 1:
  396. self.assertTrue((results['gt_bboxes'].numpy() == gt_bboxes).all())
  397. else:
  398. self.assertTrue((ious >= mode).all())
  399. def test_repr(self):
  400. transform = MinIoURandomCrop()
  401. self.assertEqual(
  402. repr(transform), ('MinIoURandomCrop'
  403. '(min_ious=(0.1, 0.3, 0.5, 0.7, 0.9), '
  404. 'min_crop_size=0.3, '
  405. 'bbox_clip_border=True)'))
  406. class TestPhotoMetricDistortion(unittest.TestCase):
  407. def test_transform(self):
  408. img = mmcv.imread(
  409. osp.join(osp.dirname(__file__), '../../data/color.jpg'), 'color')
  410. transform = PhotoMetricDistortion()
  411. # test uint8 input
  412. results = dict()
  413. results['img'] = img
  414. results = transform.transform(copy.deepcopy(results))
  415. self.assertEqual(results['img'].dtype, np.float32)
  416. # test float32 input
  417. results = dict()
  418. results['img'] = img.astype(np.float32)
  419. results = transform.transform(copy.deepcopy(results))
  420. self.assertEqual(results['img'].dtype, np.float32)
  421. def test_repr(self):
  422. transform = PhotoMetricDistortion()
  423. self.assertEqual(
  424. repr(transform), ('PhotoMetricDistortion'
  425. '(brightness_delta=32, '
  426. 'contrast_range=(0.5, 1.5), '
  427. 'saturation_range=(0.5, 1.5), '
  428. 'hue_delta=18)'))
  429. class TestExpand(unittest.TestCase):
  430. def setUp(self):
  431. """Setup the model and optimizer which are used in every test method.
  432. TestCase calls functions in this order: setUp() -> testMethod() ->
  433. tearDown() -> cleanUp()
  434. """
  435. rng = np.random.RandomState(0)
  436. self.results = {
  437. 'img': np.random.random((224, 224, 3)),
  438. 'img_shape': (224, 224),
  439. 'gt_bboxes': np.array([[0, 1, 100, 101]]),
  440. 'gt_masks':
  441. BitmapMasks(rng.rand(1, 224, 224), height=224, width=224),
  442. 'gt_seg_map': np.random.random((224, 224))
  443. }
  444. def test_transform(self):
  445. transform = Expand()
  446. results = transform.transform(copy.deepcopy(self.results))
  447. self.assertEqual(results['img_shape'], results['img'].shape[:2])
  448. self.assertEqual(
  449. results['img_shape'],
  450. (results['gt_masks'].height, results['gt_masks'].width))
  451. self.assertEqual(results['img_shape'], results['gt_seg_map'].shape)
  452. def test_transform_use_box_type(self):
  453. results = copy.deepcopy(self.results)
  454. results['gt_bboxes'] = HorizontalBoxes(results['gt_bboxes'])
  455. transform = Expand()
  456. results = transform.transform(results)
  457. self.assertEqual(
  458. results['img_shape'],
  459. (results['gt_masks'].height, results['gt_masks'].width))
  460. self.assertEqual(results['img_shape'], results['gt_seg_map'].shape)
  461. def test_repr(self):
  462. transform = Expand()
  463. self.assertEqual(
  464. repr(transform), ('Expand'
  465. '(mean=(0, 0, 0), to_rgb=True, '
  466. 'ratio_range=(1, 4), '
  467. 'seg_ignore_label=None, '
  468. 'prob=0.5)'))
  469. class TestSegRescale(unittest.TestCase):
  470. def setUp(self) -> None:
  471. seg_map = np.random.randint(0, 255, size=(32, 32), dtype=np.int32)
  472. self.results = {'gt_seg_map': seg_map}
  473. def test_transform(self):
  474. # test scale_factor != 1
  475. transform = SegRescale(scale_factor=2)
  476. results = transform(copy.deepcopy(self.results))
  477. self.assertEqual(results['gt_seg_map'].shape[:2], (64, 64))
  478. # test scale_factor = 1
  479. transform = SegRescale(scale_factor=1)
  480. results = transform(copy.deepcopy(self.results))
  481. self.assertEqual(results['gt_seg_map'].shape[:2], (32, 32))
  482. def test_repr(self):
  483. transform = SegRescale(scale_factor=2)
  484. self.assertEqual(
  485. repr(transform), ('SegRescale(scale_factor=2, backend=cv2)'))
  486. class TestRandomCrop(unittest.TestCase):
  487. def test_init(self):
  488. # test invalid crop_type
  489. with self.assertRaisesRegex(ValueError, 'Invalid crop_type'):
  490. RandomCrop(crop_size=(10, 10), crop_type='unknown')
  491. crop_type_list = ['absolute', 'absolute_range']
  492. for crop_type in crop_type_list:
  493. # test h > 0 and w > 0
  494. for crop_size in [(0, 0), (0, 1), (1, 0)]:
  495. with self.assertRaises(AssertionError):
  496. RandomCrop(crop_size=crop_size, crop_type=crop_type)
  497. # test type(h) = int and type(w) = int
  498. for crop_size in [(1.0, 1), (1, 1.0), (1.0, 1.0)]:
  499. with self.assertRaises(AssertionError):
  500. RandomCrop(crop_size=crop_size, crop_type=crop_type)
  501. # test crop_size[0] <= crop_size[1]
  502. with self.assertRaises(AssertionError):
  503. RandomCrop(crop_size=(10, 5), crop_type='absolute_range')
  504. # test h in (0, 1] and w in (0, 1]
  505. crop_type_list = ['relative_range', 'relative']
  506. for crop_type in crop_type_list:
  507. for crop_size in [(0, 1), (1, 0), (1.1, 0.5), (0.5, 1.1)]:
  508. with self.assertRaises(AssertionError):
  509. RandomCrop(crop_size=crop_size, crop_type=crop_type)
  510. def test_transform(self):
  511. # test relative and absolute crop
  512. src_results = {
  513. 'img': np.random.randint(0, 255, size=(24, 32), dtype=np.int32)
  514. }
  515. target_shape = (12, 16)
  516. for crop_type, crop_size in zip(['relative', 'absolute'], [(0.5, 0.5),
  517. (16, 12)]):
  518. transform = RandomCrop(crop_size=crop_size, crop_type=crop_type)
  519. results = transform(copy.deepcopy(src_results))
  520. print(results['img'].shape[:2])
  521. self.assertEqual(results['img'].shape[:2], target_shape)
  522. # test absolute_range crop
  523. transform = RandomCrop(crop_size=(10, 20), crop_type='absolute_range')
  524. results = transform(copy.deepcopy(src_results))
  525. h, w = results['img'].shape
  526. self.assertTrue(10 <= w <= 20)
  527. self.assertTrue(10 <= h <= 20)
  528. self.assertEqual(results['img_shape'], results['img'].shape[:2])
  529. # test relative_range crop
  530. transform = RandomCrop(
  531. crop_size=(0.5, 0.5), crop_type='relative_range')
  532. results = transform(copy.deepcopy(src_results))
  533. h, w = results['img'].shape
  534. self.assertTrue(16 <= w <= 32)
  535. self.assertTrue(12 <= h <= 24)
  536. self.assertEqual(results['img_shape'], results['img'].shape[:2])
  537. # test with gt_bboxes, gt_bboxes_labels, gt_ignore_flags,
  538. # gt_masks, gt_seg_map
  539. img = np.random.randint(0, 255, size=(10, 10), dtype=np.uint8)
  540. gt_bboxes = np.array([[0, 0, 7, 7], [2, 3, 9, 9]], dtype=np.float32)
  541. gt_bboxes_labels = np.array([0, 1], dtype=np.int64)
  542. gt_ignore_flags = np.array([0, 1], dtype=bool)
  543. gt_masks_ = np.zeros((2, 10, 10), np.uint8)
  544. gt_masks_[0, 0:7, 0:7] = 1
  545. gt_masks_[1, 2:7, 3:8] = 1
  546. gt_masks = BitmapMasks(gt_masks_.copy(), height=10, width=10)
  547. gt_seg_map = np.random.randint(0, 255, size=(10, 10), dtype=np.uint8)
  548. src_results = {
  549. 'img': img,
  550. 'gt_bboxes': gt_bboxes,
  551. 'gt_bboxes_labels': gt_bboxes_labels,
  552. 'gt_ignore_flags': gt_ignore_flags,
  553. 'gt_masks': gt_masks,
  554. 'gt_seg_map': gt_seg_map
  555. }
  556. transform = RandomCrop(
  557. crop_size=(7, 5),
  558. allow_negative_crop=False,
  559. recompute_bbox=False,
  560. bbox_clip_border=True)
  561. results = transform(copy.deepcopy(src_results))
  562. h, w = results['img'].shape
  563. self.assertEqual(h, 5)
  564. self.assertEqual(w, 7)
  565. self.assertEqual(results['gt_bboxes'].shape[0], 2)
  566. self.assertEqual(results['gt_bboxes_labels'].shape[0], 2)
  567. self.assertEqual(results['gt_ignore_flags'].shape[0], 2)
  568. self.assertTupleEqual(results['gt_seg_map'].shape[:2], (5, 7))
  569. self.assertEqual(results['img_shape'], results['img'].shape[:2])
  570. # test geometric transformation with homography matrix
  571. bboxes = copy.deepcopy(src_results['gt_bboxes'])
  572. self.assertTrue((bbox_project(bboxes, results['homography_matrix'],
  573. (5, 7)) == results['gt_bboxes']).all())
  574. # test recompute_bbox = True
  575. gt_masks_ = np.zeros((2, 10, 10), np.uint8)
  576. gt_masks = BitmapMasks(gt_masks_.copy(), height=10, width=10)
  577. gt_bboxes = np.array([[0.1, 0.1, 0.2, 0.2]])
  578. src_results = {
  579. 'img': img,
  580. 'gt_bboxes': gt_bboxes,
  581. 'gt_masks': gt_masks
  582. }
  583. target_gt_bboxes = np.zeros((1, 4), dtype=np.float32)
  584. transform = RandomCrop(
  585. crop_size=(10, 11),
  586. allow_negative_crop=False,
  587. recompute_bbox=True,
  588. bbox_clip_border=True)
  589. results = transform(copy.deepcopy(src_results))
  590. self.assertTrue((results['gt_bboxes'] == target_gt_bboxes).all())
  591. # test bbox_clip_border = False
  592. src_results = {'img': img, 'gt_bboxes': gt_bboxes}
  593. transform = RandomCrop(
  594. crop_size=(10, 11),
  595. allow_negative_crop=False,
  596. recompute_bbox=True,
  597. bbox_clip_border=False)
  598. results = transform(copy.deepcopy(src_results))
  599. self.assertTrue(
  600. (results['gt_bboxes'] == src_results['gt_bboxes']).all())
  601. # test the crop does not contain any gt-bbox
  602. # allow_negative_crop = False
  603. img = np.random.randint(0, 255, size=(10, 10), dtype=np.uint8)
  604. gt_bboxes = np.zeros((0, 4), dtype=np.float32)
  605. src_results = {'img': img, 'gt_bboxes': gt_bboxes}
  606. transform = RandomCrop(crop_size=(5, 3), allow_negative_crop=False)
  607. results = transform(copy.deepcopy(src_results))
  608. self.assertIsNone(results)
  609. # allow_negative_crop = True
  610. img = np.random.randint(0, 255, size=(10, 10), dtype=np.uint8)
  611. gt_bboxes = np.zeros((0, 4), dtype=np.float32)
  612. src_results = {'img': img, 'gt_bboxes': gt_bboxes}
  613. transform = RandomCrop(crop_size=(5, 3), allow_negative_crop=True)
  614. results = transform(copy.deepcopy(src_results))
  615. self.assertTrue(isinstance(results, dict))
  616. def test_transform_use_box_type(self):
  617. # test with gt_bboxes, gt_bboxes_labels, gt_ignore_flags,
  618. # gt_masks, gt_seg_map
  619. img = np.random.randint(0, 255, size=(10, 10), dtype=np.uint8)
  620. gt_bboxes = np.array([[0, 0, 7, 7], [2, 3, 9, 9]], dtype=np.float32)
  621. gt_bboxes_labels = np.array([0, 1], dtype=np.int64)
  622. gt_ignore_flags = np.array([0, 1], dtype=bool)
  623. gt_masks_ = np.zeros((2, 10, 10), np.uint8)
  624. gt_masks_[0, 0:7, 0:7] = 1
  625. gt_masks_[1, 2:7, 3:8] = 1
  626. gt_masks = BitmapMasks(gt_masks_.copy(), height=10, width=10)
  627. gt_seg_map = np.random.randint(0, 255, size=(10, 10), dtype=np.uint8)
  628. src_results = {
  629. 'img': img,
  630. 'gt_bboxes': HorizontalBoxes(gt_bboxes),
  631. 'gt_bboxes_labels': gt_bboxes_labels,
  632. 'gt_ignore_flags': gt_ignore_flags,
  633. 'gt_masks': gt_masks,
  634. 'gt_seg_map': gt_seg_map
  635. }
  636. transform = RandomCrop(
  637. crop_size=(7, 5),
  638. allow_negative_crop=False,
  639. recompute_bbox=False,
  640. bbox_clip_border=True)
  641. results = transform(copy.deepcopy(src_results))
  642. h, w = results['img'].shape
  643. self.assertEqual(h, 5)
  644. self.assertEqual(w, 7)
  645. self.assertEqual(results['gt_bboxes'].shape[0], 2)
  646. self.assertEqual(results['gt_bboxes_labels'].shape[0], 2)
  647. self.assertEqual(results['gt_ignore_flags'].shape[0], 2)
  648. self.assertTupleEqual(results['gt_seg_map'].shape[:2], (5, 7))
  649. # test geometric transformation with homography matrix
  650. bboxes = copy.deepcopy(src_results['gt_bboxes'].numpy())
  651. print(bboxes, results['gt_bboxes'])
  652. self.assertTrue(
  653. (bbox_project(bboxes, results['homography_matrix'],
  654. (5, 7)) == results['gt_bboxes'].numpy()).all())
  655. # test recompute_bbox = True
  656. gt_masks_ = np.zeros((2, 10, 10), np.uint8)
  657. gt_masks = BitmapMasks(gt_masks_.copy(), height=10, width=10)
  658. gt_bboxes = HorizontalBoxes(np.array([[0.1, 0.1, 0.2, 0.2]]))
  659. src_results = {
  660. 'img': img,
  661. 'gt_bboxes': gt_bboxes,
  662. 'gt_masks': gt_masks
  663. }
  664. target_gt_bboxes = np.zeros((1, 4), dtype=np.float32)
  665. transform = RandomCrop(
  666. crop_size=(10, 11),
  667. allow_negative_crop=False,
  668. recompute_bbox=True,
  669. bbox_clip_border=True)
  670. results = transform(copy.deepcopy(src_results))
  671. self.assertTrue(
  672. (results['gt_bboxes'].numpy() == target_gt_bboxes).all())
  673. # test bbox_clip_border = False
  674. src_results = {'img': img, 'gt_bboxes': gt_bboxes}
  675. transform = RandomCrop(
  676. crop_size=(10, 10),
  677. allow_negative_crop=False,
  678. recompute_bbox=True,
  679. bbox_clip_border=False)
  680. results = transform(copy.deepcopy(src_results))
  681. self.assertTrue(
  682. (results['gt_bboxes'].numpy() == src_results['gt_bboxes'].numpy()
  683. ).all())
  684. # test the crop does not contain any gt-bbox
  685. # allow_negative_crop = False
  686. img = np.random.randint(0, 255, size=(10, 10), dtype=np.uint8)
  687. gt_bboxes = HorizontalBoxes(np.zeros((0, 4), dtype=np.float32))
  688. src_results = {'img': img, 'gt_bboxes': gt_bboxes}
  689. transform = RandomCrop(crop_size=(5, 2), allow_negative_crop=False)
  690. results = transform(copy.deepcopy(src_results))
  691. self.assertIsNone(results)
  692. # allow_negative_crop = True
  693. img = np.random.randint(0, 255, size=(10, 10), dtype=np.uint8)
  694. gt_bboxes = HorizontalBoxes(np.zeros((0, 4), dtype=np.float32))
  695. src_results = {'img': img, 'gt_bboxes': gt_bboxes}
  696. transform = RandomCrop(crop_size=(5, 2), allow_negative_crop=True)
  697. results = transform(copy.deepcopy(src_results))
  698. self.assertTrue(isinstance(results, dict))
  699. def test_repr(self):
  700. crop_type = 'absolute'
  701. crop_size = (10, 5)
  702. allow_negative_crop = False
  703. recompute_bbox = True
  704. bbox_clip_border = False
  705. transform = RandomCrop(
  706. crop_size=crop_size,
  707. crop_type=crop_type,
  708. allow_negative_crop=allow_negative_crop,
  709. recompute_bbox=recompute_bbox,
  710. bbox_clip_border=bbox_clip_border)
  711. self.assertEqual(
  712. repr(transform),
  713. f'RandomCrop(crop_size={crop_size}, crop_type={crop_type}, '
  714. f'allow_negative_crop={allow_negative_crop}, '
  715. f'recompute_bbox={recompute_bbox}, '
  716. f'bbox_clip_border={bbox_clip_border})')
  717. class TestCutOut(unittest.TestCase):
  718. def setUp(self):
  719. """Setup the model and optimizer which are used in every test method.
  720. TestCase calls functions in this order: setUp() -> testMethod() ->
  721. tearDown() -> cleanUp()
  722. """
  723. img = mmcv.imread(
  724. osp.join(osp.dirname(__file__), '../../data/color.jpg'), 'color')
  725. self.results = {'img': img}
  726. def test_transform(self):
  727. # test n_holes
  728. with self.assertRaises(AssertionError):
  729. transform = CutOut(n_holes=(5, 3), cutout_shape=(8, 8))
  730. with self.assertRaises(AssertionError):
  731. transform = CutOut(n_holes=(3, 4, 5), cutout_shape=(8, 8))
  732. # test cutout_shape and cutout_ratio
  733. with self.assertRaises(AssertionError):
  734. transform = CutOut(n_holes=1, cutout_shape=8)
  735. with self.assertRaises(AssertionError):
  736. transform = CutOut(n_holes=1, cutout_ratio=0.2)
  737. # either of cutout_shape and cutout_ratio should be given
  738. with self.assertRaises(AssertionError):
  739. transform = CutOut(n_holes=1)
  740. with self.assertRaises(AssertionError):
  741. transform = CutOut(
  742. n_holes=1, cutout_shape=(2, 2), cutout_ratio=(0.4, 0.4))
  743. transform = CutOut(n_holes=1, cutout_shape=(10, 10))
  744. results = transform(copy.deepcopy(self.results))
  745. self.assertTrue(results['img'].sum() < self.results['img'].sum())
  746. transform = CutOut(
  747. n_holes=(2, 4),
  748. cutout_shape=[(10, 10), (15, 15)],
  749. fill_in=(255, 255, 255))
  750. results = transform(copy.deepcopy(self.results))
  751. self.assertTrue(results['img'].sum() > self.results['img'].sum())
  752. transform = CutOut(
  753. n_holes=1, cutout_ratio=(0.8, 0.8), fill_in=(255, 255, 255))
  754. results = transform(copy.deepcopy(self.results))
  755. self.assertTrue(results['img'].sum() > self.results['img'].sum())
  756. def test_repr(self):
  757. transform = CutOut(n_holes=1, cutout_shape=(10, 10))
  758. self.assertEqual(
  759. repr(transform), ('CutOut(n_holes=(1, 1), '
  760. 'cutout_shape=[(10, 10)], '
  761. 'fill_in=(0, 0, 0))'))
  762. transform = CutOut(
  763. n_holes=1, cutout_ratio=(0.8, 0.8), fill_in=(255, 255, 255))
  764. self.assertEqual(
  765. repr(transform), ('CutOut(n_holes=(1, 1), '
  766. 'cutout_ratio=[(0.8, 0.8)], '
  767. 'fill_in=(255, 255, 255))'))
  768. class TestMosaic(unittest.TestCase):
  769. def setUp(self):
  770. """Setup the model and optimizer which are used in every test method.
  771. TestCase calls functions in this order: setUp() -> testMethod() ->
  772. tearDown() -> cleanUp()
  773. """
  774. rng = np.random.RandomState(0)
  775. self.results = {
  776. 'img':
  777. np.random.random((224, 224, 3)),
  778. 'img_shape': (224, 224),
  779. 'gt_bboxes_labels':
  780. np.array([1, 2, 3], dtype=np.int64),
  781. 'gt_bboxes':
  782. np.array([[10, 10, 20, 20], [20, 20, 40, 40], [40, 40, 80, 80]],
  783. dtype=np.float32),
  784. 'gt_ignore_flags':
  785. np.array([0, 0, 1], dtype=bool),
  786. 'gt_masks':
  787. BitmapMasks(rng.rand(3, 224, 224), height=224, width=224),
  788. }
  789. def test_transform(self):
  790. # test assertion for invalid img_scale
  791. with self.assertRaises(AssertionError):
  792. transform = Mosaic(img_scale=640)
  793. # test assertion for invalid probability
  794. with self.assertRaises(AssertionError):
  795. transform = Mosaic(prob=1.5)
  796. transform = Mosaic(img_scale=(12, 10))
  797. # test assertion for invalid mix_results
  798. with self.assertRaises(AssertionError):
  799. results = transform(copy.deepcopy(self.results))
  800. self.results['mix_results'] = [copy.deepcopy(self.results)] * 3
  801. results = transform(copy.deepcopy(self.results))
  802. self.assertTrue(results['img'].shape[:2] == (20, 24))
  803. self.assertTrue(results['gt_bboxes_labels'].shape[0] ==
  804. results['gt_bboxes'].shape[0])
  805. self.assertTrue(results['gt_bboxes_labels'].dtype == np.int64)
  806. self.assertTrue(results['gt_bboxes'].dtype == np.float32)
  807. self.assertTrue(results['gt_ignore_flags'].dtype == bool)
  808. self.assertEqual(results['img_shape'], results['img'].shape[:2])
  809. def test_transform_with_no_gt(self):
  810. self.results['gt_bboxes'] = np.empty((0, 4), dtype=np.float32)
  811. self.results['gt_bboxes_labels'] = np.empty((0, ), dtype=np.int64)
  812. self.results['gt_ignore_flags'] = np.empty((0, ), dtype=bool)
  813. transform = Mosaic(img_scale=(12, 10))
  814. self.results['mix_results'] = [copy.deepcopy(self.results)] * 3
  815. results = transform(copy.deepcopy(self.results))
  816. self.assertIsInstance(results, dict)
  817. self.assertTrue(results['img'].shape[:2] == (20, 24))
  818. self.assertTrue(
  819. results['gt_bboxes_labels'].shape[0] == results['gt_bboxes'].
  820. shape[0] == results['gt_ignore_flags'].shape[0] == 0)
  821. self.assertTrue(results['gt_bboxes_labels'].dtype == np.int64)
  822. self.assertTrue(results['gt_bboxes'].dtype == np.float32)
  823. self.assertTrue(results['gt_ignore_flags'].dtype == bool)
  824. def test_transform_use_box_type(self):
  825. transform = Mosaic(img_scale=(12, 10))
  826. results = copy.deepcopy(self.results)
  827. results['gt_bboxes'] = HorizontalBoxes(results['gt_bboxes'])
  828. results['mix_results'] = [results] * 3
  829. results = transform(results)
  830. self.assertTrue(results['img'].shape[:2] == (20, 24))
  831. self.assertTrue(results['gt_bboxes_labels'].shape[0] ==
  832. results['gt_bboxes'].shape[0])
  833. self.assertTrue(results['gt_bboxes_labels'].dtype == np.int64)
  834. self.assertTrue(results['gt_bboxes'].dtype == torch.float32)
  835. self.assertTrue(results['gt_ignore_flags'].dtype == bool)
  836. def test_repr(self):
  837. transform = Mosaic(img_scale=(640, 640), )
  838. self.assertEqual(
  839. repr(transform), ('Mosaic(img_scale=(640, 640), '
  840. 'center_ratio_range=(0.5, 1.5), '
  841. 'pad_val=114.0, '
  842. 'prob=1.0)'))
  843. class TestMixUp(unittest.TestCase):
  844. def setUp(self):
  845. """Setup the model and optimizer which are used in every test method.
  846. TestCase calls functions in this order: setUp() -> testMethod() ->
  847. tearDown() -> cleanUp()
  848. """
  849. rng = np.random.RandomState(0)
  850. self.results = {
  851. 'img':
  852. np.random.random((224, 224, 3)),
  853. 'img_shape': (224, 224),
  854. 'gt_bboxes_labels':
  855. np.array([1, 2, 3], dtype=np.int64),
  856. 'gt_bboxes':
  857. np.array([[10, 10, 20, 20], [20, 20, 40, 40], [40, 40, 80, 80]],
  858. dtype=np.float32),
  859. 'gt_ignore_flags':
  860. np.array([0, 0, 1], dtype=bool),
  861. 'gt_masks':
  862. BitmapMasks(rng.rand(3, 224, 224), height=224, width=224),
  863. }
  864. def test_transform(self):
  865. # test assertion for invalid img_scale
  866. with self.assertRaises(AssertionError):
  867. transform = MixUp(img_scale=640)
  868. transform = MixUp(img_scale=(12, 10))
  869. # test assertion for invalid mix_results
  870. with self.assertRaises(AssertionError):
  871. results = transform(copy.deepcopy(self.results))
  872. with self.assertRaises(AssertionError):
  873. self.results['mix_results'] = [copy.deepcopy(self.results)] * 2
  874. results = transform(copy.deepcopy(self.results))
  875. self.results['mix_results'] = [copy.deepcopy(self.results)]
  876. results = transform(copy.deepcopy(self.results))
  877. self.assertTrue(results['img'].shape[:2] == (224, 224))
  878. self.assertTrue(results['gt_bboxes_labels'].shape[0] ==
  879. results['gt_bboxes'].shape[0])
  880. self.assertTrue(results['gt_bboxes_labels'].dtype == np.int64)
  881. self.assertTrue(results['gt_bboxes'].dtype == np.float32)
  882. self.assertTrue(results['gt_ignore_flags'].dtype == bool)
  883. self.assertEqual(results['img_shape'], results['img'].shape[:2])
  884. def test_transform_use_box_type(self):
  885. results = copy.deepcopy(self.results)
  886. results['gt_bboxes'] = HorizontalBoxes(results['gt_bboxes'])
  887. transform = MixUp(img_scale=(12, 10))
  888. results['mix_results'] = [results]
  889. results = transform(results)
  890. self.assertTrue(results['img'].shape[:2] == (224, 224))
  891. self.assertTrue(results['gt_bboxes_labels'].shape[0] ==
  892. results['gt_bboxes'].shape[0])
  893. self.assertTrue(results['gt_bboxes_labels'].dtype == np.int64)
  894. self.assertTrue(results['gt_bboxes'].dtype == torch.float32)
  895. self.assertTrue(results['gt_ignore_flags'].dtype == bool)
  896. def test_repr(self):
  897. transform = MixUp(
  898. img_scale=(640, 640),
  899. ratio_range=(0.8, 1.6),
  900. pad_val=114.0,
  901. )
  902. self.assertEqual(
  903. repr(transform), ('MixUp(dynamic_scale=(640, 640), '
  904. 'ratio_range=(0.8, 1.6), '
  905. 'flip_ratio=0.5, '
  906. 'pad_val=114.0, '
  907. 'max_iters=15, '
  908. 'bbox_clip_border=True)'))
  909. class TestRandomAffine(unittest.TestCase):
  910. def setUp(self):
  911. """Setup the model and optimizer which are used in every test method.
  912. TestCase calls functions in this order: setUp() -> testMethod() ->
  913. tearDown() -> cleanUp()
  914. """
  915. self.results = {
  916. 'img':
  917. np.random.random((224, 224, 3)),
  918. 'img_shape': (224, 224),
  919. 'gt_bboxes_labels':
  920. np.array([1, 2, 3], dtype=np.int64),
  921. 'gt_bboxes':
  922. np.array([[10, 10, 20, 20], [20, 20, 40, 40], [40, 40, 80, 80]],
  923. dtype=np.float32),
  924. 'gt_ignore_flags':
  925. np.array([0, 0, 1], dtype=bool),
  926. }
  927. def test_transform(self):
  928. # test assertion for invalid translate_ratio
  929. with self.assertRaises(AssertionError):
  930. transform = RandomAffine(max_translate_ratio=1.5)
  931. # test assertion for invalid scaling_ratio_range
  932. with self.assertRaises(AssertionError):
  933. transform = RandomAffine(scaling_ratio_range=(1.5, 0.5))
  934. with self.assertRaises(AssertionError):
  935. transform = RandomAffine(scaling_ratio_range=(0, 0.5))
  936. transform = RandomAffine()
  937. results = transform(copy.deepcopy(self.results))
  938. self.assertTrue(results['img'].shape[:2] == (224, 224))
  939. self.assertTrue(results['gt_bboxes_labels'].shape[0] ==
  940. results['gt_bboxes'].shape[0])
  941. self.assertTrue(results['gt_bboxes_labels'].dtype == np.int64)
  942. self.assertTrue(results['gt_bboxes'].dtype == np.float32)
  943. self.assertTrue(results['gt_ignore_flags'].dtype == bool)
  944. self.assertEqual(results['img_shape'], results['img'].shape[:2])
  945. def test_transform_use_box_type(self):
  946. results = copy.deepcopy(self.results)
  947. results['gt_bboxes'] = HorizontalBoxes(results['gt_bboxes'])
  948. transform = RandomAffine()
  949. results = transform(copy.deepcopy(results))
  950. self.assertTrue(results['img'].shape[:2] == (224, 224))
  951. self.assertTrue(results['gt_bboxes_labels'].shape[0] ==
  952. results['gt_bboxes'].shape[0])
  953. self.assertTrue(results['gt_bboxes_labels'].dtype == np.int64)
  954. self.assertTrue(results['gt_bboxes'].dtype == torch.float32)
  955. self.assertTrue(results['gt_ignore_flags'].dtype == bool)
  956. def test_repr(self):
  957. transform = RandomAffine(
  958. scaling_ratio_range=(0.1, 2),
  959. border=(-320, -320),
  960. )
  961. self.assertEqual(
  962. repr(transform), ('RandomAffine(max_rotate_degree=10.0, '
  963. 'max_translate_ratio=0.1, '
  964. 'scaling_ratio_range=(0.1, 2), '
  965. 'max_shear_degree=2.0, '
  966. 'border=(-320, -320), '
  967. 'border_val=(114, 114, 114), '
  968. 'bbox_clip_border=True)'))
  969. class TestYOLOXHSVRandomAug(unittest.TestCase):
  970. def setUp(self):
  971. """Setup the model and optimizer which are used in every test method.
  972. TestCase calls functions in this order: setUp() -> testMethod() ->
  973. tearDown() -> cleanUp()
  974. """
  975. img = mmcv.imread(
  976. osp.join(osp.dirname(__file__), '../../data/color.jpg'), 'color')
  977. self.results = {
  978. 'img':
  979. img,
  980. 'img_shape': (224, 224),
  981. 'gt_bboxes_labels':
  982. np.array([1, 2, 3], dtype=np.int64),
  983. 'gt_bboxes':
  984. np.array([[10, 10, 20, 20], [20, 20, 40, 40], [40, 40, 80, 80]],
  985. dtype=np.float32),
  986. 'gt_ignore_flags':
  987. np.array([0, 0, 1], dtype=bool),
  988. }
  989. def test_transform(self):
  990. transform = YOLOXHSVRandomAug()
  991. results = transform(copy.deepcopy(self.results))
  992. self.assertTrue(
  993. results['img'].shape[:2] == self.results['img'].shape[:2])
  994. self.assertTrue(results['gt_bboxes_labels'].shape[0] ==
  995. results['gt_bboxes'].shape[0])
  996. self.assertTrue(results['gt_bboxes_labels'].dtype == np.int64)
  997. self.assertTrue(results['gt_bboxes'].dtype == np.float32)
  998. self.assertTrue(results['gt_ignore_flags'].dtype == bool)
  999. def test_repr(self):
  1000. transform = YOLOXHSVRandomAug()
  1001. self.assertEqual(
  1002. repr(transform), ('YOLOXHSVRandomAug(hue_delta=5, '
  1003. 'saturation_delta=30, '
  1004. 'value_delta=30)'))
  1005. class TestRandomCenterCropPad(unittest.TestCase):
  1006. def test_init(self):
  1007. # test assertion for invalid crop_size while test_mode=False
  1008. with self.assertRaises(AssertionError):
  1009. RandomCenterCropPad(
  1010. crop_size=(-1, 0), test_mode=False, test_pad_mode=None)
  1011. # test assertion for invalid ratios while test_mode=False
  1012. with self.assertRaises(AssertionError):
  1013. RandomCenterCropPad(
  1014. crop_size=(511, 511),
  1015. ratios=(1.0, 1.0),
  1016. test_mode=False,
  1017. test_pad_mode=None)
  1018. # test assertion for invalid mean, std and to_rgb
  1019. with self.assertRaises(AssertionError):
  1020. RandomCenterCropPad(
  1021. crop_size=(511, 511),
  1022. mean=None,
  1023. std=None,
  1024. to_rgb=None,
  1025. test_mode=False,
  1026. test_pad_mode=None)
  1027. # test assertion for invalid crop_size while test_mode=True
  1028. with self.assertRaises(AssertionError):
  1029. RandomCenterCropPad(
  1030. crop_size=(511, 511),
  1031. ratios=None,
  1032. border=None,
  1033. mean=[123.675, 116.28, 103.53],
  1034. std=[58.395, 57.12, 57.375],
  1035. to_rgb=True,
  1036. test_mode=True,
  1037. test_pad_mode=('logical_or', 127))
  1038. # test assertion for invalid ratios while test_mode=True
  1039. with self.assertRaises(AssertionError):
  1040. RandomCenterCropPad(
  1041. crop_size=None,
  1042. ratios=(0.9, 1.0, 1.1),
  1043. border=None,
  1044. mean=[123.675, 116.28, 103.53],
  1045. std=[58.395, 57.12, 57.375],
  1046. to_rgb=True,
  1047. test_mode=True,
  1048. test_pad_mode=('logical_or', 127))
  1049. # test assertion for invalid border while test_mode=True
  1050. with self.assertRaises(AssertionError):
  1051. RandomCenterCropPad(
  1052. crop_size=None,
  1053. ratios=None,
  1054. border=128,
  1055. mean=[123.675, 116.28, 103.53],
  1056. std=[58.395, 57.12, 57.375],
  1057. to_rgb=True,
  1058. test_mode=True,
  1059. test_pad_mode=('logical_or', 127))
  1060. # test assertion for invalid test_pad_mode while test_mode=True
  1061. with self.assertRaises(AssertionError):
  1062. RandomCenterCropPad(
  1063. crop_size=None,
  1064. ratios=None,
  1065. border=None,
  1066. mean=[123.675, 116.28, 103.53],
  1067. std=[58.395, 57.12, 57.375],
  1068. to_rgb=True,
  1069. test_mode=True,
  1070. test_pad_mode=('do_nothing', 100))
  1071. def test_transform(self):
  1072. results = dict(
  1073. img_path=osp.join(osp.dirname(__file__), '../../data/color.jpg'))
  1074. load = LoadImageFromFile(to_float32=True)
  1075. results = load(results)
  1076. test_results = copy.deepcopy(results)
  1077. h, w = results['img_shape']
  1078. gt_bboxes = create_random_bboxes(4, w, h)
  1079. gt_bboxes_labels = np.array([1, 2, 3, 1], dtype=np.int64)
  1080. gt_ignore_flags = np.array([0, 0, 1, 1], dtype=bool)
  1081. results['gt_bboxes'] = gt_bboxes
  1082. results['gt_bboxes_labels'] = gt_bboxes_labels
  1083. results['gt_ignore_flags'] = gt_ignore_flags
  1084. crop_module = RandomCenterCropPad(
  1085. crop_size=(w - 20, h - 20),
  1086. ratios=(1.0, ),
  1087. border=128,
  1088. mean=[123.675, 116.28, 103.53],
  1089. std=[58.395, 57.12, 57.375],
  1090. to_rgb=True,
  1091. test_mode=False,
  1092. test_pad_mode=None)
  1093. train_results = crop_module(results)
  1094. assert train_results['img'].shape[:2] == (h - 20, w - 20)
  1095. # All bboxes should be reserved after crop
  1096. assert train_results['img_shape'][:2] == (h - 20, w - 20)
  1097. assert train_results['gt_bboxes'].shape[0] == 4
  1098. assert train_results['gt_bboxes'].dtype == np.float32
  1099. self.assertEqual(results['img_shape'], results['img'].shape[:2])
  1100. crop_module = RandomCenterCropPad(
  1101. crop_size=None,
  1102. ratios=None,
  1103. border=None,
  1104. mean=[123.675, 116.28, 103.53],
  1105. std=[58.395, 57.12, 57.375],
  1106. to_rgb=True,
  1107. test_mode=True,
  1108. test_pad_mode=('logical_or', 127))
  1109. test_results = crop_module(test_results)
  1110. assert test_results['img'].shape[:2] == (h | 127, w | 127)
  1111. assert test_results['img_shape'][:2] == (h | 127, w | 127)
  1112. assert 'border' in test_results
  1113. def test_transform_use_box_type(self):
  1114. results = dict(
  1115. img_path=osp.join(osp.dirname(__file__), '../../data/color.jpg'))
  1116. load = LoadImageFromFile(to_float32=True)
  1117. results = load(results)
  1118. test_results = copy.deepcopy(results)
  1119. h, w = results['img_shape']
  1120. gt_bboxes = create_random_bboxes(4, w, h)
  1121. gt_bboxes_labels = np.array([1, 2, 3, 1], dtype=np.int64)
  1122. gt_ignore_flags = np.array([0, 0, 1, 1], dtype=bool)
  1123. results['gt_bboxes'] = HorizontalBoxes(gt_bboxes)
  1124. results['gt_bboxes_labels'] = gt_bboxes_labels
  1125. results['gt_ignore_flags'] = gt_ignore_flags
  1126. crop_module = RandomCenterCropPad(
  1127. crop_size=(w - 20, h - 20),
  1128. ratios=(1.0, ),
  1129. border=128,
  1130. mean=[123.675, 116.28, 103.53],
  1131. std=[58.395, 57.12, 57.375],
  1132. to_rgb=True,
  1133. test_mode=False,
  1134. test_pad_mode=None)
  1135. train_results = crop_module(results)
  1136. assert train_results['img'].shape[:2] == (h - 20, w - 20)
  1137. # All bboxes should be reserved after crop
  1138. assert train_results['img_shape'][:2] == (h - 20, w - 20)
  1139. assert train_results['gt_bboxes'].shape[0] == 4
  1140. assert train_results['gt_bboxes'].dtype == torch.float32
  1141. crop_module = RandomCenterCropPad(
  1142. crop_size=None,
  1143. ratios=None,
  1144. border=None,
  1145. mean=[123.675, 116.28, 103.53],
  1146. std=[58.395, 57.12, 57.375],
  1147. to_rgb=True,
  1148. test_mode=True,
  1149. test_pad_mode=('logical_or', 127))
  1150. test_results = crop_module(test_results)
  1151. assert test_results['img'].shape[:2] == (h | 127, w | 127)
  1152. assert test_results['img_shape'][:2] == (h | 127, w | 127)
  1153. assert 'border' in test_results
  1154. class TestCopyPaste(unittest.TestCase):
  1155. def setUp(self):
  1156. """Setup the model and optimizer which are used in every test method.
  1157. TestCase calls functions in this order: setUp() -> testMethod() ->
  1158. tearDown() -> cleanUp()
  1159. """
  1160. img = mmcv.imread(
  1161. osp.join(osp.dirname(__file__), '../../data/color.jpg'), 'color')
  1162. h, w, _ = img.shape
  1163. dst_bboxes = np.array([[0.2 * w, 0.2 * h, 0.4 * w, 0.4 * h],
  1164. [0.5 * w, 0.5 * h, 0.6 * w, 0.6 * h]],
  1165. dtype=np.float32)
  1166. src_bboxes = np.array([[0.1 * w, 0.1 * h, 0.3 * w, 0.5 * h],
  1167. [0.4 * w, 0.4 * h, 0.7 * w, 0.7 * h],
  1168. [0.8 * w, 0.8 * h, 0.9 * w, 0.9 * h]],
  1169. dtype=np.float32)
  1170. self.dst_results = {
  1171. 'img': img.copy(),
  1172. 'gt_bboxes': dst_bboxes,
  1173. 'gt_bboxes_labels': np.ones(dst_bboxes.shape[0], dtype=np.int64),
  1174. 'gt_masks': create_full_masks(dst_bboxes, w, h),
  1175. 'gt_ignore_flags': np.array([0, 1], dtype=bool),
  1176. }
  1177. self.src_results = {
  1178. 'img': img.copy(),
  1179. 'gt_bboxes': src_bboxes,
  1180. 'gt_bboxes_labels':
  1181. np.ones(src_bboxes.shape[0], dtype=np.int64) * 2,
  1182. 'gt_masks': create_full_masks(src_bboxes, w, h),
  1183. 'gt_ignore_flags': np.array([0, 0, 1], dtype=bool),
  1184. }
  1185. def test_transform(self):
  1186. transform = CopyPaste(selected=False)
  1187. # test assertion for invalid mix_results
  1188. with self.assertRaises(AssertionError):
  1189. results = transform(copy.deepcopy(self.dst_results))
  1190. results = copy.deepcopy(self.dst_results)
  1191. results['mix_results'] = [copy.deepcopy(self.src_results)]
  1192. results = transform(results)
  1193. self.assertEqual(results['img'].shape[:2],
  1194. self.dst_results['img'].shape[:2])
  1195. # one object of destination image is totally occluded
  1196. self.assertEqual(
  1197. results['gt_bboxes'].shape[0],
  1198. self.dst_results['gt_bboxes'].shape[0] +
  1199. self.src_results['gt_bboxes'].shape[0] - 1)
  1200. self.assertEqual(
  1201. results['gt_bboxes_labels'].shape[0],
  1202. self.dst_results['gt_bboxes_labels'].shape[0] +
  1203. self.src_results['gt_bboxes_labels'].shape[0] - 1)
  1204. self.assertEqual(
  1205. results['gt_masks'].masks.shape[0],
  1206. self.dst_results['gt_masks'].masks.shape[0] +
  1207. self.src_results['gt_masks'].masks.shape[0] - 1)
  1208. self.assertEqual(
  1209. results['gt_ignore_flags'].shape[0],
  1210. self.dst_results['gt_ignore_flags'].shape[0] +
  1211. self.src_results['gt_ignore_flags'].shape[0] - 1)
  1212. # the object of destination image is partially occluded
  1213. ori_bbox = self.dst_results['gt_bboxes'][0]
  1214. occ_bbox = results['gt_bboxes'][0]
  1215. ori_mask = self.dst_results['gt_masks'].masks[0]
  1216. occ_mask = results['gt_masks'].masks[0]
  1217. self.assertTrue(ori_mask.sum() > occ_mask.sum())
  1218. self.assertTrue(
  1219. np.all(np.abs(occ_bbox - ori_bbox) <= transform.bbox_occluded_thr)
  1220. or occ_mask.sum() > transform.mask_occluded_thr)
  1221. # test copypaste with selected objects
  1222. transform = CopyPaste()
  1223. results = copy.deepcopy(self.dst_results)
  1224. results['mix_results'] = [copy.deepcopy(self.src_results)]
  1225. results = transform(results)
  1226. # test copypaste with an empty source image
  1227. results = copy.deepcopy(self.dst_results)
  1228. valid_inds = [False] * self.src_results['gt_bboxes'].shape[0]
  1229. results['mix_results'] = [{
  1230. 'img':
  1231. self.src_results['img'].copy(),
  1232. 'gt_bboxes':
  1233. self.src_results['gt_bboxes'][valid_inds],
  1234. 'gt_bboxes_labels':
  1235. self.src_results['gt_bboxes_labels'][valid_inds],
  1236. 'gt_masks':
  1237. self.src_results['gt_masks'][valid_inds],
  1238. 'gt_ignore_flags':
  1239. self.src_results['gt_ignore_flags'][valid_inds],
  1240. }]
  1241. results = transform(results)
  1242. def test_transform_use_box_type(self):
  1243. src_results = copy.deepcopy(self.src_results)
  1244. src_results['gt_bboxes'] = HorizontalBoxes(src_results['gt_bboxes'])
  1245. dst_results = copy.deepcopy(self.dst_results)
  1246. dst_results['gt_bboxes'] = HorizontalBoxes(dst_results['gt_bboxes'])
  1247. transform = CopyPaste(selected=False)
  1248. results = copy.deepcopy(dst_results)
  1249. results['mix_results'] = [copy.deepcopy(src_results)]
  1250. results = transform(results)
  1251. self.assertEqual(results['img'].shape[:2],
  1252. self.dst_results['img'].shape[:2])
  1253. # one object of destination image is totally occluded
  1254. self.assertEqual(
  1255. results['gt_bboxes'].shape[0],
  1256. self.dst_results['gt_bboxes'].shape[0] +
  1257. self.src_results['gt_bboxes'].shape[0] - 1)
  1258. self.assertEqual(
  1259. results['gt_bboxes_labels'].shape[0],
  1260. self.dst_results['gt_bboxes_labels'].shape[0] +
  1261. self.src_results['gt_bboxes_labels'].shape[0] - 1)
  1262. self.assertEqual(
  1263. results['gt_masks'].masks.shape[0],
  1264. self.dst_results['gt_masks'].masks.shape[0] +
  1265. self.src_results['gt_masks'].masks.shape[0] - 1)
  1266. self.assertEqual(
  1267. results['gt_ignore_flags'].shape[0],
  1268. self.dst_results['gt_ignore_flags'].shape[0] +
  1269. self.src_results['gt_ignore_flags'].shape[0] - 1)
  1270. # the object of destination image is partially occluded
  1271. ori_bbox = dst_results['gt_bboxes'][0].numpy()
  1272. occ_bbox = results['gt_bboxes'][0].numpy()
  1273. ori_mask = dst_results['gt_masks'].masks[0]
  1274. occ_mask = results['gt_masks'].masks[0]
  1275. self.assertTrue(ori_mask.sum() > occ_mask.sum())
  1276. self.assertTrue(
  1277. np.all(np.abs(occ_bbox - ori_bbox) <= transform.bbox_occluded_thr)
  1278. or occ_mask.sum() > transform.mask_occluded_thr)
  1279. # test copypaste with selected objects
  1280. transform = CopyPaste()
  1281. results = copy.deepcopy(dst_results)
  1282. results['mix_results'] = [copy.deepcopy(src_results)]
  1283. results = transform(results)
  1284. # test copypaste with an empty source image
  1285. results = copy.deepcopy(dst_results)
  1286. valid_inds = [False] * self.src_results['gt_bboxes'].shape[0]
  1287. results['mix_results'] = [{
  1288. 'img':
  1289. src_results['img'].copy(),
  1290. 'gt_bboxes':
  1291. src_results['gt_bboxes'][valid_inds],
  1292. 'gt_bboxes_labels':
  1293. src_results['gt_bboxes_labels'][valid_inds],
  1294. 'gt_masks':
  1295. src_results['gt_masks'][valid_inds],
  1296. 'gt_ignore_flags':
  1297. src_results['gt_ignore_flags'][valid_inds],
  1298. }]
  1299. results = transform(results)
  1300. def test_repr(self):
  1301. transform = CopyPaste()
  1302. self.assertEqual(
  1303. repr(transform), ('CopyPaste(max_num_pasted=100, '
  1304. 'bbox_occluded_thr=10, '
  1305. 'mask_occluded_thr=300, '
  1306. 'selected=True)'))
  1307. class TestAlbu(unittest.TestCase):
  1308. @unittest.skipIf(albumentations is None, 'albumentations is not installed')
  1309. def test_transform(self):
  1310. results = dict(
  1311. img_path=osp.join(osp.dirname(__file__), '../../data/color.jpg'))
  1312. # Define simple pipeline
  1313. load = dict(type='LoadImageFromFile')
  1314. load = TRANSFORMS.build(load)
  1315. albu_transform = dict(
  1316. type='Albu', transforms=[dict(type='ChannelShuffle', p=1)])
  1317. albu_transform = TRANSFORMS.build(albu_transform)
  1318. # Execute transforms
  1319. results = load(results)
  1320. results = albu_transform(results)
  1321. self.assertEqual(results['img'].dtype, np.uint8)
  1322. # test bbox
  1323. albu_transform = dict(
  1324. type='Albu',
  1325. transforms=[dict(type='ChannelShuffle', p=1)],
  1326. bbox_params=dict(
  1327. type='BboxParams',
  1328. format='pascal_voc',
  1329. label_fields=['gt_bboxes_labels', 'gt_ignore_flags']),
  1330. keymap={
  1331. 'img': 'image',
  1332. 'gt_bboxes': 'bboxes'
  1333. })
  1334. albu_transform = TRANSFORMS.build(albu_transform)
  1335. results = {
  1336. 'img':
  1337. np.random.random((224, 224, 3)),
  1338. 'img_shape': (224, 224),
  1339. 'gt_bboxes_labels':
  1340. np.array([1, 2, 3], dtype=np.int64),
  1341. 'gt_bboxes':
  1342. np.array([[10, 10, 20, 20], [20, 20, 40, 40], [40, 40, 80, 80]],
  1343. dtype=np.float32),
  1344. 'gt_ignore_flags':
  1345. np.array([0, 0, 1], dtype=bool),
  1346. }
  1347. results = albu_transform(results)
  1348. self.assertEqual(results['img'].dtype, np.float64)
  1349. self.assertEqual(results['gt_bboxes'].dtype, np.float32)
  1350. self.assertEqual(results['gt_ignore_flags'].dtype, bool)
  1351. self.assertEqual(results['gt_bboxes_labels'].dtype, np.int64)
  1352. self.assertEqual(results['img_shape'], results['img'].shape[:2])
  1353. @unittest.skipIf(albumentations is None, 'albumentations is not installed')
  1354. def test_repr(self):
  1355. albu_transform = dict(
  1356. type='Albu', transforms=[dict(type='ChannelShuffle', p=1)])
  1357. albu_transform = TRANSFORMS.build(albu_transform)
  1358. self.assertEqual(
  1359. repr(albu_transform), 'Albu(transforms=['
  1360. '{\'type\': \'ChannelShuffle\', '
  1361. '\'p\': 1}])')
  1362. class TestCorrupt(unittest.TestCase):
  1363. def test_transform(self):
  1364. results = dict(
  1365. img_path=osp.join(osp.dirname(__file__), '../../data/color.jpg'))
  1366. # Define simple pipeline
  1367. load = dict(type='LoadImageFromFile')
  1368. load = TRANSFORMS.build(load)
  1369. corrupt_transform = dict(type='Corrupt', corruption='gaussian_blur')
  1370. corrupt_transform = TRANSFORMS.build(corrupt_transform)
  1371. # Execute transforms
  1372. results = load(results)
  1373. results = corrupt_transform(results)
  1374. self.assertEqual(results['img'].dtype, np.uint8)
  1375. def test_repr(self):
  1376. corrupt_transform = dict(type='Corrupt', corruption='gaussian_blur')
  1377. corrupt_transform = TRANSFORMS.build(corrupt_transform)
  1378. self.assertEqual(
  1379. repr(corrupt_transform), 'Corrupt(corruption=gaussian_blur, '
  1380. 'severity=1)')
  1381. class TestRandomShift(unittest.TestCase):
  1382. def test_init(self):
  1383. # test assertion for invalid shift_ratio
  1384. with self.assertRaises(AssertionError):
  1385. RandomShift(prob=1.5)
  1386. # test assertion for invalid max_shift_px
  1387. with self.assertRaises(AssertionError):
  1388. RandomShift(max_shift_px=-1)
  1389. def test_transform(self):
  1390. results = dict()
  1391. img = mmcv.imread(
  1392. osp.join(osp.dirname(__file__), '../../data/color.jpg'), 'color')
  1393. results['img'] = img
  1394. h, w, _ = img.shape
  1395. gt_bboxes = create_random_bboxes(8, w, h)
  1396. results['gt_bboxes_labels'] = np.ones(
  1397. gt_bboxes.shape[0], dtype=np.int64)
  1398. results['gt_bboxes'] = gt_bboxes
  1399. transform = RandomShift(prob=1.0)
  1400. results = transform(results)
  1401. self.assertEqual(results['img'].shape[:2], (h, w))
  1402. self.assertEqual(results['gt_bboxes_labels'].shape[0],
  1403. results['gt_bboxes'].shape[0])
  1404. self.assertEqual(results['gt_bboxes_labels'].dtype, np.int64)
  1405. self.assertEqual(results['gt_bboxes'].dtype, np.float32)
  1406. def test_transform_use_box_type(self):
  1407. results = dict()
  1408. img = mmcv.imread(
  1409. osp.join(osp.dirname(__file__), '../../data/color.jpg'), 'color')
  1410. results['img'] = img
  1411. h, w, _ = img.shape
  1412. gt_bboxes = create_random_bboxes(8, w, h)
  1413. results['gt_bboxes_labels'] = np.ones(
  1414. gt_bboxes.shape[0], dtype=np.int64)
  1415. results['gt_bboxes'] = HorizontalBoxes(gt_bboxes)
  1416. transform = RandomShift(prob=1.0)
  1417. results = transform(results)
  1418. self.assertEqual(results['img'].shape[:2], (h, w))
  1419. self.assertEqual(results['gt_bboxes_labels'].shape[0],
  1420. results['gt_bboxes'].shape[0])
  1421. self.assertEqual(results['gt_bboxes_labels'].dtype, np.int64)
  1422. self.assertEqual(results['gt_bboxes'].dtype, torch.float32)
  1423. def test_repr(self):
  1424. transform = RandomShift()
  1425. self.assertEqual(
  1426. repr(transform), ('RandomShift(prob=0.5, '
  1427. 'max_shift_px=32, '
  1428. 'filter_thr_px=1)'))
  1429. class TestRandomErasing(unittest.TestCase):
  1430. def setUp(self):
  1431. """Setup the model and optimizer which are used in every test method.
  1432. TestCase calls functions in this order: setUp() -> testMethod() ->
  1433. tearDown() -> cleanUp()
  1434. """
  1435. self.results = construct_toy_data(poly2mask=True)
  1436. def test_transform(self):
  1437. transform = RandomErasing(
  1438. n_patches=(1, 5), ratio=(0.4, 0.8), img_border_value=0)
  1439. results = transform(copy.deepcopy(self.results))
  1440. self.assertTrue(results['img'].sum() < self.results['img'].sum())
  1441. transform = RandomErasing(
  1442. n_patches=1, ratio=0.999, img_border_value=255)
  1443. results = transform(copy.deepcopy(self.results))
  1444. self.assertTrue(results['img'].sum() > self.results['img'].sum())
  1445. # test empty results
  1446. empty_results = copy.deepcopy(self.results)
  1447. empty_results['gt_bboxes'] = np.zeros((0, 4), dtype=np.float32)
  1448. empty_results['gt_bboxes_labels'] = np.zeros((0, ), dtype=np.int64)
  1449. empty_results['gt_masks'] = empty_results['gt_masks'][False]
  1450. empty_results['gt_ignore_flags'] = np.zeros((0, ), dtype=bool)
  1451. empty_results['gt_seg_map'] = np.ones_like(
  1452. empty_results['gt_seg_map']) * 255
  1453. results = transform(copy.deepcopy(empty_results))
  1454. self.assertTrue(results['img'].sum() > self.results['img'].sum())
  1455. def test_transform_use_box_type(self):
  1456. src_results = copy.deepcopy(self.results)
  1457. src_results['gt_bboxes'] = HorizontalBoxes(src_results['gt_bboxes'])
  1458. transform = RandomErasing(
  1459. n_patches=(1, 5), ratio=(0.4, 0.8), img_border_value=0)
  1460. results = transform(copy.deepcopy(src_results))
  1461. self.assertTrue(results['img'].sum() < src_results['img'].sum())
  1462. transform = RandomErasing(
  1463. n_patches=1, ratio=0.999, img_border_value=255)
  1464. results = transform(copy.deepcopy(src_results))
  1465. self.assertTrue(results['img'].sum() > src_results['img'].sum())
  1466. # test empty results
  1467. empty_results = copy.deepcopy(src_results)
  1468. empty_results['gt_bboxes'] = HorizontalBoxes([], dtype=torch.float32)
  1469. empty_results['gt_bboxes_labels'] = np.zeros((0, ), dtype=np.int64)
  1470. empty_results['gt_masks'] = empty_results['gt_masks'][False]
  1471. empty_results['gt_ignore_flags'] = np.zeros((0, ), dtype=bool)
  1472. empty_results['gt_seg_map'] = np.ones_like(
  1473. empty_results['gt_seg_map']) * 255
  1474. results = transform(copy.deepcopy(empty_results))
  1475. self.assertTrue(results['img'].sum() > src_results['img'].sum())
  1476. def test_repr(self):
  1477. transform = RandomErasing(n_patches=(1, 5), ratio=(0, 0.2))
  1478. self.assertEqual(
  1479. repr(transform), ('RandomErasing(n_patches=(1, 5), '
  1480. 'ratio=(0, 0.2), '
  1481. 'squared=True, '
  1482. 'bbox_erased_thr=0.9, '
  1483. 'img_border_value=128, '
  1484. 'mask_border_value=0, '
  1485. 'seg_ignore_label=255)'))