def get_config(config_from_args=None, config_file=None): # Configuration load order: # # 1. default config (lowest priority) # 2. config file passed by command line argument or ~/.labelmerc # 3. command line argument (highest priority) # 1. default config config = get_default_config() # save default config to ~/.labelmerc home = osp.expanduser('~') default_config_file = osp.join(home, '.labelmerc') if not osp.exists(default_config_file): try: with open(default_config_file, 'w') as f: yaml.safe_dump(config, f, default_flow_style=False) except Exception: logger.warn('Failed to save config: {}' .format(default_config_file)) # 2. config from yaml file if config_file is None: config_file = default_config_file if osp.exists(config_file): with open(config_file) as f: user_config = yaml.load(f) or {} update_dict(config, user_config, validate_item=validate_config_item) # 3. command line argument if config_from_args is not None: update_dict(config, config_from_args, validate_item=validate_config_item) return config
def get_config(config_from_args=None, config_file=None): # Configuration load order: # # 1. default config (lowest priority) # 2. config file passed by command line argument or ~/.labelmerc # 3. command line argument (highest priority) # 1. default config config = get_default_config() # save default config to ~/.labelmerc home = osp.expanduser('~') default_config_file = osp.join(home, '.labelmerc') if not osp.exists(default_config_file): try: with open(config_file, 'w') as f: yaml.safe_dump(config, f, default_flow_style=False) except Exception: logger.warn('Failed to save config: {}'.format(config_file)) # 2. config from yaml file if config_file is None: config_file = default_config_file if osp.exists(config_file): with open(config_file) as f: user_config = yaml.load(f) or {} update_dict(config, user_config, validate_item=validate_config_item) # 3. command line argument if config_from_args is not None: update_dict(config, config_from_args, validate_item=validate_config_item) return config
def get_config(config_from_args=None, config_file=None): # default config config = get_default_config() if config_from_args is not None: update_dict(config, config_from_args, validate_item=validate_config_item) save_config_file = False if config_file is None: home = os.path.expanduser('~') config_file = os.path.join(home, '.labelmerc') save_config_file = True if os.path.exists(config_file): with open(config_file) as f: user_config = yaml.load(f) or {} update_dict(config, user_config, validate_item=validate_config_item) if save_config_file: try: with open(config_file, 'w') as f: yaml.safe_dump(config, f, default_flow_style=False) except Exception: logger.warn('Failed to save config: {}'.format(config_file)) return config
def __init__(self, text="Enter object label", parent=None, labels=None, sort_labels=True, show_text_field=True, completion='startswith'): super(LabelDialog, self).__init__(parent) self.edit = LabelQLineEdit() self.edit.setPlaceholderText(text) self.edit.setValidator(labelme.utils.labelValidator()) self.edit.editingFinished.connect(self.postProcess) layout = QtWidgets.QVBoxLayout() if show_text_field: layout.addWidget(self.edit) # buttons self.buttonBox = bb = QtWidgets.QDialogButtonBox( QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel, QtCore.Qt.Horizontal, self, ) 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) # label_list self.labelList = QtWidgets.QListWidget() self._sort_labels = sort_labels if labels: self.labelList.addItems(labels) if self._sort_labels: self.labelList.sortItems() else: self.labelList.setDragDropMode( QtGui.QAbstractItemView.InternalMove) self.labelList.currentItemChanged.connect(self.labelSelected) self.edit.setListWidget(self.labelList) layout.addWidget(self.labelList) self.setLayout(layout) # completion completer = QtWidgets.QCompleter() if not QT5 and completion != 'startswith': logger.warn("completion other than 'startswith' is only " "supported with Qt5. Using 'startswith'") completion = 'startswith' if completion == 'startswith': completer.setCompletionMode(QtWidgets.QCompleter.InlineCompletion) # Default settings. # completer.setFilterMode(QtCore.Qt.MatchStartsWith) elif completion == 'contains': completer.setCompletionMode(QtWidgets.QCompleter.PopupCompletion) completer.setFilterMode(QtCore.Qt.MatchContains) else: raise ValueError('Unsupported completion: {}'.format(completion)) completer.setModel(self.labelList.model()) self.edit.setCompleter(completer)
def update_dict(target_dict, new_dict): for key, value in new_dict.items(): if key not in target_dict: logger.warn('Skipping unexpected key in config: {}'.format(key)) continue if isinstance(target_dict[key], dict) and \ isinstance(value, dict): update_dict(target_dict[key], value) else: target_dict[key] = value
def __init__(self, text="Enter object label", parent=None, labels=None, sort_labels=True, show_text_field=True, completion='startswith'): super(LabelDialog, self).__init__(parent) self.edit = LabelQLineEdit() self.edit.setPlaceholderText(text) self.edit.setValidator(labelme.utils.labelValidator()) self.edit.editingFinished.connect(self.postProcess) layout = QtWidgets.QVBoxLayout() if show_text_field: layout.addWidget(self.edit) # buttons self.buttonBox = bb = QtWidgets.QDialogButtonBox( QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel, QtCore.Qt.Horizontal, self, ) 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) # label_list self.labelList = QtWidgets.QListWidget() self._sort_labels = sort_labels if labels: self.labelList.addItems(labels) if self._sort_labels: self.labelList.sortItems() else: self.labelList.setDragDropMode( QtGui.QAbstractItemView.InternalMove) self.labelList.currentItemChanged.connect(self.labelSelected) self.edit.setListWidget(self.labelList) layout.addWidget(self.labelList) self.setLayout(layout) # completion completer = QtWidgets.QCompleter() if not QT5 and completion != 'startswith': logger.warn( "completion other than 'startswith' is only " "supported with Qt5. Using 'startswith'" ) completion = 'startswith' if completion == 'startswith': completer.setCompletionMode(QtWidgets.QCompleter.InlineCompletion) # Default settings. # completer.setFilterMode(QtCore.Qt.MatchStartsWith) elif completion == 'contains': completer.setCompletionMode(QtWidgets.QCompleter.PopupCompletion) completer.setFilterMode(QtCore.Qt.MatchContains) else: raise ValueError('Unsupported completion: {}'.format(completion)) completer.setModel(self.labelList.model()) self.edit.setCompleter(completer)
def update_dict(target_dict, new_dict, validate_item=None): for key, value in new_dict.items(): if validate_item: validate_item(key, value) if key not in target_dict: logger.warn('Skipping unexpected key in config: {}' .format(key)) continue if isinstance(target_dict[key], dict) and \ isinstance(value, dict): update_dict(target_dict[key], value, validate_item=validate_item) else: target_dict[key] = 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)
def get_default_config(): config_file = osp.join(here, 'default_config.yaml') with open(config_file) as f: config = yaml.load(f) # save default config to ~/.labelmerc user_config_file = get_user_config_file() if not osp.exists(user_config_file): try: shutil.copy(config_file, user_config_file) except Exception: logger.warn('Failed to save config: {}'.format(user_config_file)) return config
def get_default_config(): config_file = osp.join(here, 'default_config.yaml') with open(config_file) as f: config = yaml.load(f) # save default config to ~/.labelmerc user_config_file = osp.join(osp.expanduser('~'), '.labelmerc') if not osp.exists(user_config_file): try: shutil.copy(config_file, user_config_file) except Exception: logger.warn('Failed to save config: {}'.format(user_config_file)) return config
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
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 )
def org_lbl_save(filename, org, label): if os.path.splitext(filename)[1] not in ['.png', '.PNG']: filename += '.png' # Assume label ranses [-1, 254] for int32, # and [0, 255] for uint8 as VOC. if label.min() >= -1 and label.max() < 255: org_img = PIL.Image.fromarray(org.astype(np.uint8), mode='RGB') lbl_pil = PIL.Image.fromarray(label.astype(np.uint8), mode='P') colormap = (label_colormap(255) * 255).astype(np.uint8) lbl_pil.putpalette(colormap.flatten()) plt.figure(figsize=(13, 10)) grid_spec = gridspec.GridSpec(2, 2, width_ratios=[5, 5], height_ratios=[8, 2]) plt.subplot(grid_spec[0]) plt.imshow(org_img) plt.axis('off') plt.title('input image') plt.subplot(grid_spec[1]) plt.imshow(lbl_pil) plt.axis('off') plt.title('GT(label image)') label_names, full_color_map = get_label_name_and_map(colormap) unique_labels = range(0, len(label_names)) ax = plt.subplot(grid_spec[3]) plt.imshow(full_color_map[unique_labels].astype(np.uint8), interpolation='nearest') ax.yaxis.tick_right() plt.yticks(range(len(unique_labels)), label_names[unique_labels]) plt.xticks([], []) ax.tick_params(width=0.0) plt.grid('off') plt.savefig(filename) plt.close() else: logger.warn('[%s] Cannot save the pixel-wise class label as PNG, ' 'so please use the npy file.' % filename)
def lblsave(filename, lbl, size=None): if os.path.splitext(filename)[1] not in ['.png', '.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') if size is not None: if isinstance(size, tuple): lbl_pil = lbl_pil.resize(size) else: raise AttributeError( 'size is not set properly. given size:{}'.format(size)) colormap = (label_colormap(255) * 255).astype(np.uint8) lbl_pil.putpalette(colormap.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)
def get_config(): # default config config = get_default_config() # shortcuts for actions home = os.path.expanduser('~') config_file = os.path.join(home, '.labelmerc') if os.path.exists(config_file): user_config = yaml.load(open(config_file)) or {} update_dict(config, user_config) # save config try: yaml.safe_dump(config, open(config_file, 'w'), default_flow_style=False) except Exception: logger.warn('Failed to save config: {}'.format(config_file)) return config
def load(self, filename): keys = [ "version", "imageData", "imagePath", "shapes", # polygonal annotations "flags", # image level flags "imageHeight", "imageWidth", ] shape_keys = [ "label", "points", "group_id", "shape_type", "flags", ] try: with open(filename, "r", encoding='utf-8') as f: data = json.load(f) version = data.get("version") if version is None: logger.warn("Loading JSON file ({}) of unknown version".format( filename)) elif version.split(".")[0] != __version__.split(".")[0]: logger.warn("This JSON file ({}) may be incompatible with " "current labelme. version in file: {}, " "current version: {}".format( filename, version, __version__)) if data["imageData"] is not None: imageData = base64.b64decode(data["imageData"]) # if PY2 and QT4: # imageData = img_data_to_png_data(imageData) else: # relative path from label file to relative path from cwd imagePath = osp.join(osp.dirname(filename), data["imagePath"]) imageData = self.load_image_file(imagePath) flags = data.get("flags") or {} imagePath = data["imagePath"] self._check_image_height_and_width( base64.b64encode(imageData).decode("utf-8"), data.get("imageHeight"), data.get("imageWidth"), ) shapes = [ dict( label=s["label"], points=s["points"], shape_type=s.get("shape_type", "polygon"), flags=s.get("flags", {}), group_id=s.get("group_id"), other_data={ k: v for k, v in s.items() if k not in shape_keys }, ) for s in data["shapes"] ] except Exception as e: raise LabelFileError(e) otherData = {} for key, value in data.items(): if key not in keys: otherData[key] = value # Only replace data after everything is loaded. self.flags = flags self.shapes = shapes self.imagePath = imagePath self.imageData = imageData self.filename = filename self.otherData = otherData
def close(self): if len(self.points) <= 2: logger.warn('Polygon should be created with points >2') self._closed = True
def __init__(self, text="Enter object label", parent=None, labels=None, sort_labels=True, show_text_field=True, completion='startswith', fit_to_content=None): if fit_to_content is None: fit_to_content = {'row': False, 'column': True} self._fit_to_content = fit_to_content super(LabelDialog, self).__init__(parent) self.edit = LabelQLineEdit() self.edit.setPlaceholderText(text) self.edit.setValidator(labelme.utils.labelValidator()) self.edit.editingFinished.connect(self.postProcess) layout = QtWidgets.QVBoxLayout() if show_text_field: layout.addWidget(self.edit) #tags # lihaodong edit self.first_lable = QtWidgets.QLabel() self.first_lable.setText('first') self.first_combox=QtWidgets.QComboBox() self.first_combox.addItem('front') self.first_combox.addItem('left') self.first_combox.addItem('right') self.first_combox.addItem('rear') self.second_lable = QtWidgets.QLabel() self.second_lable.setText('second') self.second_combox = QtWidgets.QComboBox() self.second_combox.addItem('front') self.second_combox.addItem('left') self.second_combox.addItem('right') self.second_combox.addItem('rear') layout.addWidget(self.first_lable) layout.addWidget(self.first_combox) layout.addWidget(self.second_lable) layout.addWidget(self.second_combox) ## # buttons self.buttonBox = bb = QtWidgets.QDialogButtonBox( QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel, QtCore.Qt.Horizontal, self, ) 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) # label_list self.labelList = QtWidgets.QListWidget() if self._fit_to_content['row']: self.labelList.setHorizontalScrollBarPolicy( QtCore.Qt.ScrollBarAlwaysOff ) if self._fit_to_content['column']: self.labelList.setVerticalScrollBarPolicy( QtCore.Qt.ScrollBarAlwaysOff ) self._sort_labels = sort_labels if labels: self.labelList.addItems(labels) if self._sort_labels: self.labelList.sortItems() else: self.labelList.setDragDropMode( QtGui.QAbstractItemView.InternalMove) self.labelList.currentItemChanged.connect(self.labelSelected) self.edit.setListWidget(self.labelList) layout.addWidget(self.labelList) self.setLayout(layout) # completion completer = QtWidgets.QCompleter() if not QT5 and completion != 'startswith': logger.warn( "completion other than 'startswith' is only " "supported with Qt5. Using 'startswith'" ) completion = 'startswith' if completion == 'startswith': completer.setCompletionMode(QtWidgets.QCompleter.InlineCompletion) # Default settings. # completer.setFilterMode(QtCore.Qt.MatchStartsWith) elif completion == 'contains': completer.setCompletionMode(QtWidgets.QCompleter.PopupCompletion) completer.setFilterMode(QtCore.Qt.MatchContains) else: raise ValueError('Unsupported completion: {}'.format(completion)) completer.setModel(self.labelList.model()) self.edit.setCompleter(completer)