@@ -51,6 +51,9 @@ def _setUpModule():
51
51
import cvat .apps .dataset_manager as dm
52
52
globals ()['dm' ] = dm
53
53
54
+ import datumaro
55
+ globals ()['datumaro' ] = datumaro
56
+
54
57
import sys
55
58
sys .path .insert (0 , __file__ [:__file__ .rfind ('/dataset_manager/' )])
56
59
@@ -61,6 +64,7 @@ def _setUpModule():
61
64
import os .path as osp
62
65
import random
63
66
import tempfile
67
+ import zipfile
64
68
65
69
from PIL import Image
66
70
from django .contrib .auth .models import User , Group
@@ -113,38 +117,7 @@ def setUp(self):
113
117
def setUpTestData (cls ):
114
118
create_db_users (cls )
115
119
116
- def _generate_task (self ):
117
- task = {
118
- "name" : "my task #1" ,
119
- "owner" : '' ,
120
- "assignee" : '' ,
121
- "overlap" : 0 ,
122
- "segment_size" : 100 ,
123
- "z_order" : False ,
124
- "labels" : [
125
- {
126
- "name" : "car" ,
127
- "attributes" : [
128
- {
129
- "name" : "model" ,
130
- "mutable" : False ,
131
- "input_type" : "select" ,
132
- "default_value" : "mazda" ,
133
- "values" : ["bmw" , "mazda" , "renault" ]
134
- },
135
- {
136
- "name" : "parked" ,
137
- "mutable" : True ,
138
- "input_type" : "checkbox" ,
139
- "default_value" : False
140
- },
141
- ]
142
- },
143
- {"name" : "person" },
144
- ]
145
- }
146
- task = self ._create_task (task , 3 )
147
-
120
+ def _generate_annotations (self , task ):
148
121
annotations = {
149
122
"version" : 0 ,
150
123
"tags" : [
@@ -256,8 +229,39 @@ def _generate_task(self):
256
229
]
257
230
}
258
231
self ._put_api_v1_task_id_annotations (task ["id" ], annotations )
232
+ return annotations
259
233
260
- return task , annotations
234
+ def _generate_task (self ):
235
+ task = {
236
+ "name" : "my task #1" ,
237
+ "owner" : '' ,
238
+ "assignee" : '' ,
239
+ "overlap" : 0 ,
240
+ "segment_size" : 100 ,
241
+ "z_order" : False ,
242
+ "labels" : [
243
+ {
244
+ "name" : "car" ,
245
+ "attributes" : [
246
+ {
247
+ "name" : "model" ,
248
+ "mutable" : False ,
249
+ "input_type" : "select" ,
250
+ "default_value" : "mazda" ,
251
+ "values" : ["bmw" , "mazda" , "renault" ]
252
+ },
253
+ {
254
+ "name" : "parked" ,
255
+ "mutable" : True ,
256
+ "input_type" : "checkbox" ,
257
+ "default_value" : False
258
+ },
259
+ ]
260
+ },
261
+ {"name" : "person" },
262
+ ]
263
+ }
264
+ return self ._create_task (task , 3 )
261
265
262
266
def _create_task (self , data , size ):
263
267
with ForceLogin (self .user , self .client ):
@@ -285,53 +289,99 @@ def _put_api_v1_task_id_annotations(self, tid, data):
285
289
286
290
return response
287
291
288
- def _test_export (self , format_name , save_images = False ):
289
- task , _ = self ._generate_task ()
290
-
292
+ def _test_export (self , check , task , format_name , ** export_args ):
291
293
with tempfile .TemporaryDirectory () as temp_dir :
292
294
file_path = osp .join (temp_dir , format_name )
293
295
dm .task .export_task (task ["id" ], file_path ,
294
- format_name , save_images = save_images )
295
-
296
- with open (file_path , 'rb' ) as f :
297
- self .assertTrue (len (f .read ()) != 0 )
298
-
299
- def test_datumaro (self ):
300
- self ._test_export ('Datumaro 1.0' , save_images = False )
301
-
302
- def test_coco (self ):
303
- self ._test_export ('COCO 1.0' , save_images = True )
304
-
305
- def test_voc (self ):
306
- self ._test_export ('PASCAL VOC 1.1' , save_images = True )
307
-
308
- def test_tf_record (self ):
309
- self ._test_export ('TFRecord 1.0' , save_images = True )
296
+ format_name , ** export_args )
310
297
311
- def test_yolo (self ):
312
- self ._test_export ('YOLO 1.1' , save_images = True )
313
-
314
- def test_mot (self ):
315
- self ._test_export ('MOT 1.1' , save_images = True )
316
-
317
- def test_labelme (self ):
318
- self ._test_export ('LabelMe 3.0' , save_images = True )
319
-
320
- def test_mask (self ):
321
- self ._test_export ('Segmentation mask 1.1' , save_images = True )
322
-
323
- def test_cvat_video (self ):
324
- self ._test_export ('CVAT for video 1.1' , save_images = True )
325
-
326
- def test_cvat_images (self ):
327
- self ._test_export ('CVAT for images 1.1' , save_images = True )
298
+ check (file_path )
328
299
329
300
def test_export_formats_query (self ):
330
301
formats = dm .views .get_export_formats ()
331
302
332
- self .assertEqual (len (formats ), 10 )
303
+ self .assertEqual ({f .DISPLAY_NAME for f in formats },
304
+ {
305
+ 'COCO 1.0' ,
306
+ 'CVAT for images 1.1' ,
307
+ 'CVAT for video 1.1' ,
308
+ 'Datumaro 1.0' ,
309
+ 'LabelMe 3.0' ,
310
+ 'MOT 1.1' ,
311
+ 'PASCAL VOC 1.1' ,
312
+ 'Segmentation mask 1.1' ,
313
+ 'TFRecord 1.0' ,
314
+ 'YOLO 1.1' ,
315
+ })
333
316
334
317
def test_import_formats_query (self ):
335
318
formats = dm .views .get_import_formats ()
336
319
337
- self .assertEqual (len (formats ), 8 )
320
+ self .assertEqual ({f .DISPLAY_NAME for f in formats },
321
+ {
322
+ 'COCO 1.0' ,
323
+ 'CVAT 1.1' ,
324
+ 'LabelMe 3.0' ,
325
+ 'MOT 1.1' ,
326
+ 'PASCAL VOC 1.1' ,
327
+ 'Segmentation mask 1.1' ,
328
+ 'TFRecord 1.0' ,
329
+ 'YOLO 1.1' ,
330
+ })
331
+
332
+ def test_exports (self ):
333
+ def check (file_path ):
334
+ with open (file_path , 'rb' ) as f :
335
+ self .assertTrue (len (f .read ()) != 0 )
336
+
337
+ for f in dm .views .get_export_formats ():
338
+ format_name = f .DISPLAY_NAME
339
+ for save_images in { True , False }:
340
+ with self .subTest (format = format_name , save_images = save_images ):
341
+ task = self ._generate_task ()
342
+ self ._generate_annotations (task )
343
+ self ._test_export (check , task ,
344
+ format_name , save_images = save_images )
345
+
346
+ def test_empty_images_are_exported (self ):
347
+ dm_env = dm .formats .registry .dm_env
348
+
349
+ for format_name , importer_name in [
350
+ ('COCO 1.0' , 'coco' ),
351
+ ('CVAT for images 1.1' , 'cvat' ),
352
+ # ('CVAT for video 1.1', 'cvat'), # does not support
353
+ ('Datumaro 1.0' , 'datumaro_project' ),
354
+ ('LabelMe 3.0' , 'label_me' ),
355
+ # ('MOT 1.1', 'mot_seq'), # does not support
356
+ ('PASCAL VOC 1.1' , 'voc' ),
357
+ ('Segmentation mask 1.1' , 'voc' ),
358
+ ('TFRecord 1.0' , 'tf_detection_api' ),
359
+ ('YOLO 1.1' , 'yolo' ),
360
+ ]:
361
+ with self .subTest (format = format_name ):
362
+ task = self ._generate_task ()
363
+
364
+ def check (file_path ):
365
+ def load_dataset (src ):
366
+ if importer_name == 'datumaro_project' :
367
+ project = datumaro .components .project . \
368
+ Project .load (src )
369
+
370
+ # NOTE: can't import cvat.utils.cli
371
+ # for whatever reason, so remove the dependency
372
+ project .config .remove ('sources' )
373
+
374
+ return project .make_dataset ()
375
+ return dm_env .make_importer (importer_name )(src ) \
376
+ .make_dataset ()
377
+
378
+ if zipfile .is_zipfile (file_path ):
379
+ with tempfile .TemporaryDirectory () as tmp_dir :
380
+ zipfile .ZipFile (file_path ).extractall (tmp_dir )
381
+ dataset = load_dataset (tmp_dir )
382
+ else :
383
+ dataset = load_dataset (file_path )
384
+
385
+ self .assertEqual (len (dataset ), task ["size" ])
386
+ self ._test_export (check , task , format_name , save_images = False )
387
+
0 commit comments