فهرست منبع

Create labelme.utils

Kentaro Wada 6 سال پیش
والد
کامیت
e43d9e75a5

+ 5 - 5
labelme/app.py

@@ -17,16 +17,16 @@ from labelme import __version__
 from labelme.config import get_config
 from labelme.labelFile import LabelFile
 from labelme.labelFile import LabelFileError
-from labelme.lib import addActions
-from labelme.lib import fmtShortcut
-from labelme.lib import newAction
-from labelme.lib import newIcon
-from labelme.lib import struct
 from labelme import logger
 from labelme import QT5
 from labelme.shape import DEFAULT_FILL_COLOR
 from labelme.shape import DEFAULT_LINE_COLOR
 from labelme.shape import Shape
+from labelme.utils import addActions
+from labelme.utils import fmtShortcut
+from labelme.utils import newAction
+from labelme.utils import newIcon
+from labelme.utils import struct
 from labelme.widgets import Canvas
 from labelme.widgets import ColorDialog
 from labelme.widgets import LabelDialog

+ 3 - 4
labelme/shape.py

@@ -1,7 +1,6 @@
 from qtpy import QtGui
 
-from labelme.lib import distance
-from labelme.lib import distancetoline
+import labelme.utils
 
 
 # TODO(unknown):
@@ -131,7 +130,7 @@ class Shape(object):
         min_distance = float('inf')
         min_i = None
         for i, p in enumerate(self.points):
-            dist = distance(p - point)
+            dist = labelme.utils.distance(p - point)
             if dist <= epsilon and dist < min_distance:
                 min_distance = dist
                 min_i = i
@@ -142,7 +141,7 @@ class Shape(object):
         post_i = None
         for i in range(len(self.points)):
             line = [self.points[i - 1], self.points[i]]
-            dist = distancetoline(point, line)
+            dist = labelme.utils.distancetoline(point, line)
             if dist <= epsilon and dist < min_distance:
                 min_distance = dist
                 post_i = i

+ 0 - 199
labelme/utils.py

@@ -1,199 +0,0 @@
-import base64
-import io
-import os.path as osp
-import warnings
-
-import numpy as np
-import PIL.Image
-import PIL.ImageDraw
-
-from labelme import logger
-
-
-def label_colormap(N=256):
-
-    def bitget(byteval, idx):
-        return ((byteval & (1 << idx)) != 0)
-
-    cmap = np.zeros((N, 3))
-    for i in range(0, N):
-        id = i
-        r, g, b = 0, 0, 0
-        for j in range(0, 8):
-            r = np.bitwise_or(r, (bitget(id, 0) << 7 - j))
-            g = np.bitwise_or(g, (bitget(id, 1) << 7 - j))
-            b = np.bitwise_or(b, (bitget(id, 2) << 7 - j))
-            id = (id >> 3)
-        cmap[i, 0] = r
-        cmap[i, 1] = g
-        cmap[i, 2] = b
-    cmap = cmap.astype(np.float32) / 255
-    return cmap
-
-
-def labelcolormap(N=256):
-    warnings.warn('labelcolormap is deprecated. Please use label_colormap.')
-    return label_colormap(N=N)
-
-
-# similar function as skimage.color.label2rgb
-def label2rgb(lbl, img=None, n_labels=None, alpha=0.5, thresh_suppress=0):
-    if n_labels is None:
-        n_labels = len(np.unique(lbl))
-
-    cmap = label_colormap(n_labels)
-    cmap = (cmap * 255).astype(np.uint8)
-
-    lbl_viz = cmap[lbl]
-    lbl_viz[lbl == -1] = (0, 0, 0)  # unlabeled
-
-    if img is not None:
-        img_gray = PIL.Image.fromarray(img).convert('LA')
-        img_gray = np.asarray(img_gray.convert('RGB'))
-        # img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
-        # img_gray = cv2.cvtColor(img_gray, cv2.COLOR_GRAY2RGB)
-        lbl_viz = alpha * lbl_viz + (1 - alpha) * img_gray
-        lbl_viz = lbl_viz.astype(np.uint8)
-
-    return lbl_viz
-
-
-def img_b64_to_array(img_b64):
-    warnings.warn('img_ba64_to_array is deprecated. '
-                  'Please use img_b64_to_arr.')
-    return img_b64_to_arr(img_b64)
-
-
-def img_b64_to_arr(img_b64):
-    f = io.BytesIO()
-    f.write(base64.b64decode(img_b64))
-    img_arr = np.array(PIL.Image.open(f))
-    return img_arr
-
-
-def img_arr_to_b64(img_arr):
-    img_pil = PIL.Image.fromarray(img_arr)
-    f = io.BytesIO()
-    img_pil.save(f, format='PNG')
-    img_bin = f.getvalue()
-    img_b64 = base64.encodestring(img_bin)
-    return img_b64
-
-
-def polygons_to_mask(img_shape, polygons):
-    mask = np.zeros(img_shape[:2], dtype=np.uint8)
-    mask = PIL.Image.fromarray(mask)
-    xy = list(map(tuple, polygons))
-    PIL.ImageDraw.Draw(mask).polygon(xy=xy, outline=1, fill=1)
-    mask = np.array(mask, dtype=bool)
-    return mask
-
-
-def draw_label(label, img=None, label_names=None, colormap=None):
-    import matplotlib.pyplot as plt
-    backend_org = plt.rcParams['backend']
-    plt.switch_backend('agg')
-
-    plt.subplots_adjust(left=0, right=1, top=1, bottom=0,
-                        wspace=0, hspace=0)
-    plt.margins(0, 0)
-    plt.gca().xaxis.set_major_locator(plt.NullLocator())
-    plt.gca().yaxis.set_major_locator(plt.NullLocator())
-
-    if label_names is None:
-        label_names = [str(l) for l in range(label.max() + 1)]
-
-    if colormap is None:
-        colormap = label_colormap(len(label_names))
-
-    label_viz = label2rgb(label, img, n_labels=len(label_names))
-    plt.imshow(label_viz)
-    plt.axis('off')
-
-    plt_handlers = []
-    plt_titles = []
-    for label_value, label_name in enumerate(label_names):
-        if label_value not in label:
-            continue
-        if label_name.startswith('_'):
-            continue
-        fc = colormap[label_value]
-        p = plt.Rectangle((0, 0), 1, 1, fc=fc)
-        plt_handlers.append(p)
-        plt_titles.append('{value}: {name}'
-                          .format(value=label_value, name=label_name))
-    plt.legend(plt_handlers, plt_titles, loc='lower right', framealpha=.5)
-
-    f = io.BytesIO()
-    plt.savefig(f, bbox_inches='tight', pad_inches=0)
-    plt.cla()
-    plt.close()
-
-    plt.switch_backend(backend_org)
-
-    out_size = (label_viz.shape[1], label_viz.shape[0])
-    out = PIL.Image.open(f).resize(out_size, PIL.Image.BILINEAR).convert('RGB')
-    out = np.asarray(out)
-    return out
-
-
-def shapes_to_label(img_shape, shapes, label_name_to_value, type='class'):
-    assert type in ['class', 'instance']
-
-    cls = np.zeros(img_shape[:2], dtype=np.int32)
-    if type == 'instance':
-        ins = np.zeros(img_shape[:2], dtype=np.int32)
-        instance_names = ['_background_']
-    for shape in shapes:
-        polygons = shape['points']
-        label = shape['label']
-        if type == 'class':
-            cls_name = label
-        elif type == 'instance':
-            cls_name = label.split('-')[0]
-            if label not in instance_names:
-                instance_names.append(label)
-            ins_id = len(instance_names) - 1
-        cls_id = label_name_to_value[cls_name]
-        mask = polygons_to_mask(img_shape[:2], polygons)
-        cls[mask] = cls_id
-        if type == 'instance':
-            ins[mask] = ins_id
-
-    if type == 'instance':
-        return cls, ins
-    return cls
-
-
-def labelme_shapes_to_label(img_shape, shapes):
-    warnings.warn('labelme_shapes_to_label is deprecated, so please use '
-                  'shapes_to_label.')
-
-    label_name_to_value = {'_background_': 0}
-    for shape in shapes:
-        label_name = shape['label']
-        if label_name in label_name_to_value:
-            label_value = label_name_to_value[label_name]
-        else:
-            label_value = len(label_name_to_value)
-            label_name_to_value[label_name] = label_value
-
-    lbl = shapes_to_label(img_shape, shapes, label_name_to_value)
-    return lbl, label_name_to_value
-
-
-def lblsave(filename, lbl):
-    if osp.splitext(filename)[1] != '.png':
-        filename += '.png'
-    # Assume label ranses [-1, 254] for int32,
-    # and [0, 255] for uint8 as VOC.
-    if lbl.min() >= -1 and lbl.max() < 255:
-        lbl_pil = PIL.Image.fromarray(lbl.astype(np.uint8), mode='P')
-        colormap = label_colormap(255)
-        lbl_pil.putpalette((colormap * 255).astype(np.uint8).flatten())
-        lbl_pil.save(filename)
-    else:
-        logger.warn(
-            '[%s] Cannot save the pixel-wise class label as PNG, '
-            'so please use the npy file.' % filename
-        )

+ 24 - 0
labelme/utils/__init__.py

@@ -0,0 +1,24 @@
+# flake8: noqa
+
+from ._io import lblsave
+
+from .image import img_arr_to_b64
+from .image import img_b64_to_arr
+
+from .shape import labelme_shapes_to_label
+from .shape import polygons_to_mask
+from .shape import shapes_to_label
+
+from .draw import draw_label
+from .draw import label_colormap
+from .draw import label2rgb
+
+from .qt import newIcon
+from .qt import newButton
+from .qt import newAction
+from .qt import addActions
+from .qt import labelValidator
+from .qt import struct
+from .qt import distance
+from .qt import distancetoline
+from .qt import fmtShortcut

+ 24 - 0
labelme/utils/_io.py

@@ -0,0 +1,24 @@
+import os.path as osp
+
+import numpy as np
+import PIL.Image
+
+from labelme import logger
+from labelme.utils.draw import label_colormap
+
+
+def lblsave(filename, lbl):
+    if osp.splitext(filename)[1] != '.png':
+        filename += '.png'
+    # Assume label ranses [-1, 254] for int32,
+    # and [0, 255] for uint8 as VOC.
+    if lbl.min() >= -1 and lbl.max() < 255:
+        lbl_pil = PIL.Image.fromarray(lbl.astype(np.uint8), mode='P')
+        colormap = label_colormap(255)
+        lbl_pil.putpalette((colormap * 255).astype(np.uint8).flatten())
+        lbl_pil.save(filename)
+    else:
+        logger.warn(
+            '[%s] Cannot save the pixel-wise class label as PNG, '
+            'so please use the npy file.' % filename
+        )

+ 96 - 0
labelme/utils/draw.py

@@ -0,0 +1,96 @@
+import io
+
+import numpy as np
+import PIL.Image
+import PIL.ImageDraw
+
+
+def label_colormap(N=256):
+
+    def bitget(byteval, idx):
+        return ((byteval & (1 << idx)) != 0)
+
+    cmap = np.zeros((N, 3))
+    for i in range(0, N):
+        id = i
+        r, g, b = 0, 0, 0
+        for j in range(0, 8):
+            r = np.bitwise_or(r, (bitget(id, 0) << 7 - j))
+            g = np.bitwise_or(g, (bitget(id, 1) << 7 - j))
+            b = np.bitwise_or(b, (bitget(id, 2) << 7 - j))
+            id = (id >> 3)
+        cmap[i, 0] = r
+        cmap[i, 1] = g
+        cmap[i, 2] = b
+    cmap = cmap.astype(np.float32) / 255
+    return cmap
+
+
+# similar function as skimage.color.label2rgb
+def label2rgb(lbl, img=None, n_labels=None, alpha=0.5, thresh_suppress=0):
+    if n_labels is None:
+        n_labels = len(np.unique(lbl))
+
+    cmap = label_colormap(n_labels)
+    cmap = (cmap * 255).astype(np.uint8)
+
+    lbl_viz = cmap[lbl]
+    lbl_viz[lbl == -1] = (0, 0, 0)  # unlabeled
+
+    if img is not None:
+        img_gray = PIL.Image.fromarray(img).convert('LA')
+        img_gray = np.asarray(img_gray.convert('RGB'))
+        # img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
+        # img_gray = cv2.cvtColor(img_gray, cv2.COLOR_GRAY2RGB)
+        lbl_viz = alpha * lbl_viz + (1 - alpha) * img_gray
+        lbl_viz = lbl_viz.astype(np.uint8)
+
+    return lbl_viz
+
+
+def draw_label(label, img=None, label_names=None, colormap=None):
+    import matplotlib.pyplot as plt
+    backend_org = plt.rcParams['backend']
+    plt.switch_backend('agg')
+
+    plt.subplots_adjust(left=0, right=1, top=1, bottom=0,
+                        wspace=0, hspace=0)
+    plt.margins(0, 0)
+    plt.gca().xaxis.set_major_locator(plt.NullLocator())
+    plt.gca().yaxis.set_major_locator(plt.NullLocator())
+
+    if label_names is None:
+        label_names = [str(l) for l in range(label.max() + 1)]
+
+    if colormap is None:
+        colormap = label_colormap(len(label_names))
+
+    label_viz = label2rgb(label, img, n_labels=len(label_names))
+    plt.imshow(label_viz)
+    plt.axis('off')
+
+    plt_handlers = []
+    plt_titles = []
+    for label_value, label_name in enumerate(label_names):
+        if label_value not in label:
+            continue
+        if label_name.startswith('_'):
+            continue
+        fc = colormap[label_value]
+        p = plt.Rectangle((0, 0), 1, 1, fc=fc)
+        plt_handlers.append(p)
+        plt_titles.append('{value}: {name}'
+                          .format(value=label_value, name=label_name))
+    plt.legend(plt_handlers, plt_titles, loc='lower right', framealpha=.5)
+
+    f = io.BytesIO()
+    plt.savefig(f, bbox_inches='tight', pad_inches=0)
+    plt.cla()
+    plt.close()
+
+    plt.switch_backend(backend_org)
+
+    out_size = (label_viz.shape[1], label_viz.shape[0])
+    out = PIL.Image.open(f).resize(out_size, PIL.Image.BILINEAR).convert('RGB')
+    out = np.asarray(out)
+    return out

+ 21 - 0
labelme/utils/image.py

@@ -0,0 +1,21 @@
+import base64
+import io
+
+import numpy as np
+import PIL.Image
+
+
+def img_b64_to_arr(img_b64):
+    f = io.BytesIO()
+    f.write(base64.b64decode(img_b64))
+    img_arr = np.array(PIL.Image.open(f))
+    return img_arr
+
+
+def img_arr_to_b64(img_arr):
+    img_pil = PIL.Image.fromarray(img_arr)
+    f = io.BytesIO()
+    img_pil.save(f, format='PNG')
+    img_bin = f.getvalue()
+    img_b64 = base64.encodestring(img_bin)
+    return img_b64

+ 0 - 0
labelme/lib.py → labelme/utils/qt.py


+ 59 - 0
labelme/utils/shape.py

@@ -0,0 +1,59 @@
+import numpy as np
+import PIL.Image
+import PIL.ImageDraw
+
+from labelme import logger
+
+
+def polygons_to_mask(img_shape, polygons):
+    mask = np.zeros(img_shape[:2], dtype=np.uint8)
+    mask = PIL.Image.fromarray(mask)
+    xy = list(map(tuple, polygons))
+    PIL.ImageDraw.Draw(mask).polygon(xy=xy, outline=1, fill=1)
+    mask = np.array(mask, dtype=bool)
+    return mask
+
+
+def shapes_to_label(img_shape, shapes, label_name_to_value, type='class'):
+    assert type in ['class', 'instance']
+
+    cls = np.zeros(img_shape[:2], dtype=np.int32)
+    if type == 'instance':
+        ins = np.zeros(img_shape[:2], dtype=np.int32)
+        instance_names = ['_background_']
+    for shape in shapes:
+        polygons = shape['points']
+        label = shape['label']
+        if type == 'class':
+            cls_name = label
+        elif type == 'instance':
+            cls_name = label.split('-')[0]
+            if label not in instance_names:
+                instance_names.append(label)
+            ins_id = len(instance_names) - 1
+        cls_id = label_name_to_value[cls_name]
+        mask = polygons_to_mask(img_shape[:2], polygons)
+        cls[mask] = cls_id
+        if type == 'instance':
+            ins[mask] = ins_id
+
+    if type == 'instance':
+        return cls, ins
+    return cls
+
+
+def labelme_shapes_to_label(img_shape, shapes):
+    logger.warn('labelme_shapes_to_label is deprecated, so please use '
+                'shapes_to_label.')
+
+    label_name_to_value = {'_background_': 0}
+    for shape in shapes:
+        label_name = shape['label']
+        if label_name in label_name_to_value:
+            label_value = label_name_to_value[label_name]
+        else:
+            label_value = len(label_name_to_value)
+            label_name_to_value[label_name] = label_value
+
+    lbl = shapes_to_label(img_shape, shapes, label_name_to_value)
+    return lbl, label_name_to_value

+ 5 - 0
labelme/widgets/__init__.py

@@ -1,7 +1,12 @@
 # flake8: noqa
 
 from .canvas import Canvas
+
 from .color_dialog import ColorDialog
+
 from .label_dialog import LabelDialog
+from .label_dialog import LabelQLineEdit
+
 from .tool_bar import ToolBar
+
 from .zoom_widget import ZoomWidget

+ 3 - 3
labelme/widgets/canvas.py

@@ -2,9 +2,9 @@ from qtpy import QtCore
 from qtpy import QtGui
 from qtpy import QtWidgets
 
-from labelme.lib import distance
 from labelme import QT5
 from labelme.shape import Shape
+import labelme.utils
 
 
 # TODO(unknown):
@@ -519,7 +519,7 @@ class Canvas(QtWidgets.QWidget):
         # d = distance(p1 - p2)
         # m = (p1-p2).manhattanLength()
         # print "d %.2f, m %d, %.2f" % (d, m, d - m)
-        return distance(p1 - p2) < self.epsilon
+        return labelme.utils.distance(p1 - p2) < self.epsilon
 
     def intersectionPoint(self, p1, p2):
         # Cycle through each image edge in clockwise fashion,
@@ -569,7 +569,7 @@ class Canvas(QtWidgets.QWidget):
                 x = x1 + ua * (x2 - x1)
                 y = y1 + ua * (y2 - y1)
                 m = QtCore.QPoint((x3 + x4) / 2, (y3 + y4) / 2)
-                d = distance(m - QtCore.QPoint(x2, y2))
+                d = labelme.utils.distance(m - QtCore.QPoint(x2, y2))
                 yield d, i, (x, y)
 
     # These two, along with a call to adjustSize are required for the

+ 4 - 5
labelme/widgets/label_dialog.py

@@ -5,8 +5,7 @@ from qtpy import QtWidgets
 
 QT5 = QT_VERSION[0] == '5'  # NOQA
 
-from labelme.lib import labelValidator
-from labelme.lib import newIcon
+import labelme.utils
 
 
 # TODO(unknown):
@@ -32,7 +31,7 @@ class LabelDialog(QtWidgets.QDialog):
         super(LabelDialog, self).__init__(parent)
         self.edit = LabelQLineEdit()
         self.edit.setPlaceholderText(text)
-        self.edit.setValidator(labelValidator())
+        self.edit.setValidator(labelme.utils.labelValidator())
         self.edit.editingFinished.connect(self.postProcess)
         layout = QtWidgets.QVBoxLayout()
         if show_text_field:
@@ -43,8 +42,8 @@ class LabelDialog(QtWidgets.QDialog):
             QtCore.Qt.Horizontal,
             self,
         )
-        bb.button(bb.Ok).setIcon(newIcon('done'))
-        bb.button(bb.Cancel).setIcon(newIcon('undo'))
+        bb.button(bb.Ok).setIcon(labelme.utils.newIcon('done'))
+        bb.button(bb.Cancel).setIcon(labelme.utils.newIcon('undo'))
         bb.accepted.connect(self.validate)
         bb.rejected.connect(self.reject)
         layout.addWidget(bb)