From a09ecbb7bb0004d6e779c225bf1bbcc6eef47360 Mon Sep 17 00:00:00 2001 From: tzutalin Date: Fri, 21 Jul 2017 17:32:30 +0800 Subject: [PATCH] Add single mode features and fix minor issues --- labelImg.py | 76 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/labelImg.py b/labelImg.py index ad42ecd7..baadf695 100755 --- a/labelImg.py +++ b/labelImg.py @@ -26,20 +26,17 @@ except ImportError: import resources # Add internal libs -dir_name = os.path.abspath(os.path.dirname(__file__)) -libs_path = os.path.join(dir_name, 'libs') -sys.path.insert(0, libs_path) -from lib import struct, newAction, newIcon, addActions, fmtShortcut -from shape import Shape, DEFAULT_LINE_COLOR, DEFAULT_FILL_COLOR -from canvas import Canvas -from zoomWidget import ZoomWidget -from labelDialog import LabelDialog -from colorDialog import ColorDialog -from labelFile import LabelFile, LabelFileError -from toolBar import ToolBar -from pascal_voc_io import PascalVocReader -from pascal_voc_io import XML_EXT -from ustr import ustr +from libs.lib import struct, newAction, newIcon, addActions, fmtShortcut +from libs.shape import Shape, DEFAULT_LINE_COLOR, DEFAULT_FILL_COLOR +from libs.canvas import Canvas +from libs.zoomWidget import ZoomWidget +from libs.labelDialog import LabelDialog +from libs.colorDialog import ColorDialog +from libs.labelFile import LabelFile, LabelFileError +from libs.toolBar import ToolBar +from libs.pascal_voc_io import PascalVocReader +from libs.pascal_voc_io import XML_EXT +from libs.ustr import ustr __appname__ = 'labelImg' @@ -102,8 +99,6 @@ class MainWindow(QMainWindow, WindowMixin): # Whether we need to save or not. self.dirty = False - # Enble auto saving if pressing next - self.autoSaving = True self._noSelectionSlot = False self._beginner = True self.screencastViewer = "firefox" @@ -111,19 +106,19 @@ class MainWindow(QMainWindow, WindowMixin): # Main widgets and related state. self.labelDialog = LabelDialog(parent=self, listItem=self.labelHist) - + self.itemsToShapes = {} self.shapesToItems = {} self.prevLabelText = '' listLayout = QVBoxLayout() listLayout.setContentsMargins(0, 0, 0, 0) - + # Create a widget for using default label self.useDefautLabelCheckbox = QCheckBox(u'Use default label') self.useDefautLabelCheckbox.setChecked(False) self.defaultLabelTextLine = QLineEdit() - useDefautLabelQHBoxLayout = QHBoxLayout() + useDefautLabelQHBoxLayout = QHBoxLayout() useDefautLabelQHBoxLayout.addWidget(self.useDefautLabelCheckbox) useDefautLabelQHBoxLayout.addWidget(self.defaultLabelTextLine) useDefautLabelContainer = QWidget() @@ -136,7 +131,7 @@ class MainWindow(QMainWindow, WindowMixin): self.editButton = QToolButton() self.editButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) - # Add some of widgets to listLayout + # Add some of widgets to listLayout listLayout.addWidget(self.editButton) listLayout.addWidget(self.diffcButton) listLayout.addWidget(useDefautLabelContainer) @@ -208,11 +203,11 @@ class MainWindow(QMainWindow, WindowMixin): opendir = action('&Open Dir', self.openDir, 'Ctrl+u', 'open', u'Open Dir') - changeSavedir = action('&Change default saved Annotation dir', self.changeSavedir, + changeSavedir = action('&Change Save Dir', self.changeSavedir, 'Ctrl+r', 'open', u'Change default saved Annotation dir') openAnnotation = action('&Open Annotation', self.openAnnotation, - 'Ctrl+Shift+O', 'openAnnotation', u'Open Annotation') + 'Ctrl+Shift+O', 'open', u'Open Annotation') openNextImg = action('&Next Image', self.openNextImg, 'd', 'next', u'Open Next') @@ -345,10 +340,22 @@ class MainWindow(QMainWindow, WindowMixin): recentFiles=QMenu('Open &Recent'), labelList=labelMenu) + # Auto saving : Enble auto saving if pressing next + self.autoSaving = QAction("Auto Saving", self) + self.autoSaving.setCheckable(True) + + # Sync single class mode from PR#106 + self.singleClassMode = QAction("Single Class Mode", self) + self.singleClassMode.setShortcut("Ctrl+Shift+S") + self.singleClassMode.setCheckable(True) + self.lastLabel = None + addActions(self.menus.file, (open, opendir, changeSavedir, openAnnotation, self.menus.recentFiles, save, saveAs, close, None, quit)) addActions(self.menus.help, (help,)) addActions(self.menus.view, ( + self.autoSaving, + self.singleClassMode, labels, advancedMode, None, hideAll, showAll, None, zoomIn, zoomOut, zoomOrg, None, @@ -364,11 +371,11 @@ class MainWindow(QMainWindow, WindowMixin): self.tools = self.toolbar('Tools') self.actions.beginner = ( - open, opendir, openNextImg, openPrevImg, verify, save, None, create, copy, delete, None, + open, opendir, changeSavedir, openNextImg, openPrevImg, verify, save, None, create, copy, delete, None, zoomIn, zoom, zoomOut, fitWindow, fitWidth) self.actions.advanced = ( - open, save, None, + open, opendir, changeSavedir, openNextImg, openPrevImg, save, None, createMode, editMode, None, hideAll, showAll) @@ -769,7 +776,12 @@ class MainWindow(QMainWindow, WindowMixin): self.labelDialog = LabelDialog( parent=self, listItem=self.labelHist) - text = self.labelDialog.popUp(text=self.prevLabelText) + # Sync single class mode from PR#106 + if self.singleClassMode.isChecked() and self.lastLabel: + text = self.lastLabel + else: + text = self.labelDialog.popUp(text=self.prevLabelText) + self.lastLabel = text else: text = self.defaultLabelTextLine.text() @@ -1046,14 +1058,15 @@ class MainWindow(QMainWindow, WindowMixin): def openAnnotation(self, _value=False): if self.filePath is None: + self.statusBar().showMessage('Please select image first') + self.statusBar().show() return path = os.path.dirname(ustr(self.filePath))\ if self.filePath else '.' if self.usingPascalVocFormat: - filters = "Open Annotation XML file (%s)" % \ - ' '.join(['*.xml']) - filename = QFileDialog.getOpenFileName(self,'%s - Choose a xml file' % __appname__, path, filters) + filters = "Open Annotation XML file (%s)" % ' '.join(['*.xml']) + filename = ustr(QFileDialog.getOpenFileName(self,'%s - Choose a xml file' % __appname__, path, filters)) if filename: if isinstance(filename, (tuple, list)): filename = filename[0] @@ -1101,6 +1114,11 @@ class MainWindow(QMainWindow, WindowMixin): self.saveFile() def openPrevImg(self, _value=False): + # Proceding prev image without dialog if having any label + if self.autoSaving.isChecked() and self.defaultSaveDir is not None: + if self.dirty is True: + self.saveFile() + if not self.mayContinue(): return @@ -1118,7 +1136,7 @@ class MainWindow(QMainWindow, WindowMixin): def openNextImg(self, _value=False): # Proceding next image without dialog if having any label - if self.autoSaving is True and self.defaultSaveDir is not None: + if self.autoSaving.isChecked() and self.defaultSaveDir is not None: if self.dirty is True: self.saveFile()