4949 "pan" : ("pan_seg" , "bitmasks" ),
5050}
5151_TRACKING_DATASET_INFO = {
52- "mots" : ("bdd100k_seg_track_20" , "seg_track_20" , os .path .join ("seg_track_20" , "polygons" )),
53- "mot" : (
54- "bdd100k_box_track_20" ,
55- "" ,
56- "" ,
57- ),
52+ "mots" : ("bdd100k_seg_track_20" , "seg_track_20" ),
53+ "mot" : ("bdd100k_box_track_20" , "" ),
5854}
59- _DATA_GETTER = Callable [[str , Dict [str , Any ]], Data ]
60- _DATA_GENERATOR = Callable [[str , str , _DATA_GETTER ], Iterable [Data ]]
55+ _DATA_GENERATOR = Callable [[str , str , str , str , str ], Iterable [Data ]]
6156
6257
6358def BDD100K (path : str ) -> Dataset :
@@ -250,13 +245,13 @@ def _get_data_10k(
250245 _add_poly2d_label_10k (label_info , polygon )
251246 label = data .label
252247 label .polygon = polygon
253- filename = os .path .splitext (os .path .basename (image_path ))[0 ]
254- label .semantic_mask = SemanticMask (os .path .join (original_mask_paths ["sem" ], f"{ filename } .png" ))
248+ stem = os .path .splitext (os .path .basename (image_path ))[0 ]
249+ label .semantic_mask = SemanticMask (os .path .join (original_mask_paths ["sem" ], f"{ stem } .png" ))
255250 label .instance_mask = _get_instance_mask (
256- filename , original_mask_paths ["ins" ], single_channel_mask_paths ["ins" ]
251+ stem , original_mask_paths ["ins" ], single_channel_mask_paths ["ins" ]
257252 )
258253 label .panoptic_mask = _get_panoptic_mask (
259- filename , original_mask_paths ["pan" ], single_channel_mask_paths ["pan" ]
254+ stem , original_mask_paths ["pan" ], single_channel_mask_paths ["pan" ]
260255 )
261256 return data
262257
@@ -369,13 +364,13 @@ def _merge_label(source_label_contents: List[List[Dict[str, Any]]]) -> Dict[str,
369364
370365
371366def _get_instance_mask (
372- filename : str , original_mask_directory : str , mask_directory : str
367+ stem : str , original_mask_directory : str , mask_directory : str
373368) -> InstanceMask :
374- mask_path = os .path .join (mask_directory , f"{ filename } .png" )
369+ mask_path = os .path .join (mask_directory , f"{ stem } .png" )
375370 mask_info = _save_and_get_mask_info (
376- os .path .join (original_mask_directory , f"{ filename } .png" ),
371+ os .path .join (original_mask_directory , f"{ stem } .png" ),
377372 mask_path ,
378- os .path .join (mask_directory , f"{ filename } .json" ),
373+ os .path .join (mask_directory , f"{ stem } .json" ),
379374 "ins" ,
380375 )
381376
@@ -385,13 +380,13 @@ def _get_instance_mask(
385380
386381
387382def _get_panoptic_mask (
388- filename : str , original_mask_directory : str , mask_directory : str
383+ stem : str , original_mask_directory : str , mask_directory : str
389384) -> PanopticMask :
390- mask_path = os .path .join (mask_directory , f"{ filename } .png" )
385+ mask_path = os .path .join (mask_directory , f"{ stem } .png" )
391386 mask_info = _save_and_get_mask_info (
392- os .path .join (original_mask_directory , f"{ filename } .png" ),
387+ os .path .join (original_mask_directory , f"{ stem } .png" ),
393388 mask_path ,
394- os .path .join (mask_directory , f"{ filename } .json" ),
389+ os .path .join (mask_directory , f"{ stem } .json" ),
395390 "pan" ,
396391 )
397392
@@ -405,29 +400,31 @@ def _save_and_get_mask_info(
405400 original_mask_path : str , mask_path : str , mask_info_path : str , seg_type : str
406401) -> Dict [str , Any ]:
407402 if not os .path .exists (mask_path ):
408- mask = np .array (Image .open (original_mask_path ))
403+ mask = np .array (Image .open (original_mask_path ), dtype = np . uint16 )
409404 all_attributes = {}
410405 if seg_type == "pan" :
411406 all_category_ids = {}
412- for instance_info in set (map (tuple , np .reshape (mask , (- 1 , 4 )))):
413- instance_id = int (instance_info [- 1 ]) # type:ignore[call-overload]
414- attributes = instance_info [1 ]
407+ for category_id , attributes , instance_id_high , instance_id_low in np .unique (
408+ np .reshape (mask , (- 1 , 4 )), axis = 0
409+ ):
410+ # the instance_id is represented by 2 channels, instance_id = high*256+low
411+ instance_id = int (instance_id_low + (instance_id_high << 8 ))
415412 all_attributes [instance_id ] = {
416- "truncated" : bool (attributes & 8 ), # type:ignore[operator]
417- "occluded" : bool (attributes & 4 ), # type:ignore[operator]
418- "crowd" : bool (attributes & 2 ), # type:ignore[operator]
419- "ignore" : bool (attributes & 1 ), # type:ignore[operator]
413+ "truncated" : bool (attributes & 8 ),
414+ "occluded" : bool (attributes & 4 ),
415+ "crowd" : bool (attributes & 2 ),
416+ "ignore" : bool (attributes & 1 ),
420417 }
421418 if seg_type == "pan" :
422- all_category_ids [instance_id ] = int (instance_info [ 0 ]) # type:ignore[call-overload]
419+ all_category_ids [instance_id ] = int (category_id )
423420 mask_info = (
424421 {"all_attributes" : all_attributes , "all_category_ids" : all_category_ids }
425422 if seg_type == "pan"
426423 else {"all_attributes" : all_attributes }
427424 )
428425 with open (mask_info_path , "w" ) as fp :
429426 json .dump (mask_info , fp )
430- Image .fromarray (mask [:, :, - 1 ]).save (mask_path )
427+ Image .fromarray (mask [:, :, - 1 ] + ( mask [:, :, - 2 ] << 8 ) ).save (mask_path )
431428 else :
432429 with open (mask_info_path , "r" ) as fp :
433430 mask_info = json .load (
@@ -467,6 +464,17 @@ def _BDD100K_MOTS2020(path: str) -> Dataset:
467464 ...
468465 labels/
469466 seg_track_20/
467+ bitmasks/
468+ train/
469+ 000d4f89-3bcbe37a/
470+ 000d4f89-3bcbe37a-0000001.png
471+ ...
472+ ...
473+ val/
474+ b1c9c847-3bda4659/
475+ b1c9c847-3bda4659-0000001.png
476+ ...
477+ ...
470478 polygons/
471479 train/
472480 000d4f89-3bcbe37a.json
@@ -529,19 +537,14 @@ def _BDD100K_MOT2020(path: str) -> Dataset:
529537
530538
531539def _tracking_loader (path : str , tracking_type : str ) -> Dataset :
532- if tracking_type == "mot" :
533- get_data = _get_mot_data
534- else :
535- get_data = _get_mots_data
536- root_path = os .path .join (
537- os .path .abspath (os .path .expanduser (path )), _TRACKING_DATASET_INFO [tracking_type ][0 ]
538- )
540+ tracking_dataset_info = _TRACKING_DATASET_INFO [tracking_type ]
541+ root_path = os .path .join (os .path .abspath (os .path .expanduser (path )), tracking_dataset_info [0 ])
539542 dataset = Dataset (DATASET_NAMES [tracking_type ])
540543 dataset .notes .is_continuous = True
541544 dataset .load_catalog (os .path .join (os .path .dirname (__file__ ), f"catalog_{ tracking_type } .json" ))
542- images_directory = os .path .join (root_path , "images" , _TRACKING_DATASET_INFO [ tracking_type ] [1 ])
543- labels_directory = os .path .join (root_path , "labels" , _TRACKING_DATASET_INFO [ tracking_type ][ 2 ])
544- _load_tracking_segment (dataset , images_directory , labels_directory , get_data )
545+ images_directory = os .path .join (root_path , "images" , tracking_dataset_info [1 ])
546+ labels_directory = os .path .join (root_path , "labels" , tracking_dataset_info [ 1 ])
547+ _load_tracking_segment (dataset , images_directory , labels_directory , tracking_type )
545548
546549 return dataset
547550
@@ -550,39 +553,64 @@ def _load_tracking_segment(
550553 dataset : Dataset ,
551554 images_directory : str ,
552555 labels_directory : str ,
553- load_label : _DATA_GETTER ,
556+ tracking_type : str ,
554557) -> None :
555558 for segment_prefix in _SEGMENT_NAMES :
556559 image_directory = glob (os .path .join (images_directory , segment_prefix , "*" ))
557- labels_directory_segment = os .path .join (labels_directory , segment_prefix )
560+ segment_labels_directory = os .path .join (labels_directory , "polygons" , segment_prefix )
561+ original_mask_directory = os .path .join (labels_directory , "bitmasks" , segment_prefix )
562+ mask_directory = os .path .join (labels_directory , "single_channel_masks" , segment_prefix )
563+ os .makedirs (mask_directory , exist_ok = True )
564+
558565 if segment_prefix == "test" :
559566 generate_data : _DATA_GENERATOR = _generate_test_data
560567 else :
561568 generate_data = _generate_data
562569 for image_subdir in image_directory :
563570 segment = dataset .create_segment (f"{ segment_prefix } _{ os .path .basename (image_subdir )} " )
564- segment .extend (generate_data (image_subdir , labels_directory_segment , load_label ))
571+ segment .extend (
572+ generate_data (
573+ image_subdir ,
574+ segment_labels_directory ,
575+ original_mask_directory ,
576+ mask_directory ,
577+ tracking_type ,
578+ )
579+ )
565580
566581
567- def _generate_test_data (image_subdir : str , _ : str , __ : _DATA_GETTER ) -> Iterable [Data ]:
582+ def _generate_test_data (image_subdir : str , _ : str , __ : str , ___ : str , ____ : str ) -> Iterable [Data ]:
568583 yield from map (Data , glob (os .path .join (image_subdir , "*.jpg" )))
569584
570585
571586def _generate_data (
572587 image_subdir : str ,
573- labels_directory_segment : str ,
574- get_data : _DATA_GETTER ,
588+ segment_labels_directory : str ,
589+ original_mask_directory : str ,
590+ mask_directory : str ,
591+ tracking_type : str ,
575592) -> Iterable [Data ]:
576- label_filename = f"{ os .path .basename (image_subdir )} .json"
577- with open (os .path .join (labels_directory_segment , label_filename ), "r" ) as fp :
593+ subdir_name = os .path .basename (image_subdir )
594+ if tracking_type == "mots" :
595+ original_mask_subdir = os .path .join (original_mask_directory , subdir_name )
596+ mask_subdir = os .path .join (mask_directory , subdir_name )
597+ os .makedirs (mask_subdir , exist_ok = True )
598+ with open (os .path .join (segment_labels_directory , f"{ subdir_name } .json" ), "r" ) as fp :
578599 label_contents = json .load (fp )
579600 for label_content in label_contents :
580601 label_content_name = label_content ["name" ]
581602 if "/" in label_content_name :
582603 label_content_name = label_content_name [len (label_content ["videoName" ]) + 1 :]
583604 image_path = os .path .join (image_subdir , label_content_name )
584-
585- yield get_data (image_path , label_content )
605+ yield _get_mot_data (
606+ image_path , label_content
607+ ) if tracking_type == "mot" else _get_mots_data (
608+ image_path ,
609+ original_mask_subdir ,
610+ mask_subdir ,
611+ os .path .splitext (label_content_name )[0 ],
612+ label_content ,
613+ )
586614
587615
588616def _get_mot_data (image_path : str , label_content : Dict [str , Any ]) -> Data :
@@ -607,7 +635,13 @@ def _get_mot_data(image_path: str, label_content: Dict[str, Any]) -> Data:
607635 return data
608636
609637
610- def _get_mots_data (image_path : str , label_content : Dict [str , Any ]) -> Data :
638+ def _get_mots_data (
639+ image_path : str ,
640+ original_mask_subdir : str ,
641+ mask_subdir : str ,
642+ stem : str ,
643+ label_content : Dict [str , Any ],
644+ ) -> Data :
611645 data = Data (image_path )
612646 labeled_multipolygons = []
613647 for label_info in label_content .get ("labels" , ()):
@@ -620,6 +654,7 @@ def _get_mots_data(image_path: str, label_content: Dict[str, Any]) -> Data:
620654 instance = str (label_info ["id" ]),
621655 )
622656 labeled_multipolygons .append (labeled_multipolygon )
623- data .label .multi_polygon = labeled_multipolygons
624-
657+ label = data .label
658+ label .multi_polygon = labeled_multipolygons
659+ label .instance_mask = _get_instance_mask (stem , original_mask_subdir , mask_subdir )
625660 return data
0 commit comments