Add single mode features and fix minor issues
This commit is contained in:
parent
4015a0eab5
commit
a09ecbb7bb
76
labelImg.py
76
labelImg.py
@ -26,20 +26,17 @@ except ImportError:
|
|||||||
|
|
||||||
import resources
|
import resources
|
||||||
# Add internal libs
|
# Add internal libs
|
||||||
dir_name = os.path.abspath(os.path.dirname(__file__))
|
from libs.lib import struct, newAction, newIcon, addActions, fmtShortcut
|
||||||
libs_path = os.path.join(dir_name, 'libs')
|
from libs.shape import Shape, DEFAULT_LINE_COLOR, DEFAULT_FILL_COLOR
|
||||||
sys.path.insert(0, libs_path)
|
from libs.canvas import Canvas
|
||||||
from lib import struct, newAction, newIcon, addActions, fmtShortcut
|
from libs.zoomWidget import ZoomWidget
|
||||||
from shape import Shape, DEFAULT_LINE_COLOR, DEFAULT_FILL_COLOR
|
from libs.labelDialog import LabelDialog
|
||||||
from canvas import Canvas
|
from libs.colorDialog import ColorDialog
|
||||||
from zoomWidget import ZoomWidget
|
from libs.labelFile import LabelFile, LabelFileError
|
||||||
from labelDialog import LabelDialog
|
from libs.toolBar import ToolBar
|
||||||
from colorDialog import ColorDialog
|
from libs.pascal_voc_io import PascalVocReader
|
||||||
from labelFile import LabelFile, LabelFileError
|
from libs.pascal_voc_io import XML_EXT
|
||||||
from toolBar import ToolBar
|
from libs.ustr import ustr
|
||||||
from pascal_voc_io import PascalVocReader
|
|
||||||
from pascal_voc_io import XML_EXT
|
|
||||||
from ustr import ustr
|
|
||||||
|
|
||||||
__appname__ = 'labelImg'
|
__appname__ = 'labelImg'
|
||||||
|
|
||||||
@ -102,8 +99,6 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||||||
# Whether we need to save or not.
|
# Whether we need to save or not.
|
||||||
self.dirty = False
|
self.dirty = False
|
||||||
|
|
||||||
# Enble auto saving if pressing next
|
|
||||||
self.autoSaving = True
|
|
||||||
self._noSelectionSlot = False
|
self._noSelectionSlot = False
|
||||||
self._beginner = True
|
self._beginner = True
|
||||||
self.screencastViewer = "firefox"
|
self.screencastViewer = "firefox"
|
||||||
@ -111,19 +106,19 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||||||
|
|
||||||
# Main widgets and related state.
|
# Main widgets and related state.
|
||||||
self.labelDialog = LabelDialog(parent=self, listItem=self.labelHist)
|
self.labelDialog = LabelDialog(parent=self, listItem=self.labelHist)
|
||||||
|
|
||||||
self.itemsToShapes = {}
|
self.itemsToShapes = {}
|
||||||
self.shapesToItems = {}
|
self.shapesToItems = {}
|
||||||
self.prevLabelText = ''
|
self.prevLabelText = ''
|
||||||
|
|
||||||
listLayout = QVBoxLayout()
|
listLayout = QVBoxLayout()
|
||||||
listLayout.setContentsMargins(0, 0, 0, 0)
|
listLayout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
|
||||||
# Create a widget for using default label
|
# Create a widget for using default label
|
||||||
self.useDefautLabelCheckbox = QCheckBox(u'Use default label')
|
self.useDefautLabelCheckbox = QCheckBox(u'Use default label')
|
||||||
self.useDefautLabelCheckbox.setChecked(False)
|
self.useDefautLabelCheckbox.setChecked(False)
|
||||||
self.defaultLabelTextLine = QLineEdit()
|
self.defaultLabelTextLine = QLineEdit()
|
||||||
useDefautLabelQHBoxLayout = QHBoxLayout()
|
useDefautLabelQHBoxLayout = QHBoxLayout()
|
||||||
useDefautLabelQHBoxLayout.addWidget(self.useDefautLabelCheckbox)
|
useDefautLabelQHBoxLayout.addWidget(self.useDefautLabelCheckbox)
|
||||||
useDefautLabelQHBoxLayout.addWidget(self.defaultLabelTextLine)
|
useDefautLabelQHBoxLayout.addWidget(self.defaultLabelTextLine)
|
||||||
useDefautLabelContainer = QWidget()
|
useDefautLabelContainer = QWidget()
|
||||||
@ -136,7 +131,7 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||||||
self.editButton = QToolButton()
|
self.editButton = QToolButton()
|
||||||
self.editButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
|
self.editButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
|
||||||
|
|
||||||
# Add some of widgets to listLayout
|
# Add some of widgets to listLayout
|
||||||
listLayout.addWidget(self.editButton)
|
listLayout.addWidget(self.editButton)
|
||||||
listLayout.addWidget(self.diffcButton)
|
listLayout.addWidget(self.diffcButton)
|
||||||
listLayout.addWidget(useDefautLabelContainer)
|
listLayout.addWidget(useDefautLabelContainer)
|
||||||
@ -208,11 +203,11 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||||||
opendir = action('&Open Dir', self.openDir,
|
opendir = action('&Open Dir', self.openDir,
|
||||||
'Ctrl+u', 'open', u'Open Dir')
|
'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')
|
'Ctrl+r', 'open', u'Change default saved Annotation dir')
|
||||||
|
|
||||||
openAnnotation = action('&Open Annotation', self.openAnnotation,
|
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,
|
openNextImg = action('&Next Image', self.openNextImg,
|
||||||
'd', 'next', u'Open Next')
|
'd', 'next', u'Open Next')
|
||||||
@ -345,10 +340,22 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||||||
recentFiles=QMenu('Open &Recent'),
|
recentFiles=QMenu('Open &Recent'),
|
||||||
labelList=labelMenu)
|
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,
|
addActions(self.menus.file,
|
||||||
(open, opendir, changeSavedir, openAnnotation, self.menus.recentFiles, save, saveAs, close, None, quit))
|
(open, opendir, changeSavedir, openAnnotation, self.menus.recentFiles, save, saveAs, close, None, quit))
|
||||||
addActions(self.menus.help, (help,))
|
addActions(self.menus.help, (help,))
|
||||||
addActions(self.menus.view, (
|
addActions(self.menus.view, (
|
||||||
|
self.autoSaving,
|
||||||
|
self.singleClassMode,
|
||||||
labels, advancedMode, None,
|
labels, advancedMode, None,
|
||||||
hideAll, showAll, None,
|
hideAll, showAll, None,
|
||||||
zoomIn, zoomOut, zoomOrg, None,
|
zoomIn, zoomOut, zoomOrg, None,
|
||||||
@ -364,11 +371,11 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||||||
|
|
||||||
self.tools = self.toolbar('Tools')
|
self.tools = self.toolbar('Tools')
|
||||||
self.actions.beginner = (
|
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)
|
zoomIn, zoom, zoomOut, fitWindow, fitWidth)
|
||||||
|
|
||||||
self.actions.advanced = (
|
self.actions.advanced = (
|
||||||
open, save, None,
|
open, opendir, changeSavedir, openNextImg, openPrevImg, save, None,
|
||||||
createMode, editMode, None,
|
createMode, editMode, None,
|
||||||
hideAll, showAll)
|
hideAll, showAll)
|
||||||
|
|
||||||
@ -769,7 +776,12 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||||||
self.labelDialog = LabelDialog(
|
self.labelDialog = LabelDialog(
|
||||||
parent=self, listItem=self.labelHist)
|
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:
|
else:
|
||||||
text = self.defaultLabelTextLine.text()
|
text = self.defaultLabelTextLine.text()
|
||||||
|
|
||||||
@ -1046,14 +1058,15 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||||||
|
|
||||||
def openAnnotation(self, _value=False):
|
def openAnnotation(self, _value=False):
|
||||||
if self.filePath is None:
|
if self.filePath is None:
|
||||||
|
self.statusBar().showMessage('Please select image first')
|
||||||
|
self.statusBar().show()
|
||||||
return
|
return
|
||||||
|
|
||||||
path = os.path.dirname(ustr(self.filePath))\
|
path = os.path.dirname(ustr(self.filePath))\
|
||||||
if self.filePath else '.'
|
if self.filePath else '.'
|
||||||
if self.usingPascalVocFormat:
|
if self.usingPascalVocFormat:
|
||||||
filters = "Open Annotation XML file (%s)" % \
|
filters = "Open Annotation XML file (%s)" % ' '.join(['*.xml'])
|
||||||
' '.join(['*.xml'])
|
filename = ustr(QFileDialog.getOpenFileName(self,'%s - Choose a xml file' % __appname__, path, filters))
|
||||||
filename = QFileDialog.getOpenFileName(self,'%s - Choose a xml file' % __appname__, path, filters)
|
|
||||||
if filename:
|
if filename:
|
||||||
if isinstance(filename, (tuple, list)):
|
if isinstance(filename, (tuple, list)):
|
||||||
filename = filename[0]
|
filename = filename[0]
|
||||||
@ -1101,6 +1114,11 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||||||
self.saveFile()
|
self.saveFile()
|
||||||
|
|
||||||
def openPrevImg(self, _value=False):
|
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():
|
if not self.mayContinue():
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -1118,7 +1136,7 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||||||
|
|
||||||
def openNextImg(self, _value=False):
|
def openNextImg(self, _value=False):
|
||||||
# Proceding next image without dialog if having any label
|
# 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:
|
if self.dirty is True:
|
||||||
self.saveFile()
|
self.saveFile()
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user