Repository: PaddlePaddle/PaddleSeg

Issue:
LabelMe标注好图片之后，使用labelme2seg无法生成真值图片
我使用LabelMe标注好图片之后，使用labelme2seg生成真值图片，运行labelme2seg的时候报错，报错信息如下：
class_names: ('_background_', 'steel')
Saved class_names: D:\2\class_names.txt
Generating dataset from: D:\2\2020_5_15_13_19_46_995.json
Traceback (most recent call last):
  File "D:\PaddleSeg\pdseg\tools\labelme2seg.py", line 90, in <module>
    main(args)
  File "D:\PaddleSeg\pdseg\tools\labelme2seg.py", line 78, in main
    if lbl.min() >= 0 and lbl.max() <= 255:
AttributeError: 'tuple' object has no attribute 'min'


Discussion:

Resolving patch:
diff --git a/pdseg/tools/jingling2seg.py b/pdseg/tools/jingling2seg.py
--- a/pdseg/tools/jingling2seg.py
+++ b/pdseg/tools/jingling2seg.py
@@ -20,12 +20,11 @@
 import json
 import os
 import os.path as osp
-
 import numpy as np
 import PIL.Image
-import labelme
 
 from gray2pseudo_color import get_color_map_list
+from labelme2seg import shape2label
 
 
 def parse_args():
@@ -102,10 +101,10 @@ def main(args):
             img_shape = (data_size['height'], data_size['width'],
                          data_size['depth'])
 
-            lbl = labelme.utils.shapes_to_label(
-                img_shape=img_shape,
+            lbl = shape2label(
+                img_size=img_shape,
                 shapes=data_shapes,
-                label_name_to_value=class_name_to_id,
+                class_name_mapping=class_name_to_id,
             )
 
             if osp.splitext(out_png_file)[1] != '.png':
diff --git a/pdseg/tools/labelme2seg.py b/pdseg/tools/labelme2seg.py
--- a/pdseg/tools/labelme2seg.py
+++ b/pdseg/tools/labelme2seg.py
@@ -17,13 +17,14 @@
 
 import argparse
 import glob
+import math
 import json
 import os
 import os.path as osp
-
 import numpy as np
 import PIL.Image
-import labelme
+import PIL.ImageDraw
+import cv2
 
 from gray2pseudo_color import get_color_map_list
 
@@ -77,12 +78,12 @@ def main(args):
             data = json.load(f)
 
             img_file = osp.join(osp.dirname(label_file), data['imagePath'])
-            img = np.asarray(PIL.Image.open(img_file))
+            img = np.asarray(cv2.imread(img_file))
 
-            lbl = labelme.utils.shapes_to_label(
-                img_shape=img.shape,
+            lbl = shape2label(
+                img_size=img.shape,
                 shapes=data['shapes'],
-                label_name_to_value=class_name_to_id,
+                class_name_mapping=class_name_to_id,
             )
 
             if osp.splitext(out_png_file)[1] != '.png':
@@ -98,6 +99,27 @@ def main(args):
                     'Please consider using the .npy format.' % out_png_file)
 
 
+def shape2mask(img_size, points):
+    label_mask = PIL.Image.fromarray(np.zeros(img_size[:2], dtype=np.uint8))
+    image_draw = PIL.ImageDraw.Draw(label_mask)
+    points_list = [tuple(point) for point in points]
+    assert len(points_list) > 2, 'Polygon must have points more than 2'
+    image_draw.polygon(xy=points_list, outline=1, fill=1)
+    return np.array(label_mask, dtype=bool)
+
+
+def shape2label(img_size, shapes, class_name_mapping):
+    label = np.zeros(img_size[:2], dtype=np.int32)
+    for shape in shapes:
+        points = shape['points']
+        class_name = shape['label']
+        shape_type = shape.get('shape_type', None)
+        class_id = class_name_mapping[class_name]
+        label_mask = shape2mask(img_size[:2], points)
+        label[label_mask] = class_id
+    return label
+
+
 if __name__ == '__main__':
     args = parse_args()
     main(args)


Test patch: