@@ -478,7 +478,7 @@ def __serialize(value: any) -> any:
478478def to_yolo (project_type : str , tasks : list , classes : list , output_dir : str ) -> tuple :
479479 if len (classes ) == 0 :
480480 coco = to_coco (project_type = project_type , tasks = tasks , output_dir = output_dir )
481- return __coco2yolo (coco )
481+ return __coco2yolo (project_type , coco )
482482 else :
483483 return __to_yolo (
484484 project_type = project_type ,
@@ -488,7 +488,7 @@ def to_yolo(project_type: str, tasks: list, classes: list, output_dir: str) -> t
488488 )
489489
490490
491- def __coco2yolo (coco : dict ) -> tuple :
491+ def __coco2yolo (project_type : str , coco : dict ) -> tuple :
492492 categories = coco ["categories" ]
493493
494494 annos = []
@@ -498,39 +498,82 @@ def __coco2yolo(coco: dict) -> tuple:
498498
499499 # Get objects
500500 objs = []
501- for annotation in coco ["annotations" ]:
502- if image ["id" ] != annotation ["image_id" ]:
503- continue
501+ if project_type == "image_segmentation" :
502+ objs = __coco2yolo_segmentation (coco , categories , image , dw , dh )
503+ else :
504+ objs = __coco2yolo_rect (coco , categories , image , dw , dh )
504505
505- category_index = "0"
506- for index , category in enumerate (categories ):
507- if category ["id" ] == annotation ["category_id" ]:
508- category_index = str (index )
509- break
506+ # get annotation
507+ anno = {"filename" : image ["file_name" ], "object" : objs }
508+ annos .append (anno )
510509
511- xmin = annotation ["bbox" ][0 ]
512- ymin = annotation ["bbox" ][1 ]
513- xmax = annotation ["bbox" ][0 ] + annotation ["bbox" ][2 ]
514- ymax = annotation ["bbox" ][1 ] + annotation ["bbox" ][3 ]
510+ return annos , categories
515511
516- x = (xmin + xmax ) / 2
517- y = (ymin + ymax ) / 2
518- w = xmax - xmin
519- h = ymax - ymin
520512
521- x = str (_truncate (x * dw , 7 ))
522- y = str (_truncate (y * dh , 7 ))
523- w = str (_truncate (w * dw , 7 ))
524- h = str (_truncate (h * dh , 7 ))
513+ def __coco2yolo_rect (
514+ coco : dict , categories : list , image : dict , dw : float , dh : float
515+ ) -> list [str ]:
516+ objs = []
517+ for annotation in coco ["annotations" ]:
518+ if image ["id" ] != annotation ["image_id" ]:
519+ continue
525520
526- obj = [category_index , x , y , w , h ]
527- objs .append (" " .join (obj ))
521+ category_index = "0"
522+ for index , category in enumerate (categories ):
523+ if category ["id" ] == annotation ["category_id" ]:
524+ category_index = str (index )
525+ break
526+ xmin = annotation ["bbox" ][0 ]
527+ ymin = annotation ["bbox" ][1 ]
528+ xmax = annotation ["bbox" ][0 ] + annotation ["bbox" ][2 ]
529+ ymax = annotation ["bbox" ][1 ] + annotation ["bbox" ][3 ]
530+
531+ x = (xmin + xmax ) / 2
532+ y = (ymin + ymax ) / 2
533+ w = xmax - xmin
534+ h = ymax - ymin
535+
536+ x = str (_truncate (x * dw , 7 ))
537+ y = str (_truncate (y * dh , 7 ))
538+ w = str (_truncate (w * dw , 7 ))
539+ h = str (_truncate (h * dh , 7 ))
540+
541+ obj = [category_index , x , y , w , h ]
542+ objs .append (" " .join (obj ))
543+ return obj
544+
545+
546+ def __coco2yolo_segmentation (
547+ coco : dict , categories : list , image : dict , dw : float , dh : float
548+ ) -> list [str ]:
549+ objs = []
550+ for annotation in coco ["annotations" ]:
551+ if image ["id" ] != annotation ["image_id" ]:
552+ continue
528553
529- # get annotation
530- anno = {"filename" : image ["file_name" ], "object" : objs }
531- annos .append (anno )
554+ category_index = "0"
555+ for index , category in enumerate (categories ):
556+ if category ["id" ] == annotation ["category_id" ]:
557+ category_index = str (index )
558+ break
559+ # 座標部分を取得
560+ for coordinates in annotation ["segmentation" ]:
561+ # 座標を(x, y)のペアに分割し、yoloの小数で表す形式に変換する。
562+ yolo_vertices = [
563+ {
564+ "x" : str (_truncate (coordinates [i ] * dw , 7 )),
565+ "y" : str (_truncate (coordinates [i + 1 ] * dh , 7 )),
566+ }
567+ for i in range (0 , len (coordinates ), 2 )
568+ ]
532569
533- return annos , categories
570+ # category_index の後に x, yを順番に足していく。
571+ obj = [category_index ]
572+ for v in yolo_vertices :
573+ obj .append (v ["x" ])
574+ obj .append (v ["y" ])
575+ objs .append (" " .join (obj ))
576+ return objs
534577
535578
536579def __to_yolo (project_type : str , tasks : list , classes : list , output_dir : str ) -> tuple :
@@ -594,6 +637,7 @@ def __get_yolo_annotation(data: dict) -> dict:
594637 if (
595638 annotation_type != AnnotationType .bbox .value
596639 and annotation_type != AnnotationType .polygon .value
640+ and annotation_type != AnnotationType .segmentation .value
597641 ):
598642 return None
599643 if not points or len (points ) == 0 :
@@ -607,8 +651,36 @@ def __get_yolo_annotation(data: dict) -> dict:
607651
608652 dw = 1.0 / data ["width" ]
609653 dh = 1.0 / data ["height" ]
654+ if annotation_type == AnnotationType .segmentation .value :
655+ return __segmentation2yolo (value , classes , dw , dh , points )
656+ else :
657+ bbox = __to_bbox (annotation_type , points )
658+ return __bbox2yolo (value , classes , dw , dh , bbox )
659+
660+
661+ def __segmentation2yolo (value : str , classes : list , dw : float , dh : float , points : list ):
662+ objs = []
663+ category_index = str (classes .index (value ))
664+ for shapes in points :
665+ for coordinates in shapes :
666+ # 座標を(x, y)のペアに分割し、yoloの小数で表す形式に変換する。
667+ yolo_vertices = [
668+ {
669+ "x" : str (_truncate (coordinates [i ] * dw , 7 )),
670+ "y" : str (_truncate (coordinates [i + 1 ] * dh , 7 )),
671+ }
672+ for i in range (0 , len (coordinates ), 2 )
673+ ]
674+ # category_index の後に x, yを順番に足していく。
675+ obj = [category_index ]
676+ for v in yolo_vertices :
677+ obj .append (v ["x" ])
678+ obj .append (v ["y" ])
679+ objs .append (" " .join (obj ))
680+ return objs
610681
611- bbox = __to_bbox (annotation_type , points )
682+
683+ def __bbox2yolo (value : str , classes : list , dw : float , dh : float , bbox : list ):
612684 xmin = bbox [0 ]
613685 ymin = bbox [1 ]
614686 xmax = bbox [0 ] + bbox [2 ]
@@ -1089,7 +1161,7 @@ def execute_pascalvoc_to_fastlabel(pascalvoc: dict, file_path: str = None) -> tu
10891161 return (file_name , annotations )
10901162
10911163
1092- def execute_yolo_to_fastlabel (
1164+ def execute_bbox_yolo_to_fastlabel (
10931165 classes : dict ,
10941166 image_sizes : dict ,
10951167 yolo_annotations : dict ,
@@ -1140,6 +1212,52 @@ def execute_yolo_to_fastlabel(
11401212 return results
11411213
11421214
1215+ def execute_segmentation_yolo_to_fastlabel (
1216+ classes : dict ,
1217+ image_sizes : dict ,
1218+ yolo_annotations : dict ,
1219+ dataset_folder_path : str = None ,
1220+ ) -> dict :
1221+ results = {}
1222+ for yolo_anno_key in yolo_annotations :
1223+ annotations = []
1224+ for each_image_annotation in yolo_annotations [yolo_anno_key ]:
1225+ yolo_class_id = each_image_annotation [0 ]
1226+ coordinates = each_image_annotation [1 :]
1227+ image_width , image_height = image_sizes [yolo_anno_key ]["size" ]
1228+
1229+ classs_name = classes [str (yolo_class_id )]
1230+
1231+ points = [[[]]]
1232+ # 座標を(x, y)のペアに分割
1233+ vertices = [
1234+ {"x" : coordinates [i ], "y" : coordinates [i + 1 ]}
1235+ for i in range (0 , len (coordinates ), 2 )
1236+ ]
1237+ for vertice in vertices :
1238+ points [0 ][0 ].append (round (float (image_width ) * float (vertice ["x" ])))
1239+ points [0 ][0 ].append (round (float (image_height ) * float (vertice ["y" ])))
1240+
1241+ annotations .append (
1242+ {
1243+ "value" : classs_name ,
1244+ "points" : points ,
1245+ "type" : AnnotationType .segmentation .value ,
1246+ }
1247+ )
1248+
1249+ file_path = (
1250+ image_sizes [yolo_anno_key ]["image_file_path" ].replace (
1251+ os .path .join (* [dataset_folder_path , "" ]), ""
1252+ )
1253+ if dataset_folder_path
1254+ else image_sizes [yolo_anno_key ]["image_file_path" ]
1255+ )
1256+ results [file_path ] = annotations
1257+
1258+ return results
1259+
1260+
11431261def __get_annotation_type_by_labelme (shape_type : str ) -> str :
11441262 if shape_type == "rectangle" :
11451263 return "bbox"
0 commit comments