@@ -44,7 +44,13 @@ def from_json(labeled_data, annotations_output_dir, images_output_dir,
4444
4545 for data in label_data :
4646 try :
47- _write_label (data , label_format , images_output_dir , annotations_output_dir )
47+ write_label (
48+ data ['ID' ],
49+ data ['Labeled Data' ],
50+ data ['Label' ],
51+ label_format ,
52+ images_output_dir ,
53+ annotations_output_dir )
4854
4955 except requests .exceptions .MissingSchema as exc :
5056 logging .exception (exc )
@@ -54,14 +60,23 @@ def from_json(labeled_data, annotations_output_dir, images_output_dir,
5460 continue
5561
5662
57- def _write_label (
58- data , label_format , images_output_dir , annotations_output_dir ):
59- "Writes a Pascal VOC formatted image and label pair to disk."
63+ def write_label (label_id , image_url , labels , label_format , images_output_dir , annotations_output_dir ):
64+ """Writes a single Pascal VOC formatted image and label pair to disk.
65+
66+ Args:
67+ label_id (str): ID for the instance to write
68+ image_url (str): URL to download image file from
69+ labels (str): Labelbox formatted labels to use for generating annotation
70+ label_format (str): Format of the labeled data. Valid options are: "WKT" and "XY", default is "WKT".
71+ annotations_output_dir (str): File path of directory to write Pascal VOC
72+ annotation files.
73+ images_output_dir (str): File path of directory to write images.
74+ """
6075 # Download image and save it
61- response = requests .get (data [ 'Labeled Data' ] , stream = True )
76+ response = requests .get (image_url , stream = True )
6277 response .raw .decode_content = True
6378 image = Image .open (response .raw )
64- image_name = ('{img_id}.{ext}' .format (img_id = data [ 'ID' ] , ext = image .format .lower ()))
79+ image_name = ('{img_id}.{ext}' .format (img_id = label_id , ext = image .format .lower ()))
6580 image_fqn = os .path .join (images_output_dir , image_name )
6681 image .save (image_fqn , format = image .format )
6782
@@ -70,27 +85,27 @@ def _write_label(
7085 xml_writer = PascalWriter (image_fqn , width , height )
7186
7287 # remove classification labels (Skip, etc...)
73- if not callable (getattr (data [ 'Label' ] , 'keys' , None )):
88+ if not callable (getattr (labels , 'keys' , None )):
7489 # skip if no categories (e.g. "Skip")
7590 return
7691
7792 # convert label to Pascal VOC format
78- for category_name , wkt_data in data [ 'Label' ] .items ():
93+ for category_name , paths in labels .items ():
7994 if label_format == 'WKT' :
8095 xml_writer = _add_pascal_object_from_wkt (
81- xml_writer , img_height = height , wkt_data = wkt_data ,
96+ xml_writer , img_height = height , wkt_data = paths ,
8297 label = category_name )
8398 elif label_format == 'XY' :
8499 xml_writer = _add_pascal_object_from_xy (
85- xml_writer , img_height = height , polygons = wkt_data ,
100+ xml_writer , img_height = height , polygons = paths ,
86101 label = category_name )
87102 else :
88103 exc = UnknownFormatError (label_format = label_format )
89104 logging .exception (exc .message )
90105 raise exc
91106
92107 # write Pascal VOC xml annotation for image
93- xml_writer .save (os .path .join (annotations_output_dir , '{}.xml' .format (data [ 'ID' ] )))
108+ xml_writer .save (os .path .join (annotations_output_dir , '{}.xml' .format (label_id )))
94109
95110
96111def _add_pascal_object_from_wkt (xml_writer , img_height , wkt_data , label ):
@@ -112,10 +127,16 @@ def _add_pascal_object_from_wkt(xml_writer, img_height, wkt_data, label):
112127
113128
114129def _add_pascal_object_from_xy (xml_writer , img_height , polygons , label ):
130+ if not isinstance (polygons , list ):
131+ # polygons is not [{'geometry': [xy]}] nor [[xy]]
132+ return xml_writer
115133 for polygon in polygons :
116134 if 'geometry' in polygon : # V3
117135 polygon = polygon ['geometry' ]
118- assert isinstance (polygon , list ) # V2 and V3
136+ if not isinstance (polygon , list ) \
137+ or not all (map (lambda p : 'x' in p and 'y' in p , polygon )):
138+ # couldn't make a list of points, give up
139+ return xml_writer
119140
120141 xy_coords = []
121142 for point in polygon :
0 commit comments