提交 c6a7e0e6 编写于 作者: qq_25193841's avatar qq_25193841

Revert code display

上级 e57e6144
...@@ -25,6 +25,7 @@ from functools import partial ...@@ -25,6 +25,7 @@ from functools import partial
from collections import defaultdict from collections import defaultdict
import json import json
__dir__ = os.path.dirname(os.path.abspath(__file__)) __dir__ = os.path.dirname(os.path.abspath(__file__))
sys.path.append(__dir__) sys.path.append(__dir__)
sys.path.append(os.path.abspath(os.path.join(__dir__, '../..'))) sys.path.append(os.path.abspath(os.path.join(__dir__, '../..')))
...@@ -69,13 +70,14 @@ __appname__ = 'PPOCRLabel' ...@@ -69,13 +70,14 @@ __appname__ = 'PPOCRLabel'
class WindowMixin(object): class WindowMixin(object):
def menu(self, title, actions=None): def menu(self, title, actions=None):
menu = self.menuBar().addMenu(title) menu = self.menuBar().addMenu(title)
if actions: if actions:
addActions(menu, actions) addActions(menu, actions)
return menu return menu
def toolbar(self, title, actions=None): def toolbar(self, title, actions=None):
toolbar = ToolBar(title) toolbar = ToolBar(title)
toolbar.setObjectName(u'%sToolBar' % title) toolbar.setObjectName(u'%sToolBar' % title)
# toolbar.setOrientation(Qt.Vertical) # toolbar.setOrientation(Qt.Vertical)
...@@ -89,35 +91,23 @@ class WindowMixin(object): ...@@ -89,35 +91,23 @@ class WindowMixin(object):
class MainWindow(QMainWindow, WindowMixin): class MainWindow(QMainWindow, WindowMixin):
FIT_WINDOW, FIT_WIDTH, MANUAL_ZOOM = list(range(3)) FIT_WINDOW, FIT_WIDTH, MANUAL_ZOOM = list(range(3))
def __init__(self, def __init__(self, lang="ch", defaultFilename=None, defaultPrefdefClassFile=None, defaultSaveDir=None):
lang="ch",
defaultFilename=None,
defaultPrefdefClassFile=None,
defaultSaveDir=None):
super(MainWindow, self).__init__() super(MainWindow, self).__init__()
self.setWindowTitle(__appname__) self.setWindowTitle(__appname__)
# Load setting in the main thread # Load setting in the main thread
self.settings = Settings() self.settings = Settings()
self.settings.load() self.settings.load()
settings = self.settings settings = self.settings
self.lang = lang self.lang = lang
# Load string bundle for i18n # Load string bundle for i18n
if lang not in ['ch', 'en']: if lang not in ['ch', 'en']:
lang = 'en' lang = 'en'
self.stringBundle = StringBundle.getBundle(localeStr='zh-CN' self.stringBundle = StringBundle.getBundle(localeStr='zh-CN' if lang=='ch' else 'en') # 'en'
if lang == 'ch' else
'en') # 'en'
getStr = lambda strId: self.stringBundle.getString(strId) getStr = lambda strId: self.stringBundle.getString(strId)
self.defaultSaveDir = defaultSaveDir self.defaultSaveDir = defaultSaveDir
self.ocr = PaddleOCR( self.ocr = PaddleOCR(use_pdserving=False, use_angle_cls=True, det=True, cls=True, use_gpu=False, lang=lang)
use_pdserving=False,
use_angle_cls=True,
det=True,
cls=True,
use_gpu=False,
lang=lang)
if os.path.exists('./data/paddle.png'): if os.path.exists('./data/paddle.png'):
result = self.ocr.ocr('./data/paddle.png', cls=True, det=True) result = self.ocr.ocr('./data/paddle.png', cls=True, det=True)
...@@ -135,6 +125,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -135,6 +125,7 @@ class MainWindow(QMainWindow, WindowMixin):
self.labelFile = None self.labelFile = None
self.currIndex = 0 self.currIndex = 0
# Whether we need to save or not. # Whether we need to save or not.
self.dirty = False self.dirty = False
...@@ -166,7 +157,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -166,7 +157,7 @@ class MainWindow(QMainWindow, WindowMixin):
filelistLayout = QVBoxLayout() filelistLayout = QVBoxLayout()
filelistLayout.setContentsMargins(0, 0, 0, 0) filelistLayout.setContentsMargins(0, 0, 0, 0)
filelistLayout.addWidget(self.fileListWidget) filelistLayout.addWidget(self.fileListWidget)
self.AutoRecognition = QToolButton() self.AutoRecognition = QToolButton()
self.AutoRecognition.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.AutoRecognition.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
self.AutoRecognition.setIcon(newIcon('Auto')) self.AutoRecognition.setIcon(newIcon('Auto'))
...@@ -186,7 +177,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -186,7 +177,7 @@ class MainWindow(QMainWindow, WindowMixin):
self.filedock.setObjectName(getStr('files')) self.filedock.setObjectName(getStr('files'))
self.filedock.setWidget(fileListContainer) self.filedock.setWidget(fileListContainer)
self.addDockWidget(Qt.LeftDockWidgetArea, self.filedock) self.addDockWidget(Qt.LeftDockWidgetArea, self.filedock)
######## Right area ########## ######## Right area ##########
listLayout = QVBoxLayout() listLayout = QVBoxLayout()
listLayout.setContentsMargins(0, 0, 0, 0) listLayout.setContentsMargins(0, 0, 0, 0)
...@@ -211,6 +202,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -211,6 +202,7 @@ class MainWindow(QMainWindow, WindowMixin):
self.DelButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.DelButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
# self.DelButton.setFixedSize(QSize(80, 30)) # self.DelButton.setFixedSize(QSize(80, 30))
lefttoptoolbox = QHBoxLayout() lefttoptoolbox = QHBoxLayout()
lefttoptoolbox.addWidget(self.newButton) lefttoptoolbox.addWidget(self.newButton)
lefttoptoolbox.addWidget(self.reRecogButton) lefttoptoolbox.addWidget(self.reRecogButton)
...@@ -218,6 +210,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -218,6 +210,7 @@ class MainWindow(QMainWindow, WindowMixin):
lefttoptoolboxcontainer.setLayout(lefttoptoolbox) lefttoptoolboxcontainer.setLayout(lefttoptoolbox)
listLayout.addWidget(lefttoptoolboxcontainer) listLayout.addWidget(lefttoptoolboxcontainer)
################## label list #################### ################## label list ####################
# Create and add a widget for showing current label items # Create and add a widget for showing current label items
self.labelList = QListWidget() self.labelList = QListWidget()
...@@ -228,7 +221,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -228,7 +221,7 @@ class MainWindow(QMainWindow, WindowMixin):
self.labelList.itemDoubleClicked.connect(self.editLabel) self.labelList.itemDoubleClicked.connect(self.editLabel)
# Connect to itemChanged to detect checkbox changes. # Connect to itemChanged to detect checkbox changes.
self.labelList.itemChanged.connect(self.labelItemChanged) self.labelList.itemChanged.connect(self.labelItemChanged)
self.labelListDock = QDockWidget(getStr('recognitionResult'), self) self.labelListDock = QDockWidget(getStr('recognitionResult'),self)
self.labelListDock.setWidget(self.labelList) self.labelListDock.setWidget(self.labelList)
self.labelListDock.setFeatures(QDockWidget.NoDockWidgetFeatures) self.labelListDock.setFeatures(QDockWidget.NoDockWidgetFeatures)
listLayout.addWidget(self.labelListDock) listLayout.addWidget(self.labelListDock)
...@@ -258,6 +251,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -258,6 +251,7 @@ class MainWindow(QMainWindow, WindowMixin):
self.dock.setObjectName(getStr('labels')) self.dock.setObjectName(getStr('labels'))
self.dock.setWidget(labelListContainer) self.dock.setWidget(labelListContainer)
########## zoom bar ######### ########## zoom bar #########
self.imgsplider = QSlider(Qt.Horizontal) self.imgsplider = QSlider(Qt.Horizontal)
self.imgsplider.valueChanged.connect(self.CanvasSizeChange) self.imgsplider.valueChanged.connect(self.CanvasSizeChange)
...@@ -265,7 +259,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -265,7 +259,7 @@ class MainWindow(QMainWindow, WindowMixin):
self.imgsplider.setMaximum(150) self.imgsplider.setMaximum(150)
self.imgsplider.setSingleStep(1) self.imgsplider.setSingleStep(1)
self.imgsplider.setTickPosition(QSlider.TicksBelow) self.imgsplider.setTickPosition(QSlider.TicksBelow)
self.imgsplider.setTickInterval(1) self.imgsplider.setTickInterval(1)
op = QGraphicsOpacityEffect() op = QGraphicsOpacityEffect()
op.setOpacity(0.2) op.setOpacity(0.2)
self.imgsplider.setGraphicsEffect(op) self.imgsplider.setGraphicsEffect(op)
...@@ -284,7 +278,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -284,7 +278,7 @@ class MainWindow(QMainWindow, WindowMixin):
self.zoomWidget = ZoomWidget() self.zoomWidget = ZoomWidget()
self.colorDialog = ColorDialog(parent=self) self.colorDialog = ColorDialog(parent=self)
self.zoomWidgetValue = self.zoomWidget.value() self.zoomWidgetValue = self.zoomWidget.value()
########## thumbnail ######### ########## thumbnail #########
hlayout = QHBoxLayout() hlayout = QHBoxLayout()
m = (0, 0, 0, 0) m = (0, 0, 0, 0)
...@@ -293,7 +287,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -293,7 +287,7 @@ class MainWindow(QMainWindow, WindowMixin):
self.preButton = QToolButton() self.preButton = QToolButton()
# self.preButton.setFixedHeight(100) # self.preButton.setFixedHeight(100)
# self.preButton.setText(getStr("prevImg")) # self.preButton.setText(getStr("prevImg"))
self.preButton.setIcon(newIcon("prev", 40)) self.preButton.setIcon(newIcon("prev",40))
self.preButton.setIconSize(QSize(40, 100)) self.preButton.setIconSize(QSize(40, 100))
self.preButton.clicked.connect(self.openPrevImg) self.preButton.clicked.connect(self.openPrevImg)
# self.preButton.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) # self.preButton.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
...@@ -307,8 +301,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -307,8 +301,7 @@ class MainWindow(QMainWindow, WindowMixin):
self.iconlist.setResizeMode(QListView.Adjust) self.iconlist.setResizeMode(QListView.Adjust)
# self.iconlist.itemDoubleClicked.connect(self.iconitemDoubleClicked) # self.iconlist.itemDoubleClicked.connect(self.iconitemDoubleClicked)
self.iconlist.itemClicked.connect(self.iconitemDoubleClicked) self.iconlist.itemClicked.connect(self.iconitemDoubleClicked)
self.iconlist.setStyleSheet( self.iconlist.setStyleSheet("background-color:transparent; border: none;")
"background-color:transparent; border: none;")
self.iconlist.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.iconlist.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
# self.iconlist.setStyleSheet('border: none;') # self.iconlist.setStyleSheet('border: none;')
self.nextButton = QToolButton() self.nextButton = QToolButton()
...@@ -319,7 +312,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -319,7 +312,7 @@ class MainWindow(QMainWindow, WindowMixin):
self.nextButton.setStyleSheet('border: none;') self.nextButton.setStyleSheet('border: none;')
self.nextButton.clicked.connect(self.openNextImg) self.nextButton.clicked.connect(self.openNextImg)
# self.nextButton.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) # self.nextButton.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
hlayout.addWidget(self.preButton) hlayout.addWidget(self.preButton)
hlayout.addWidget(self.iconlist) hlayout.addWidget(self.iconlist)
hlayout.addWidget(self.nextButton) hlayout.addWidget(self.nextButton)
...@@ -333,12 +326,11 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -333,12 +326,11 @@ class MainWindow(QMainWindow, WindowMixin):
# op = QGraphicsOpacityEffect() # op = QGraphicsOpacityEffect()
# op.setOpacity(0.5) # op.setOpacity(0.5)
# iconListContainer.setGraphicsEffect(op) # iconListContainer.setGraphicsEffect(op)
########### Canvas ########### ########### Canvas ###########
self.canvas = Canvas(parent=self) self.canvas = Canvas(parent=self)
self.canvas.zoomRequest.connect(self.zoomRequest) self.canvas.zoomRequest.connect(self.zoomRequest)
self.canvas.setDrawingShapeToSquare( self.canvas.setDrawingShapeToSquare(settings.get(SETTING_DRAW_SQUARE, False))
settings.get(SETTING_DRAW_SQUARE, False))
scroll = QScrollArea() scroll = QScrollArea()
scroll.setWidget(self.canvas) scroll.setWidget(self.canvas)
...@@ -359,7 +351,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -359,7 +351,7 @@ class MainWindow(QMainWindow, WindowMixin):
centerLayout.setContentsMargins(0, 0, 0, 0) centerLayout.setContentsMargins(0, 0, 0, 0)
centerLayout.addWidget(scroll) centerLayout.addWidget(scroll)
#centerLayout.addWidget(self.icondock) #centerLayout.addWidget(self.icondock)
centerLayout.addWidget(iconListContainer, 0, Qt.AlignCenter) centerLayout.addWidget(iconListContainer,0,Qt.AlignCenter)
centercontainer = QWidget() centercontainer = QWidget()
centercontainer.setLayout(centerLayout) centercontainer.setLayout(centerLayout)
...@@ -371,12 +363,12 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -371,12 +363,12 @@ class MainWindow(QMainWindow, WindowMixin):
# tmpwidget = QWidget() # tmpwidget = QWidget()
# self.scrolldock.setTitleBarWidget(tmpwidget) # self.scrolldock.setTitleBarWidget(tmpwidget)
# del orititle # del orititle
self.setCentralWidget(centercontainer) #self.scrolldock self.setCentralWidget(centercontainer) #self.scrolldock
self.addDockWidget(Qt.RightDockWidgetArea, self.dock) self.addDockWidget(Qt.RightDockWidgetArea, self.dock)
# self.filedock.setFeatures(QDockWidget.DockWidgetFloatable) # self.filedock.setFeatures(QDockWidget.DockWidgetFloatable)
self.filedock.setFeatures(self.filedock.features() ^ self.filedock.setFeatures(self.filedock.features() ^ QDockWidget.DockWidgetFloatable)
QDockWidget.DockWidgetFloatable)
self.dockFeatures = QDockWidget.DockWidgetClosable | QDockWidget.DockWidgetFloatable self.dockFeatures = QDockWidget.DockWidgetClosable | QDockWidget.DockWidgetFloatable
self.dock.setFeatures(self.dock.features() ^ self.dockFeatures) self.dock.setFeatures(self.dock.features() ^ self.dockFeatures)
...@@ -385,118 +377,62 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -385,118 +377,62 @@ class MainWindow(QMainWindow, WindowMixin):
###### Actions ####### ###### Actions #######
action = partial(newAction, self) action = partial(newAction, self)
quit = action( quit = action(getStr('quit'), self.close,
getStr('quit'), self.close, 'Ctrl+Q', 'quit', getStr('quitApp')) 'Ctrl+Q', 'quit', getStr('quitApp'))
open = action( open = action(getStr('openFile'), self.openFile,
getStr('openFile'), self.openFile, 'Ctrl+O', 'open', 'Ctrl+O', 'open', getStr('openFileDetail'))
getStr('openFileDetail'))
opendir = action(getStr('openDir'), self.openDirDialog,
opendir = action( 'Ctrl+u', 'open', getStr('openDir'))
getStr('openDir'), self.openDirDialog, 'Ctrl+u', 'open',
getStr('openDir')) openNextImg = action(getStr('nextImg'), self.openNextImg,
'd', 'next', getStr('nextImgDetail'))
openNextImg = action(
getStr('nextImg'), self.openNextImg, 'd', 'next', openPrevImg = action(getStr('prevImg'), self.openPrevImg,
getStr('nextImgDetail')) 'a', 'prev', getStr('prevImgDetail'))
openPrevImg = action( verify = action(getStr('verifyImg'), self.verifyImg,
getStr('prevImg'), self.openPrevImg, 'a', 'prev', 'space', 'verify', getStr('verifyImgDetail'))
getStr('prevImgDetail'))
save = action(getStr('save'), self.saveFile,
verify = action( 'Ctrl+S', 'save', getStr('saveDetail'), enabled=False)
getStr('verifyImg'), self.verifyImg, 'space', 'verify',
getStr('verifyImgDetail')) alcm = action(getStr('choosemodel'), self.autolcm,
'Ctrl+M', 'next', getStr('tipchoosemodel'))
save = action(
getStr('save'), deleteImg = action(getStr('deleteImg'), self.deleteImg, 'Ctrl+D', 'close', getStr('deleteImgDetail'),
self.saveFile, enabled=True)
'Ctrl+S',
'save', resetAll = action(getStr('resetAll'), self.resetAll, None, 'resetall', getStr('resetAllDetail'))
getStr('saveDetail'),
enabled=False) color1 = action(getStr('boxLineColor'), self.chooseColor1,
'Ctrl+L', 'color_line', getStr('boxLineColorDetail'))
alcm = action(
getStr('choosemodel'), self.autolcm, 'Ctrl+M', 'next', createMode = action(getStr('crtBox'), self.setCreateMode,
getStr('tipchoosemodel')) 'w', 'new', getStr('crtBoxDetail'), enabled=False)
editMode = action('&Edit\nRectBox', self.setEditMode,
deleteImg = action( 'Ctrl+J', 'edit', u'Move and edit Boxs', enabled=False)
getStr('deleteImg'),
self.deleteImg, create = action(getStr('crtBox'), self.createShape,
'Ctrl+D', 'w', 'new', getStr('crtBoxDetail'), enabled=False)
'close',
getStr('deleteImgDetail'), delete = action(getStr('delBox'), self.deleteSelectedShape,
enabled=True) 'Delete', 'delete', getStr('delBoxDetail'), enabled=False)
copy = action(getStr('dupBox'), self.copySelectedShape,
resetAll = action( 'Ctrl+D', 'copy', getStr('dupBoxDetail'),
getStr('resetAll'), self.resetAll, None, 'resetall', enabled=False)
getStr('resetAllDetail'))
hideAll = action(getStr('hideBox'), partial(self.togglePolygons, False),
color1 = action( 'Ctrl+H', 'hide', getStr('hideAllBoxDetail'),
getStr('boxLineColor'), self.chooseColor1, 'Ctrl+L', 'color_line', enabled=False)
getStr('boxLineColorDetail')) showAll = action(getStr('showBox'), partial(self.togglePolygons, True),
'Ctrl+A', 'hide', getStr('showAllBoxDetail'),
createMode = action( enabled=False)
getStr('crtBox'),
self.setCreateMode, help = action(getStr('tutorial'), self.showTutorialDialog, None, 'help', getStr('tutorialDetail'))
'w', showInfo = action(getStr('info'), self.showInfoDialog, None, 'help', getStr('info'))
'new', showSteps = action(getStr('steps'), self.showStepsDialog, None, 'help', getStr('steps'))
getStr('crtBoxDetail'),
enabled=False)
editMode = action(
'&Edit\nRectBox',
self.setEditMode,
'Ctrl+J',
'edit',
u'Move and edit Boxs',
enabled=False)
create = action(
getStr('crtBox'),
self.createShape,
'w',
'new',
getStr('crtBoxDetail'),
enabled=False)
delete = action(
getStr('delBox'),
self.deleteSelectedShape,
'Delete',
'delete',
getStr('delBoxDetail'),
enabled=False)
copy = action(
getStr('dupBox'),
self.copySelectedShape,
'Ctrl+D',
'copy',
getStr('dupBoxDetail'),
enabled=False)
hideAll = action(
getStr('hideBox'),
partial(self.togglePolygons, False),
'Ctrl+H',
'hide',
getStr('hideAllBoxDetail'),
enabled=False)
showAll = action(
getStr('showBox'),
partial(self.togglePolygons, True),
'Ctrl+A',
'hide',
getStr('showAllBoxDetail'),
enabled=False)
help = action(
getStr('tutorial'), self.showTutorialDialog, None, 'help',
getStr('tutorialDetail'))
showInfo = action(
getStr('info'), self.showInfoDialog, None, 'help', getStr('info'))
showSteps = action(
getStr('steps'), self.showStepsDialog, None, 'help',
getStr('steps'))
zoom = QWidgetAction(self) zoom = QWidgetAction(self)
zoom.setDefaultWidget(self.zoomWidget) zoom.setDefaultWidget(self.zoomWidget)
...@@ -506,46 +442,21 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -506,46 +442,21 @@ class MainWindow(QMainWindow, WindowMixin):
fmtShortcut("Ctrl+Wheel"))) fmtShortcut("Ctrl+Wheel")))
self.zoomWidget.setEnabled(False) self.zoomWidget.setEnabled(False)
zoomIn = action( zoomIn = action(getStr('zoomin'), partial(self.addZoom, 10),
getStr('zoomin'), 'Ctrl++', 'zoom-in', getStr('zoominDetail'), enabled=False)
partial(self.addZoom, 10), zoomOut = action(getStr('zoomout'), partial(self.addZoom, -10),
'Ctrl++', 'Ctrl+-', 'zoom-out', getStr('zoomoutDetail'), enabled=False)
'zoom-in', zoomOrg = action(getStr('originalsize'), partial(self.setZoom, 100),
getStr('zoominDetail'), 'Ctrl+=', 'zoom', getStr('originalsizeDetail'), enabled=False)
enabled=False) fitWindow = action(getStr('fitWin'), self.setFitWindow,
zoomOut = action( 'Ctrl+F', 'fit-window', getStr('fitWinDetail'),
getStr('zoomout'), checkable=True, enabled=False)
partial(self.addZoom, -10), fitWidth = action(getStr('fitWidth'), self.setFitWidth,
'Ctrl+-', 'Ctrl+Shift+F', 'fit-width', getStr('fitWidthDetail'),
'zoom-out', checkable=True, enabled=False)
getStr('zoomoutDetail'),
enabled=False)
zoomOrg = action(
getStr('originalsize'),
partial(self.setZoom, 100),
'Ctrl+=',
'zoom',
getStr('originalsizeDetail'),
enabled=False)
fitWindow = action(
getStr('fitWin'),
self.setFitWindow,
'Ctrl+F',
'fit-window',
getStr('fitWinDetail'),
checkable=True,
enabled=False)
fitWidth = action(
getStr('fitWidth'),
self.setFitWidth,
'Ctrl+Shift+F',
'fit-width',
getStr('fitWidthDetail'),
checkable=True,
enabled=False)
# Group zoom controls into a list for easier toggling. # Group zoom controls into a list for easier toggling.
zoomActions = (self.zoomWidget, zoomIn, zoomOut, zoomOrg, fitWindow, zoomActions = (self.zoomWidget, zoomIn, zoomOut,
fitWidth) zoomOrg, fitWindow, fitWidth)
self.zoomMode = self.MANUAL_ZOOM self.zoomMode = self.MANUAL_ZOOM
self.scalers = { self.scalers = {
self.FIT_WINDOW: self.scaleFitWindow, self.FIT_WINDOW: self.scaleFitWindow,
...@@ -554,46 +465,22 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -554,46 +465,22 @@ class MainWindow(QMainWindow, WindowMixin):
self.MANUAL_ZOOM: lambda: 1, self.MANUAL_ZOOM: lambda: 1,
} }
edit = action( edit = action(getStr('editLabel'), self.editLabel,
getStr('editLabel'), 'Ctrl+E', 'edit', getStr('editLabelDetail'),
self.editLabel, enabled=False)
'Ctrl+E',
'edit',
getStr('editLabelDetail'),
enabled=False)
######## New actions ####### ######## New actions #######
AutoRec = action( AutoRec = action(getStr('autoRecognition'), self.autoRecognition,
getStr('autoRecognition'), 'Ctrl+Shift+A', 'Auto', getStr('autoRecognition'), enabled=False)
self.autoRecognition,
'Ctrl+Shift+A', reRec = action(getStr('reRecognition'), self.reRecognition,
'Auto', 'Ctrl+Shift+R', 'reRec', getStr('reRecognition'), enabled=False)
getStr('autoRecognition'),
enabled=False) createpoly = action(getStr('creatPolygon'), self.createPolygon,
'p', 'new', 'Creat Polygon', enabled=True)
reRec = action(
getStr('reRecognition'), saveRec = action(getStr('saveRec'), self.saveRecResult,
self.reRecognition, '', 'saveRec', getStr('saveRec'), enabled=False)
'Ctrl+Shift+R',
'reRec',
getStr('reRecognition'),
enabled=False)
createpoly = action(
getStr('creatPolygon'),
self.createPolygon,
'p',
'new',
'Creat Polygon',
enabled=True)
saveRec = action(
getStr('saveRec'),
self.saveRecResult,
'',
'saveRec',
getStr('saveRec'),
enabled=False)
self.editButton.setDefaultAction(edit) self.editButton.setDefaultAction(edit)
self.newButton.setDefaultAction(create) self.newButton.setDefaultAction(create)
...@@ -624,18 +511,12 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -624,18 +511,12 @@ class MainWindow(QMainWindow, WindowMixin):
zoomContainer.setLayout(zoomLayout) zoomContainer.setLayout(zoomLayout)
zoomContainer.setGeometry(0, 0, 30, 150) zoomContainer.setGeometry(0, 0, 30, 150)
shapeLineColor = action( shapeLineColor = action(getStr('shapeLineColor'), self.chshapeLineColor,
getStr('shapeLineColor'), icon='color_line', tip=getStr('shapeLineColorDetail'),
self.chshapeLineColor, enabled=False)
icon='color_line', shapeFillColor = action(getStr('shapeFillColor'), self.chshapeFillColor,
tip=getStr('shapeLineColorDetail'), icon='color', tip=getStr('shapeFillColorDetail'),
enabled=False) enabled=False)
shapeFillColor = action(
getStr('shapeFillColor'),
self.chshapeFillColor,
icon='color',
tip=getStr('shapeFillColorDetail'),
enabled=False)
# labels = self.dock.toggleViewAction() # labels = self.dock.toggleViewAction()
# labels.setText(getStr('showHide')) # labels.setText(getStr('showHide'))
...@@ -646,112 +527,92 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -646,112 +527,92 @@ class MainWindow(QMainWindow, WindowMixin):
addActions(labelMenu, (edit, delete)) addActions(labelMenu, (edit, delete))
self.labelList.setContextMenuPolicy(Qt.CustomContextMenu) self.labelList.setContextMenuPolicy(Qt.CustomContextMenu)
self.labelList.customContextMenuRequested.connect(self.popLabelListMenu) self.labelList.customContextMenuRequested.connect(
self.popLabelListMenu)
# Draw squares/rectangles # Draw squares/rectangles
self.drawSquaresOption = QAction(getStr('drawSquares'), self) self.drawSquaresOption = QAction(getStr('drawSquares'), self)
self.drawSquaresOption.setShortcut('Ctrl+Shift+R') self.drawSquaresOption.setShortcut('Ctrl+Shift+R')
self.drawSquaresOption.setCheckable(True) self.drawSquaresOption.setCheckable(True)
self.drawSquaresOption.setChecked( self.drawSquaresOption.setChecked(settings.get(SETTING_DRAW_SQUARE, False))
settings.get(SETTING_DRAW_SQUARE, False))
self.drawSquaresOption.triggered.connect(self.toogleDrawSquare) self.drawSquaresOption.triggered.connect(self.toogleDrawSquare)
# Store actions for further handling. # Store actions for further handling.
self.actions = struct( self.actions = struct(save=save, open=open, resetAll=resetAll, deleteImg=deleteImg,
save=save, lineColor=color1, create=create, delete=delete, edit=edit, copy=copy,
open=open, saveRec=saveRec,
resetAll=resetAll, createMode=createMode, editMode=editMode,
deleteImg=deleteImg, shapeLineColor=shapeLineColor, shapeFillColor=shapeFillColor,
lineColor=color1, zoom=zoom, zoomIn=zoomIn, zoomOut=zoomOut, zoomOrg=zoomOrg,
create=create, fitWindow=fitWindow, fitWidth=fitWidth,
delete=delete, zoomActions=zoomActions,
edit=edit, fileMenuActions=(
copy=copy, open, opendir, save, resetAll, quit),
saveRec=saveRec, beginner=(), advanced=(),
createMode=createMode, editMenu=(createpoly, edit, copy, delete,
editMode=editMode, None, color1, self.drawSquaresOption),
shapeLineColor=shapeLineColor, beginnerContext=(create, edit, copy, delete),
shapeFillColor=shapeFillColor, advancedContext=(createMode, editMode, edit, copy,
zoom=zoom, delete, shapeLineColor, shapeFillColor),
zoomIn=zoomIn, onLoadActive=(
zoomOut=zoomOut, create, createMode, editMode),
zoomOrg=zoomOrg, onShapesPresent=(hideAll, showAll))
fitWindow=fitWindow,
fitWidth=fitWidth,
zoomActions=zoomActions,
fileMenuActions=(open, opendir, save, resetAll, quit),
beginner=(),
advanced=(),
editMenu=(createpoly, edit, copy, delete, None, color1,
self.drawSquaresOption),
beginnerContext=(create, edit, copy, delete),
advancedContext=(createMode, editMode, edit, copy, delete,
shapeLineColor, shapeFillColor),
onLoadActive=(create, createMode, editMode),
onShapesPresent=(hideAll, showAll))
# menus # menus
self.menus = struct( self.menus = struct(
file=self.menu('&' + getStr('mfile')), file=self.menu('&'+getStr('mfile')),
edit=self.menu('&' + getStr('medit')), edit=self.menu('&'+getStr('medit')),
view=self.menu('&' + getStr('mview')), view=self.menu('&'+getStr('mview')),
autolabel=self.menu('&PaddleOCR'), autolabel=self.menu('&PaddleOCR'),
help=self.menu('&' + getStr('mhelp')), help=self.menu('&'+getStr('mhelp')),
recentFiles=QMenu('Open &Recent'), recentFiles=QMenu('Open &Recent'),
labelList=labelMenu) labelList=labelMenu)
# Sync single class mode from PR#106 # Sync single class mode from PR#106
self.singleClassMode = QAction(getStr('singleClsMode'), self) self.singleClassMode = QAction(getStr('singleClsMode'), self)
self.singleClassMode.setShortcut("Ctrl+Shift+S") self.singleClassMode.setShortcut("Ctrl+Shift+S")
self.singleClassMode.setCheckable(True) self.singleClassMode.setCheckable(True)
self.singleClassMode.setChecked( self.singleClassMode.setChecked(settings.get(SETTING_SINGLE_CLASS, False))
settings.get(SETTING_SINGLE_CLASS, False))
self.lastLabel = None self.lastLabel = None
# Add option to enable/disable labels being displayed at the top of bounding boxes # Add option to enable/disable labels being displayed at the top of bounding boxes
self.displayLabelOption = QAction(getStr('displayLabel'), self) self.displayLabelOption = QAction(getStr('displayLabel'), self)
self.displayLabelOption.setShortcut("Ctrl+Shift+P") self.displayLabelOption.setShortcut("Ctrl+Shift+P")
self.displayLabelOption.setCheckable(True) self.displayLabelOption.setCheckable(True)
self.displayLabelOption.setChecked( self.displayLabelOption.setChecked(settings.get(SETTING_PAINT_LABEL, False))
settings.get(SETTING_PAINT_LABEL, False))
self.displayLabelOption.triggered.connect(self.togglePaintLabelsOption) self.displayLabelOption.triggered.connect(self.togglePaintLabelsOption)
addActions(self.menus.file, addActions(self.menus.file,
(opendir, None, save, resetAll, deleteImg, quit)) (opendir, None, save, resetAll, deleteImg, quit))
addActions(self.menus.help, (showSteps, showInfo)) addActions(self.menus.help, (showSteps, showInfo))
addActions( addActions(self.menus.view, (
self.menus.view, self.displayLabelOption, # labels,
( None,
self.displayLabelOption, # labels, hideAll, showAll, None,
None, zoomIn, zoomOut, zoomOrg, None,
hideAll, fitWindow, fitWidth))
showAll,
None, addActions(self.menus.autolabel, (alcm, saveRec, None, help)) #
zoomIn,
zoomOut,
zoomOrg,
None,
fitWindow,
fitWidth))
addActions(self.menus.autolabel, (alcm, saveRec, None, help)) #
self.menus.file.aboutToShow.connect(self.updateFileMenu) self.menus.file.aboutToShow.connect(self.updateFileMenu)
# Custom context menu for the canvas widget: # Custom context menu for the canvas widget:
addActions(self.canvas.menus[0], self.actions.beginnerContext) addActions(self.canvas.menus[0], self.actions.beginnerContext)
addActions(self.canvas.menus[1], (action('&Copy here', self.copyShape), addActions(self.canvas.menus[1], (
action('&Move here', self.moveShape))) action('&Copy here', self.copyShape),
action('&Move here', self.moveShape)))
# self.tools = self.toolbar('Tools') # self.tools = self.toolbar('Tools')
self.actions.beginner = (open, opendir, openNextImg, openPrevImg, self.actions.beginner = (
verify, save, None, create, copy, delete, None, open, opendir, openNextImg, openPrevImg, verify, save, None, create, copy, delete, None,
zoomIn, zoom, zoomOut, fitWindow, fitWidth) zoomIn, zoom, zoomOut, fitWindow, fitWidth)
self.actions.advanced = (open, opendir, openNextImg, openPrevImg, save, self.actions.advanced = (
None, createMode, editMode, None, hideAll, open, opendir, openNextImg, openPrevImg, save, None,
showAll) createMode, editMode, None,
hideAll, showAll)
self.statusBar().showMessage('%s started.' % __appname__) self.statusBar().showMessage('%s started.' % __appname__)
self.statusBar().show() self.statusBar().show()
...@@ -775,8 +636,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -775,8 +636,7 @@ class MainWindow(QMainWindow, WindowMixin):
recentFileQStringList = settings.get(SETTING_RECENT_FILES) recentFileQStringList = settings.get(SETTING_RECENT_FILES)
self.recentFiles = [ustr(i) for i in recentFileQStringList] self.recentFiles = [ustr(i) for i in recentFileQStringList]
else: else:
self.recentFiles = recentFileQStringList = settings.get( self.recentFiles = recentFileQStringList = settings.get(SETTING_RECENT_FILES)
SETTING_RECENT_FILES)
size = settings.get(SETTING_WIN_SIZE, QSize(1200, 800)) size = settings.get(SETTING_WIN_SIZE, QSize(1200, 800))
...@@ -784,8 +644,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -784,8 +644,7 @@ class MainWindow(QMainWindow, WindowMixin):
saved_position = settings.get(SETTING_WIN_POSE, position) saved_position = settings.get(SETTING_WIN_POSE, position)
# Fix the multiple monitors issue # Fix the multiple monitors issue
for i in range(QApplication.desktop().screenCount()): for i in range(QApplication.desktop().screenCount()):
if QApplication.desktop().availableGeometry(i).contains( if QApplication.desktop().availableGeometry(i).contains(saved_position):
saved_position):
position = saved_position position = saved_position
break break
self.resize(size) self.resize(size)
...@@ -794,14 +653,13 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -794,14 +653,13 @@ class MainWindow(QMainWindow, WindowMixin):
self.lastOpenDir = ustr(settings.get(SETTING_LAST_OPEN_DIR, None)) self.lastOpenDir = ustr(settings.get(SETTING_LAST_OPEN_DIR, None))
self.restoreState(settings.get(SETTING_WIN_STATE, QByteArray())) self.restoreState(settings.get(SETTING_WIN_STATE, QByteArray()))
Shape.line_color = self.lineColor = QColor( Shape.line_color = self.lineColor = QColor(settings.get(SETTING_LINE_COLOR, DEFAULT_LINE_COLOR))
settings.get(SETTING_LINE_COLOR, DEFAULT_LINE_COLOR)) Shape.fill_color = self.fillColor = QColor(settings.get(SETTING_FILL_COLOR, DEFAULT_FILL_COLOR))
Shape.fill_color = self.fillColor = QColor(
settings.get(SETTING_FILL_COLOR, DEFAULT_FILL_COLOR))
self.canvas.setDrawingColor(self.lineColor) self.canvas.setDrawingColor(self.lineColor)
# Add chris # Add chris
Shape.difficult = self.difficult Shape.difficult = self.difficult
# ADD: # ADD:
# Populate the File menu dynamically. # Populate the File menu dynamically.
self.updateFileMenu() self.updateFileMenu()
...@@ -834,18 +692,19 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -834,18 +692,19 @@ class MainWindow(QMainWindow, WindowMixin):
# Draw rectangle if Ctrl is pressed # Draw rectangle if Ctrl is pressed
self.canvas.setDrawingShapeToSquare(True) self.canvas.setDrawingShapeToSquare(True)
def noShapes(self): def noShapes(self):
return not self.itemsToShapes return not self.itemsToShapes
def populateModeActions(self): def populateModeActions(self):
self.canvas.menus[0].clear() self.canvas.menus[0].clear()
addActions(self.canvas.menus[0], self.actions.beginnerContext) addActions(self.canvas.menus[0], self.actions.beginnerContext)
self.menus.edit.clear() self.menus.edit.clear()
actions = ( actions = (self.actions.create,) # if self.beginner() else (self.actions.createMode, self.actions.editMode)
self.actions.create,
) # if self.beginner() else (self.actions.createMode, self.actions.editMode)
addActions(self.menus.edit, actions + self.actions.editMenu) addActions(self.menus.edit, actions + self.actions.editMenu)
def setDirty(self): def setDirty(self):
self.dirty = True self.dirty = True
self.actions.save.setEnabled(True) self.actions.save.setEnabled(True)
...@@ -924,8 +783,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -924,8 +783,7 @@ class MainWindow(QMainWindow, WindowMixin):
def showInfoDialog(self): def showInfoDialog(self):
from libs.__init__ import __version__ from libs.__init__ import __version__
msg = u'Name:{0} \nApp Version:{1} \n{2} '.format( msg = u'Name:{0} \nApp Version:{1} \n{2} '.format(__appname__, __version__, sys.version_info)
__appname__, __version__, sys.version_info)
QMessageBox.information(self, u'Information', msg) QMessageBox.information(self, u'Information', msg)
def showStepsDialog(self): def showStepsDialog(self):
...@@ -976,11 +834,12 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -976,11 +834,12 @@ class MainWindow(QMainWindow, WindowMixin):
menu = self.menus.recentFiles menu = self.menus.recentFiles
menu.clear() menu.clear()
files = [f for f in self.recentFiles if f != currFilePath and exists(f)] files = [f for f in self.recentFiles if f !=
currFilePath and exists(f)]
for i, f in enumerate(files): for i, f in enumerate(files):
icon = newIcon('labels') icon = newIcon('labels')
action = QAction(icon, '&%d %s' % (i + 1, QFileInfo(f).fileName()), action = QAction(
self) icon, '&%d %s' % (i + 1, QFileInfo(f).fileName()), self)
action.triggered.connect(partial(self.loadRecent, f)) action.triggered.connect(partial(self.loadRecent, f))
menu.addAction(action) menu.addAction(action)
...@@ -1031,21 +890,16 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1031,21 +890,16 @@ class MainWindow(QMainWindow, WindowMixin):
try: try:
text_list = eval(text) text_list = eval(text)
except: except:
msg_box = QMessageBox(QMessageBox.Warning, 'Warning', msg_box = QMessageBox(QMessageBox.Warning, 'Warning', 'Please enter the correct format')
'Please enter the correct format')
msg_box.exec_() msg_box.exec_()
return return
if len(text_list) < 4: if len(text_list) < 4:
msg_box = QMessageBox( msg_box = QMessageBox(QMessageBox.Warning, 'Warning', 'Please enter the coordinates of 4 points')
QMessageBox.Warning, 'Warning',
'Please enter the coordinates of 4 points')
msg_box.exec_() msg_box.exec_()
return return
for box in text_list: for box in text_list:
if box[0] > width or box[0] < 0 or box[1] > height or box[ if box[0] > width or box[0] < 0 or box[1] > height or box[1] < 0:
1] < 0: msg_box = QMessageBox(QMessageBox.Warning, 'Warning', 'Out of picture size')
msg_box = QMessageBox(QMessageBox.Warning, 'Warning',
'Out of picture size')
msg_box.exec_() msg_box.exec_()
return return
...@@ -1064,15 +918,15 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1064,15 +918,15 @@ class MainWindow(QMainWindow, WindowMixin):
def indexTo5Files(self, currIndex): def indexTo5Files(self, currIndex):
if currIndex < 2: if currIndex < 2:
return self.mImgList[:5] return self.mImgList[:5]
elif currIndex > len(self.mImgList) - 3: elif currIndex > len(self.mImgList)-3:
return self.mImgList[-5:] return self.mImgList[-5:]
else: else:
return self.mImgList[currIndex - 2:currIndex + 3] return self.mImgList[currIndex - 2 : currIndex + 3]
# Tzutalin 20160906 : Add file list and dock to move faster # Tzutalin 20160906 : Add file list and dock to move faster
def fileitemDoubleClicked(self, item=None): def fileitemDoubleClicked(self, item=None):
self.currIndex = self.mImgList.index( self.currIndex = self.mImgList.index(ustr(os.path.join(os.path.abspath(self.dirname), item.text())))
ustr(os.path.join(os.path.abspath(self.dirname), item.text())))
filename = self.mImgList[self.currIndex] filename = self.mImgList[self.currIndex]
if filename: if filename:
self.mImgList5 = self.indexTo5Files(self.currIndex) self.mImgList5 = self.indexTo5Files(self.currIndex)
...@@ -1089,8 +943,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1089,8 +943,7 @@ class MainWindow(QMainWindow, WindowMixin):
def CanvasSizeChange(self): def CanvasSizeChange(self):
if len(self.mImgList) > 0: if len(self.mImgList) > 0:
self.zoomWidget.setValue(self.zoomWidgetValue + self.zoomWidget.setValue(self.zoomWidgetValue + self.imgsplider.value())
self.imgsplider.value())
# Add chris # Add chris
def btnstate(self, item=None): def btnstate(self, item=None):
...@@ -1115,8 +968,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1115,8 +968,7 @@ class MainWindow(QMainWindow, WindowMixin):
shape.difficult = difficult shape.difficult = difficult
self.setDirty() self.setDirty()
else: # User probably changed item visibility else: # User probably changed item visibility
self.canvas.setShapeVisible(shape, self.canvas.setShapeVisible(shape, item.checkState() == Qt.Checked)
item.checkState() == Qt.Checked)
except: except:
pass pass
...@@ -1149,8 +1001,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1149,8 +1001,7 @@ class MainWindow(QMainWindow, WindowMixin):
# print('item in add label is ',[(p.x(), p.y()) for p in shape.points], shape.label) # print('item in add label is ',[(p.x(), p.y()) for p in shape.points], shape.label)
# ADD for box # ADD for box
item = HashableQListWidgetItem( item = HashableQListWidgetItem(str([(int(p.x()), int(p.y())) for p in shape.points]))
str([(int(p.x()), int(p.y())) for p in shape.points]))
# item = QListWidgetItem(str([(p.x(), p.y()) for p in shape.points])) # item = QListWidgetItem(str([(p.x(), p.y()) for p in shape.points]))
item.setFlags(item.flags() | Qt.ItemIsUserCheckable) item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
item.setCheckState(Qt.Checked) item.setCheckState(Qt.Checked)
...@@ -1211,10 +1062,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1211,10 +1062,7 @@ class MainWindow(QMainWindow, WindowMixin):
def updateComboBox(self): def updateComboBox(self):
# Get the unique labels and add them to the Combobox. # Get the unique labels and add them to the Combobox.
itemsTextList = [ itemsTextList = [str(self.labelList.item(i).text()) for i in range(self.labelList.count())]
str(self.labelList.item(i).text())
for i in range(self.labelList.count())
]
uniqueTextList = list(set(itemsTextList)) uniqueTextList = list(set(itemsTextList))
# Add a null row for showing all the labels # Add a null row for showing all the labels
...@@ -1231,13 +1079,12 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1231,13 +1079,12 @@ class MainWindow(QMainWindow, WindowMixin):
def format_shape(s): def format_shape(s):
# print('s in saveLabels is ',s) # print('s in saveLabels is ',s)
return dict( return dict(label=s.label, # str
label=s.label, # str line_color=s.line_color.getRgb(),
line_color=s.line_color.getRgb(), fill_color=s.fill_color.getRgb(),
fill_color=s.fill_color.getRgb(), points=[(p.x(), p.y()) for p in s.points], # QPonitF
points=[(p.x(), p.y()) for p in s.points], # QPonitF # add chris
# add chris difficult=s.difficult) # bool
difficult=s.difficult) # bool
shapes = [] if mode == 'Auto' else \ shapes = [] if mode == 'Auto' else \
[format_shape(shape) for shape in self.canvas.shapes] [format_shape(shape) for shape in self.canvas.shapes]
...@@ -1245,11 +1092,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1245,11 +1092,7 @@ class MainWindow(QMainWindow, WindowMixin):
if self.model == 'paddle': if self.model == 'paddle':
for box in self.result_dic: for box in self.result_dic:
trans_dic = { trans_dic = {"label": box[1][0], "points": box[0], 'difficult': False}
"label": box[1][0],
"points": box[0],
'difficult': False
}
if trans_dic["label"] is "" and mode == 'Auto': if trans_dic["label"] is "" and mode == 'Auto':
continue continue
shapes.append(trans_dic) shapes.append(trans_dic)
...@@ -1257,11 +1100,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1257,11 +1100,7 @@ class MainWindow(QMainWindow, WindowMixin):
try: try:
trans_dic = [] trans_dic = []
for box in shapes: for box in shapes:
trans_dic.append({ trans_dic.append({"transcription": box['label'], "points": box['points'], 'difficult': False})
"transcription": box['label'],
"points": box['points'],
'difficult': False
})
self.PPlabel[annotationFilePath] = trans_dic self.PPlabel[annotationFilePath] = trans_dic
if mode == 'Auto': if mode == 'Auto':
...@@ -1281,6 +1120,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1281,6 +1120,7 @@ class MainWindow(QMainWindow, WindowMixin):
# fix copy and delete # fix copy and delete
self.shapeSelectionChanged(True) self.shapeSelectionChanged(True)
def labelSelectionChanged(self): def labelSelectionChanged(self):
item = self.currentItem() item = self.currentItem()
if item and self.canvas.editing(): if item and self.canvas.editing():
...@@ -1316,7 +1156,8 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1316,7 +1156,8 @@ class MainWindow(QMainWindow, WindowMixin):
position MUST be in global coordinates. position MUST be in global coordinates.
""" """
if len(self.labelHist) > 0: if len(self.labelHist) > 0:
self.labelDialog = LabelDialog(parent=self, listItem=self.labelHist) self.labelDialog = LabelDialog(
parent=self, listItem=self.labelHist)
# Sync single class mode from PR#106 # Sync single class mode from PR#106
if self.singleClassMode.isChecked() and self.lastLabel: if self.singleClassMode.isChecked() and self.lastLabel:
...@@ -1330,8 +1171,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1330,8 +1171,7 @@ class MainWindow(QMainWindow, WindowMixin):
if text is not None: if text is not None:
self.prevLabelText = self.stringBundle.getString('tempLabel') self.prevLabelText = self.stringBundle.getString('tempLabel')
# generate_color = generateColorByText(text) # generate_color = generateColorByText(text)
shape = self.canvas.setLastLabel( shape = self.canvas.setLastLabel(text, None, None)#generate_color, generate_color
text, None, None) #generate_color, generate_color
self.addLabel(shape) self.addLabel(shape)
if self.beginner(): # Switch to edit mode. if self.beginner(): # Switch to edit mode.
self.canvas.setEditing(True) self.canvas.setEditing(True)
...@@ -1345,7 +1185,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1345,7 +1185,7 @@ class MainWindow(QMainWindow, WindowMixin):
self.canvas.resetAllLines() self.canvas.resetAllLines()
def scrollRequest(self, delta, orientation): def scrollRequest(self, delta, orientation):
units = -delta / (8 * 15) units = - delta / (8 * 15)
bar = self.scrollBars[orientation] bar = self.scrollBars[orientation]
bar.setValue(bar.value() + bar.singleStep() * units) bar.setValue(bar.value() + bar.singleStep() * units)
...@@ -1456,7 +1296,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1456,7 +1296,7 @@ class MainWindow(QMainWindow, WindowMixin):
titem = self.iconlist.item(i) titem = self.iconlist.item(i)
titem.setSelected(True) titem.setSelected(True)
self.iconlist.scrollToItem(titem) self.iconlist.scrollToItem(titem)
break break
else: else:
self.fileListWidget.clear() self.fileListWidget.clear()
self.mImgList.clear() self.mImgList.clear()
...@@ -1464,16 +1304,16 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1464,16 +1304,16 @@ class MainWindow(QMainWindow, WindowMixin):
# if unicodeFilePath and self.iconList.count() > 0: # if unicodeFilePath and self.iconList.count() > 0:
# if unicodeFilePath in self.mImgList: # if unicodeFilePath in self.mImgList:
if unicodeFilePath and os.path.exists(unicodeFilePath): if unicodeFilePath and os.path.exists(unicodeFilePath):
if LabelFile.isLabelFile(unicodeFilePath): if LabelFile.isLabelFile(unicodeFilePath):
try: try:
self.labelFile = LabelFile(unicodeFilePath) self.labelFile = LabelFile(unicodeFilePath)
except LabelFileError as e: except LabelFileError as e:
self.errorMessage(u'Error opening file', ( self.errorMessage(u'Error opening file',
u"<p><b>%s</b></p>" (u"<p><b>%s</b></p>"
u"<p>Make sure <i>%s</i> is a valid label file.") % u"<p>Make sure <i>%s</i> is a valid label file.")
(e, unicodeFilePath)) % (e, unicodeFilePath))
self.status("Error reading %s" % unicodeFilePath) self.status("Error reading %s" % unicodeFilePath)
return False return False
self.imageData = self.labelFile.imageData self.imageData = self.labelFile.imageData
...@@ -1489,10 +1329,8 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1489,10 +1329,8 @@ class MainWindow(QMainWindow, WindowMixin):
image = QImage.fromData(self.imageData) image = QImage.fromData(self.imageData)
if image.isNull(): if image.isNull():
self.errorMessage( self.errorMessage(u'Error opening file',
u'Error opening file', u"<p>Make sure <i>%s</i> is a valid image file." % unicodeFilePath)
u"<p>Make sure <i>%s</i> is a valid image file." %
unicodeFilePath)
self.status("Error reading %s" % unicodeFilePath) self.status("Error reading %s" % unicodeFilePath)
return False return False
self.status("Loaded %s" % os.path.basename(unicodeFilePath)) self.status("Loaded %s" % os.path.basename(unicodeFilePath))
...@@ -1513,33 +1351,32 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1513,33 +1351,32 @@ class MainWindow(QMainWindow, WindowMixin):
self.addRecentFile(self.filePath) self.addRecentFile(self.filePath)
self.toggleActions(True) self.toggleActions(True)
self.showBoundingBoxFromPPlabel(filePath) self.showBoundingBoxFromPPlabel(filePath)
self.setWindowTitle(__appname__ + ' ' + filePath) self.setWindowTitle(__appname__ + ' ' + filePath)
# Default : select last item if there is at least one item # Default : select last item if there is at least one item
if self.labelList.count(): if self.labelList.count():
self.labelList.setCurrentItem( self.labelList.setCurrentItem(self.labelList.item(self.labelList.count() - 1))
self.labelList.item(self.labelList.count() - 1)) self.labelList.item(self.labelList.count() - 1).setSelected(True)
self.labelList.item(self.labelList.count() - 1).setSelected(
True)
self.canvas.setFocus(True) self.canvas.setFocus(True)
return True return True
return False return False
def showBoundingBoxFromPPlabel(self, filePath): def showBoundingBoxFromPPlabel(self, filePath):
imgidx = self.getImglabelidx(filePath) imgidx = self.getImglabelidx(filePath)
if imgidx not in self.PPlabel.keys(): if imgidx not in self.PPlabel.keys():
return return
shapes = [] shapes = []
for box in self.PPlabel[imgidx]: for box in self.PPlabel[imgidx]:
shapes.append((box['transcription'], box['points'], None, None, shapes.append((box['transcription'], box['points'], None, None, box['difficult']))
box['difficult']))
print(shapes) print(shapes)
self.loadLabels(shapes) self.loadLabels(shapes)
self.canvas.verified = False self.canvas.verified = False
def validFilestate(self, filePath): def validFilestate(self, filePath):
if filePath not in self.fileStatedict.keys(): if filePath not in self.fileStatedict.keys():
return None return None
...@@ -1568,7 +1405,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1568,7 +1405,7 @@ class MainWindow(QMainWindow, WindowMixin):
"""Figure out the size of the pixmap in order to fit the main widget.""" """Figure out the size of the pixmap in order to fit the main widget."""
e = 2.0 # So that no scrollbars are generated. e = 2.0 # So that no scrollbars are generated.
w1 = self.centralWidget().width() - e w1 = self.centralWidget().width() - e
h1 = self.centralWidget().height() - e - 110 h1 = self.centralWidget().height() - e -110
a1 = w1 / h1 a1 = w1 / h1
# Calculate a new scale value based on the pixmap's aspect ratio. # Calculate a new scale value based on the pixmap's aspect ratio.
w2 = self.canvas.pixmap.width() - 0.0 w2 = self.canvas.pixmap.width() - 0.0
...@@ -1588,8 +1425,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1588,8 +1425,7 @@ class MainWindow(QMainWindow, WindowMixin):
settings = self.settings settings = self.settings
# If it loads images from dir, don't load it at the begining # If it loads images from dir, don't load it at the begining
if self.dirname is None: if self.dirname is None:
settings[ settings[SETTING_FILENAME] = self.filePath if self.filePath else ''
SETTING_FILENAME] = self.filePath if self.filePath else ''
else: else:
settings[SETTING_FILENAME] = '' settings[SETTING_FILENAME] = ''
...@@ -1625,10 +1461,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1625,10 +1461,7 @@ class MainWindow(QMainWindow, WindowMixin):
self.loadFile(filename) self.loadFile(filename)
def scanAllImages(self, folderPath): def scanAllImages(self, folderPath):
extensions = [ extensions = ['.%s' % fmt.data().decode("ascii").lower() for fmt in QImageReader.supportedImageFormats()]
'.%s' % fmt.data().decode("ascii").lower()
for fmt in QImageReader.supportedImageFormats()
]
images = [] images = []
for file in os.listdir(folderPath): for file in os.listdir(folderPath):
...@@ -1639,6 +1472,8 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1639,6 +1472,8 @@ class MainWindow(QMainWindow, WindowMixin):
natural_sort(images, key=lambda x: x.lower()) natural_sort(images, key=lambda x: x.lower())
return images return images
def openDirDialog(self, _value=False, dirpath=None, silent=False): def openDirDialog(self, _value=False, dirpath=None, silent=False):
if not self.mayContinue(): if not self.mayContinue():
return return
...@@ -1647,20 +1482,18 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1647,20 +1482,18 @@ class MainWindow(QMainWindow, WindowMixin):
if self.lastOpenDir and os.path.exists(self.lastOpenDir): if self.lastOpenDir and os.path.exists(self.lastOpenDir):
defaultOpenDirPath = self.lastOpenDir defaultOpenDirPath = self.lastOpenDir
else: else:
defaultOpenDirPath = os.path.dirname( defaultOpenDirPath = os.path.dirname(self.filePath) if self.filePath else '.'
self.filePath) if self.filePath else '.'
if silent != True: if silent != True:
targetDirPath = ustr( targetDirPath = ustr(QFileDialog.getExistingDirectory(self,
QFileDialog.getExistingDirectory( '%s - Open Directory' % __appname__,
self, '%s - Open Directory' % __appname__, defaultOpenDirPath,
defaultOpenDirPath, QFileDialog.ShowDirsOnly | QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks))
QFileDialog.DontResolveSymlinks))
else: else:
targetDirPath = ustr(defaultOpenDirPath) targetDirPath = ustr(defaultOpenDirPath)
self.lastOpenDir = targetDirPath self.lastOpenDir = targetDirPath
self.importDirImages(targetDirPath) self.importDirImages(targetDirPath)
def importDirImages(self, dirpath, isDelete=False): def importDirImages(self, dirpath, isDelete = False):
if not self.mayContinue() or not dirpath: if not self.mayContinue() or not dirpath:
return return
if self.defaultSaveDir and self.defaultSaveDir != dirpath: if self.defaultSaveDir and self.defaultSaveDir != dirpath:
...@@ -1669,7 +1502,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1669,7 +1502,7 @@ class MainWindow(QMainWindow, WindowMixin):
if not isDelete: if not isDelete:
self.loadFilestate(dirpath) self.loadFilestate(dirpath)
self.PPlabelpath = dirpath + '/Label.txt' self.PPlabelpath = dirpath+ '/Label.txt'
self.PPlabel = self.loadLabelFile(self.PPlabelpath) self.PPlabel = self.loadLabelFile(self.PPlabelpath)
self.Cachelabelpath = dirpath + '/Cache.cach' self.Cachelabelpath = dirpath + '/Cache.cach'
self.Cachelabel = self.loadLabelFile(self.Cachelabelpath) self.Cachelabel = self.loadLabelFile(self.Cachelabelpath)
...@@ -1678,10 +1511,10 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1678,10 +1511,10 @@ class MainWindow(QMainWindow, WindowMixin):
self.lastOpenDir = dirpath self.lastOpenDir = dirpath
self.dirname = dirpath self.dirname = dirpath
self.defaultSaveDir = dirpath self.defaultSaveDir = dirpath
self.statusBar().showMessage( self.statusBar().showMessage('%s started. Annotation will be saved to %s' %
'%s started. Annotation will be saved to %s' % (__appname__, self.defaultSaveDir))
(__appname__, self.defaultSaveDir))
self.statusBar().show() self.statusBar().show()
self.filePath = None self.filePath = None
...@@ -1731,7 +1564,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1731,7 +1564,7 @@ class MainWindow(QMainWindow, WindowMixin):
if self.filePath is None: if self.filePath is None:
return return
currIndex = self.mImgList.index(self.filePath) currIndex = self.mImgList.index(self.filePath)
self.mImgList5 = self.mImgList[:5] self.mImgList5 = self.mImgList[:5]
if currIndex - 1 >= 0: if currIndex - 1 >= 0:
...@@ -1759,22 +1592,16 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1759,22 +1592,16 @@ class MainWindow(QMainWindow, WindowMixin):
else: else:
self.mImgList5 = self.indexTo5Files(currIndex) self.mImgList5 = self.indexTo5Files(currIndex)
if filename: if filename:
print('file name in openNext is ', filename) print('file name in openNext is ',filename)
self.loadFile(filename) self.loadFile(filename)
def openFile(self, _value=False): def openFile(self, _value=False):
if not self.mayContinue(): if not self.mayContinue():
return return
path = os.path.dirname(ustr(self.filePath)) if self.filePath else '.' path = os.path.dirname(ustr(self.filePath)) if self.filePath else '.'
formats = [ formats = ['*.%s' % fmt.data().decode("ascii").lower() for fmt in QImageReader.supportedImageFormats()]
'*.%s' % fmt.data().decode("ascii").lower() filters = "Image & Label files (%s)" % ' '.join(formats + ['*%s' % LabelFile.suffix])
for fmt in QImageReader.supportedImageFormats() filename = QFileDialog.getOpenFileName(self, '%s - Choose Image or Label file' % __appname__, path, filters)
]
filters = "Image & Label files (%s)" % ' '.join(
formats + ['*%s' % LabelFile.suffix])
filename = QFileDialog.getOpenFileName(
self, '%s - Choose Image or Label file' % __appname__, path,
filters)
if filename: if filename:
if isinstance(filename, (tuple, list)): if isinstance(filename, (tuple, list)):
filename = filename[0] filename = filename[0]
...@@ -1796,7 +1623,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1796,7 +1623,7 @@ class MainWindow(QMainWindow, WindowMixin):
self.fileListWidget.addItem(filename) self.fileListWidget.addItem(filename)
self.additems5(None) self.additems5(None)
print('opened image is', filename) print('opened image is', filename)
def updateFileListIcon(self, filename): def updateFileListIcon(self, filename):
pass pass
...@@ -1811,10 +1638,8 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1811,10 +1638,8 @@ class MainWindow(QMainWindow, WindowMixin):
imgFileName = os.path.basename(self.filePath) imgFileName = os.path.basename(self.filePath)
savedFileName = os.path.splitext(imgFileName)[0] savedFileName = os.path.splitext(imgFileName)[0]
savedPath = os.path.join(imgFileDir, savedFileName) savedPath = os.path.join(imgFileDir, savedFileName)
self._saveFile( self._saveFile(savedPath if self.labelFile
savedPath else self.saveFileDialog(removeExt=False), mode=mode)
if self.labelFile else self.saveFileDialog(removeExt=False),
mode=mode)
def saveFileAs(self, _value=False): def saveFileAs(self, _value=False):
assert not self.image.isNull(), "cannot save empty image" assert not self.image.isNull(), "cannot save empty image"
...@@ -1833,26 +1658,23 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1833,26 +1658,23 @@ class MainWindow(QMainWindow, WindowMixin):
if dlg.exec_(): if dlg.exec_():
fullFilePath = ustr(dlg.selectedFiles()[0]) fullFilePath = ustr(dlg.selectedFiles()[0])
if removeExt: if removeExt:
return os.path.splitext(fullFilePath)[ return os.path.splitext(fullFilePath)[0] # Return file path without the extension.
0] # Return file path without the extension.
else: else:
return fullFilePath return fullFilePath
return '' return ''
def _saveFile(self, annotationFilePath, mode='Manual'): def _saveFile(self, annotationFilePath, mode='Manual'):
if mode == 'Manual': if mode == 'Manual':
if annotationFilePath and self.saveLabels( if annotationFilePath and self.saveLabels(annotationFilePath, mode=mode):
annotationFilePath, mode=mode):
self.setClean() self.setClean()
self.statusBar().showMessage('Saved to %s' % self.statusBar().showMessage('Saved to %s' % annotationFilePath)
annotationFilePath)
self.statusBar().show() self.statusBar().show()
currIndex = self.mImgList.index(self.filePath) currIndex = self.mImgList.index(self.filePath)
item = self.fileListWidget.item(currIndex) item = self.fileListWidget.item(currIndex)
item.setIcon(newIcon('done')) item.setIcon(newIcon('done'))
self.fileStatedict[self.filePath] = 1 self.fileStatedict[self.filePath] = 1
if len(self.fileStatedict) % self.autoSaveNum == 0: if len(self.fileStatedict)%self.autoSaveNum ==0:
self.saveFilestate() self.saveFilestate()
self.savePPlabel(mode='Auto') self.savePPlabel(mode='Auto')
...@@ -1861,12 +1683,10 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1861,12 +1683,10 @@ class MainWindow(QMainWindow, WindowMixin):
self.actions.saveRec.setEnabled(True) self.actions.saveRec.setEnabled(True)
elif mode == 'Auto': elif mode == 'Auto':
if annotationFilePath and self.saveLabels( if annotationFilePath and self.saveLabels(annotationFilePath, mode=mode):
annotationFilePath, mode=mode):
self.setClean() self.setClean()
self.statusBar().showMessage('Saved to %s' % self.statusBar().showMessage('Saved to %s' % annotationFilePath)
annotationFilePath)
self.statusBar().show() self.statusBar().show()
def closeFile(self, _value=False): def closeFile(self, _value=False):
...@@ -1885,10 +1705,9 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1885,10 +1705,9 @@ class MainWindow(QMainWindow, WindowMixin):
if deleteInfo == QMessageBox.Yes: if deleteInfo == QMessageBox.Yes:
if platform.system() == 'Windows': if platform.system() == 'Windows':
from win32com.shell import shell, shellcon from win32com.shell import shell, shellcon
shell.SHFileOperation( shell.SHFileOperation((0, shellcon.FO_DELETE, deletePath, None,
(0, shellcon.FO_DELETE, deletePath, None, shellcon.FOF_SILENT | shellcon.FOF_ALLOWUNDO | shellcon.FOF_NOCONFIRMATION,
shellcon.FOF_SILENT | shellcon.FOF_ALLOWUNDO | None, None))
shellcon.FOF_NOCONFIRMATION, None, None))
# linux # linux
elif platform.system() == 'Linux': elif platform.system() == 'Linux':
cmd = 'trash ' + deletePath cmd = 'trash ' + deletePath
...@@ -1896,13 +1715,9 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1896,13 +1715,9 @@ class MainWindow(QMainWindow, WindowMixin):
# macOS # macOS
elif platform.system() == 'Darwin': elif platform.system() == 'Darwin':
import subprocess import subprocess
absPath = os.path.abspath(deletePath).replace( absPath = os.path.abspath(deletePath).replace('\\', '\\\\').replace('"', '\\"')
'\\', '\\\\').replace('"', '\\"') cmd = ['osascript', '-e',
cmd = [ 'tell app "Finder" to move {the POSIX file "' + absPath + '"} to trash']
'osascript', '-e',
'tell app "Finder" to move {the POSIX file "' + absPath
+ '"} to trash'
]
print(cmd) print(cmd)
subprocess.call(cmd, stdout=open(os.devnull, 'w')) subprocess.call(cmd, stdout=open(os.devnull, 'w'))
...@@ -1926,7 +1741,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1926,7 +1741,7 @@ class MainWindow(QMainWindow, WindowMixin):
proc.startDetached(os.path.abspath(__file__)) proc.startDetached(os.path.abspath(__file__))
def mayContinue(self): # def mayContinue(self): #
if not self.dirty: if not self.dirty:
return True return True
else: else:
discardChanges = self.discardChangesDialog() discardChanges = self.discardChangesDialog()
...@@ -1951,8 +1766,8 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1951,8 +1766,8 @@ class MainWindow(QMainWindow, WindowMixin):
return os.path.dirname(self.filePath) if self.filePath else '.' return os.path.dirname(self.filePath) if self.filePath else '.'
def chooseColor1(self): def chooseColor1(self):
color = self.colorDialog.getColor( color = self.colorDialog.getColor(self.lineColor, u'Choose line color',
self.lineColor, u'Choose line color', default=DEFAULT_LINE_COLOR) default=DEFAULT_LINE_COLOR)
if color: if color:
self.lineColor = color self.lineColor = color
Shape.line_color = color Shape.line_color = color
...@@ -1968,16 +1783,16 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -1968,16 +1783,16 @@ class MainWindow(QMainWindow, WindowMixin):
action.setEnabled(False) action.setEnabled(False)
def chshapeLineColor(self): def chshapeLineColor(self):
color = self.colorDialog.getColor( color = self.colorDialog.getColor(self.lineColor, u'Choose line color',
self.lineColor, u'Choose line color', default=DEFAULT_LINE_COLOR) default=DEFAULT_LINE_COLOR)
if color: if color:
self.canvas.selectedShape.line_color = color self.canvas.selectedShape.line_color = color
self.canvas.update() self.canvas.update()
self.setDirty() self.setDirty()
def chshapeFillColor(self): def chshapeFillColor(self):
color = self.colorDialog.getColor( color = self.colorDialog.getColor(self.fillColor, u'Choose fill color',
self.fillColor, u'Choose fill color', default=DEFAULT_FILL_COLOR) default=DEFAULT_FILL_COLOR)
if color: if color:
self.canvas.selectedShape.fill_color = color self.canvas.selectedShape.fill_color = color
self.canvas.update() self.canvas.update()
...@@ -2002,6 +1817,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -2002,6 +1817,7 @@ class MainWindow(QMainWindow, WindowMixin):
else: else:
self.labelHist.append(line) self.labelHist.append(line)
def togglePaintLabelsOption(self): def togglePaintLabelsOption(self):
for shape in self.canvas.shapes: for shape in self.canvas.shapes:
shape.paintLabel = self.displayLabelOption.isChecked() shape.paintLabel = self.displayLabelOption.isChecked()
...@@ -2014,10 +1830,8 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -2014,10 +1830,8 @@ class MainWindow(QMainWindow, WindowMixin):
pix = QPixmap(file) pix = QPixmap(file)
_, filename = os.path.split(file) _, filename = os.path.split(file)
filename, _ = os.path.splitext(filename) filename, _ = os.path.splitext(filename)
item = QListWidgetItem( item = QListWidgetItem(QIcon(pix.scaled(100, 100, Qt.IgnoreAspectRatio, Qt.FastTransformation)),
QIcon( filename[:10])
pix.scaled(100, 100, Qt.IgnoreAspectRatio,
Qt.FastTransformation)), filename[:10])
item.setToolTip(file) item.setToolTip(file)
self.iconlist.addItem(item) self.iconlist.addItem(item)
...@@ -2032,10 +1846,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -2032,10 +1846,7 @@ class MainWindow(QMainWindow, WindowMixin):
prelen = lentoken // 2 prelen = lentoken // 2
bfilename = prelen * " " + pfilename + (lentoken - prelen) * " " bfilename = prelen * " " + pfilename + (lentoken - prelen) * " "
# item = QListWidgetItem(QIcon(pix.scaled(100, 100, Qt.KeepAspectRatio, Qt.SmoothTransformation)),filename[:10]) # item = QListWidgetItem(QIcon(pix.scaled(100, 100, Qt.KeepAspectRatio, Qt.SmoothTransformation)),filename[:10])
item = QListWidgetItem( item = QListWidgetItem(QIcon(pix.scaled(100, 100, Qt.IgnoreAspectRatio, Qt.FastTransformation)),pfilename)
QIcon(
pix.scaled(100, 100, Qt.IgnoreAspectRatio,
Qt.FastTransformation)), pfilename)
# item.setForeground(QBrush(Qt.white)) # item.setForeground(QBrush(Qt.white))
item.setToolTip(file) item.setToolTip(file)
self.iconlist.addItem(item) self.iconlist.addItem(item)
...@@ -2047,7 +1858,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -2047,7 +1858,7 @@ class MainWindow(QMainWindow, WindowMixin):
self.iconlist.setMinimumWidth(owidth + 50) self.iconlist.setMinimumWidth(owidth + 50)
def getImglabelidx(self, filePath): def getImglabelidx(self, filePath):
if platform.system() == 'Windows': if platform.system()=='Windows':
spliter = '\\' spliter = '\\'
else: else:
spliter = '/' spliter = '/'
...@@ -2058,22 +1869,17 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -2058,22 +1869,17 @@ class MainWindow(QMainWindow, WindowMixin):
assert self.mImgList is not None assert self.mImgList is not None
print('Using model from ', self.model) print('Using model from ', self.model)
uncheckedList = [ uncheckedList = [i for i in self.mImgList if i not in self.fileStatedict.keys()]
i for i in self.mImgList if i not in self.fileStatedict.keys() self.autoDialog = AutoDialog(parent=self, ocr=self.ocr, mImgList=uncheckedList, lenbar=len(uncheckedList))
]
self.autoDialog = AutoDialog(
parent=self,
ocr=self.ocr,
mImgList=uncheckedList,
lenbar=len(uncheckedList))
self.autoDialog.popUp() self.autoDialog.popUp()
self.currIndex = len(self.mImgList) self.currIndex=len(self.mImgList)
self.loadFile(self.filePath) # ADD self.loadFile(self.filePath) # ADD
self.haveAutoReced = True self.haveAutoReced = True
self.AutoRecognition.setEnabled(False) self.AutoRecognition.setEnabled(False)
self.setDirty() self.setDirty()
self.saveCacheLabel() self.saveCacheLabel()
def reRecognition(self): def reRecognition(self):
img = cv2.imread(self.filePath) img = cv2.imread(self.filePath)
# org_box = [dic['points'] for dic in self.PPlabel[self.getImglabelidx(self.filePath)]] # org_box = [dic['points'] for dic in self.PPlabel[self.getImglabelidx(self.filePath)]]
...@@ -2102,16 +1908,14 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -2102,16 +1908,14 @@ class MainWindow(QMainWindow, WindowMixin):
self.saveFile(mode='Auto') self.saveFile(mode='Auto')
self.loadFile(self.filePath) self.loadFile(self.filePath)
self.setDirty() self.setDirty()
elif len(self.result_dic) == len( elif len(self.result_dic) == len(self.canvas.shapes) and rec_flag == 0:
self.canvas.shapes) and rec_flag == 0: QMessageBox.information(self, "Information", "The recognition result remains unchanged!")
QMessageBox.information(
self, "Information",
"The recognition result remains unchanged!")
else: else:
print('Can not recgonise in ', self.filePath) print('Can not recgonise in ', self.filePath)
else: else:
QMessageBox.information(self, "Information", "Draw a box!") QMessageBox.information(self, "Information", "Draw a box!")
def autolcm(self): def autolcm(self):
vbox = QVBoxLayout() vbox = QVBoxLayout()
hbox = QHBoxLayout() hbox = QHBoxLayout()
...@@ -2120,10 +1924,7 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -2120,10 +1924,7 @@ class MainWindow(QMainWindow, WindowMixin):
self.panel.setAlignment(Qt.AlignLeft) self.panel.setAlignment(Qt.AlignLeft)
self.comboBox = QComboBox() self.comboBox = QComboBox()
self.comboBox.setObjectName("comboBox") self.comboBox.setObjectName("comboBox")
self.comboBox.addItems([ self.comboBox.addItems(['Chinese & English', 'English', 'French', 'German', 'Korean', 'Japanese'])
'Chinese & English', 'English', 'French', 'German', 'Korean',
'Japanese'
])
# self.comboBox_lg = QComboBox() # self.comboBox_lg = QComboBox()
# self.comboBox_lg.setObjectName("comboBox_language") # self.comboBox_lg.setObjectName("comboBox_language")
vbox.addWidget(self.panel) vbox.addWidget(self.panel)
...@@ -2148,24 +1949,14 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -2148,24 +1949,14 @@ class MainWindow(QMainWindow, WindowMixin):
if self.filePath: if self.filePath:
self.AutoRecognition.setEnabled(True) self.AutoRecognition.setEnabled(True)
def modelChoose(self): def modelChoose(self):
print(self.comboBox.currentText()) print(self.comboBox.currentText())
lg_idx = { lg_idx = {'Chinese & English': 'ch', 'English': 'en', 'French': 'french', 'German': 'german',
'Chinese & English': 'ch', 'Korean': 'korean', 'Japanese': 'japan'}
'English': 'en',
'French': 'french',
'German': 'german',
'Korean': 'korean',
'Japanese': 'japan'
}
del self.ocr del self.ocr
self.ocr = PaddleOCR( self.ocr = PaddleOCR(use_pdserving=False, use_angle_cls=True, det=True, cls=True, use_gpu=False,
use_pdserving=False, lang=lg_idx[self.comboBox.currentText()])
use_angle_cls=True,
det=True,
cls=True,
use_gpu=False,
lang=lg_idx[self.comboBox.currentText()])
self.dialog.close() self.dialog.close()
def cancel(self): def cancel(self):
...@@ -2183,12 +1974,14 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -2183,12 +1974,14 @@ class MainWindow(QMainWindow, WindowMixin):
file, state = each.split('\t') file, state = each.split('\t')
self.fileStatedict[file] = 1 self.fileStatedict[file] = 1
def saveFilestate(self): def saveFilestate(self):
with open(self.fileStatepath, 'w', encoding='utf-8') as f: with open(self.fileStatepath, 'w', encoding='utf-8') as f:
for key in self.fileStatedict: for key in self.fileStatedict:
f.write(key + '\t') f.write(key + '\t')
f.write(str(self.fileStatedict[key]) + '\n') f.write(str(self.fileStatedict[key]) + '\n')
def loadLabelFile(self, labelpath): def loadLabelFile(self, labelpath):
labeldict = {} labeldict = {}
if not os.path.exists(labelpath): if not os.path.exists(labelpath):
...@@ -2206,27 +1999,24 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -2206,27 +1999,24 @@ class MainWindow(QMainWindow, WindowMixin):
labeldict[file] = [] labeldict[file] = []
return labeldict return labeldict
def savePPlabel(self, mode='Manual'):
def savePPlabel(self,mode='Manual'):
savedfile = [self.getImglabelidx(i) for i in self.fileStatedict.keys()] savedfile = [self.getImglabelidx(i) for i in self.fileStatedict.keys()]
with open(self.PPlabelpath, 'w', encoding='utf-8') as f: with open(self.PPlabelpath, 'w', encoding='utf-8') as f:
for key in self.PPlabel: for key in self.PPlabel:
if key in savedfile: if key in savedfile:
f.write(key + '\t') f.write(key + '\t')
f.write( f.write(json.dumps(self.PPlabel[key], ensure_ascii=False) + '\n')
json.dumps(
self.PPlabel[key], ensure_ascii=False) + '\n')
if mode == 'Manual': if mode=='Manual':
msg = 'Images that have been checked are saved in ' + self.PPlabelpath msg = 'Images that have been checked are saved in '+ self.PPlabelpath
QMessageBox.information(self, "Information", msg) QMessageBox.information(self, "Information", msg)
def saveCacheLabel(self): def saveCacheLabel(self):
with open(self.Cachelabelpath, 'w', encoding='utf-8') as f: with open(self.Cachelabelpath, 'w', encoding='utf-8') as f:
for key in self.Cachelabel: for key in self.Cachelabel:
f.write(key + '\t') f.write(key + '\t')
f.write( f.write(json.dumps(self.Cachelabel[key], ensure_ascii=False) + '\n')
json.dumps(
self.Cachelabel[key], ensure_ascii=False) + '\n')
def saveRecResult(self): def saveRecResult(self):
if None in [self.PPlabelpath, self.PPlabel, self.fileStatedict]: if None in [self.PPlabelpath, self.PPlabel, self.fileStatedict]:
...@@ -2243,21 +2033,16 @@ class MainWindow(QMainWindow, WindowMixin): ...@@ -2243,21 +2033,16 @@ class MainWindow(QMainWindow, WindowMixin):
idx = self.getImglabelidx(key) idx = self.getImglabelidx(key)
for i, label in enumerate(self.PPlabel[idx]): for i, label in enumerate(self.PPlabel[idx]):
img = cv2.imread(key) img = cv2.imread(key)
img_crop = get_rotate_crop_image( img_crop = get_rotate_crop_image(img, np.array(label['points'], np.float32))
img, np.array(label['points'], np.float32)) img_name = os.path.splitext(os.path.basename(idx))[0] + '_crop_'+str(i)+'.jpg'
img_name = os.path.splitext(os.path.basename(idx))[ cv2.imwrite(crop_img_dir+img_name, img_crop)
0] + '_crop_' + str(i) + '.jpg' f.write('crop_img/'+ img_name + '\t')
cv2.imwrite(crop_img_dir + img_name, img_crop)
f.write('crop_img/' + img_name + '\t')
f.write(label['transcription'] + '\n') f.write(label['transcription'] + '\n')
QMessageBox.information( QMessageBox.information(self, "Information", "Cropped images has been saved in "+str(crop_img_dir))
self, "Information",
"Cropped images has been saved in " + str(crop_img_dir))
def inverted(color): def inverted(color):
return QColor(* [255 - v for v in color.getRgb()]) return QColor(*[255 - v for v in color.getRgb()])
def read(filename, default=None): def read(filename, default=None):
...@@ -2279,16 +2064,14 @@ def get_main_app(argv=[]): ...@@ -2279,16 +2064,14 @@ def get_main_app(argv=[]):
# Tzutalin 201705+: Accept extra agruments to change predefined class file # Tzutalin 201705+: Accept extra agruments to change predefined class file
argparser = argparse.ArgumentParser() argparser = argparse.ArgumentParser()
argparser.add_argument("--lang", default='ch', nargs="?") argparser.add_argument("--lang", default='ch', nargs="?")
argparser.add_argument( argparser.add_argument("--predefined_classes_file",
"--predefined_classes_file", default=os.path.join(os.path.dirname(__file__), "data", "predefined_classes.txt"),
default=os.path.join( nargs="?")
os.path.dirname(__file__), "data", "predefined_classes.txt"),
nargs="?")
args = argparser.parse_args(argv[1:]) args = argparser.parse_args(argv[1:])
# Usage : labelImg.py image predefClassFile saveDir # Usage : labelImg.py image predefClassFile saveDir
win = MainWindow( win = MainWindow(lang=args.lang,
lang=args.lang, defaultPrefdefClassFile=args.predefined_classes_file,
defaultPrefdefClassFile=args.predefined_classes_file, ) )
win.show() win.show()
return app, win return app, win
...@@ -2300,7 +2083,7 @@ def main(): ...@@ -2300,7 +2083,7 @@ def main():
if __name__ == '__main__': if __name__ == '__main__':
resource_file = './libs/resources.py' resource_file = './libs/resources.py'
if not os.path.exists(resource_file): if not os.path.exists(resource_file):
output = os.system('pyrcc5 -o libs/resources.py resources.qrc') output = os.system('pyrcc5 -o libs/resources.py resources.qrc')
......
...@@ -29,7 +29,7 @@ except ImportError: ...@@ -29,7 +29,7 @@ except ImportError:
def newIcon(icon, iconSize=None): def newIcon(icon, iconSize=None):
if iconSize is not None: if iconSize is not None:
return QIcon(QIcon(':/' + icon).pixmap(iconSize, iconSize)) return QIcon(QIcon(':/' + icon).pixmap(iconSize,iconSize))
else: else:
return QIcon(':/' + icon) return QIcon(':/' + icon)
...@@ -43,15 +43,8 @@ def newButton(text, icon=None, slot=None): ...@@ -43,15 +43,8 @@ def newButton(text, icon=None, slot=None):
return b return b
def newAction(parent, def newAction(parent, text, slot=None, shortcut=None, icon=None,
text, tip=None, checkable=False, enabled=True, iconSize=None):
slot=None,
shortcut=None,
icon=None,
tip=None,
checkable=False,
enabled=True,
iconSize=None):
"""Create a new action and assign callbacks, shortcuts, etc.""" """Create a new action and assign callbacks, shortcuts, etc."""
a = QAction(text, parent) a = QAction(text, parent)
if icon is not None: if icon is not None:
...@@ -90,6 +83,7 @@ def labelValidator(): ...@@ -90,6 +83,7 @@ def labelValidator():
class struct(object): class struct(object):
def __init__(self, **kwargs): def __init__(self, **kwargs):
self.__dict__.update(kwargs) self.__dict__.update(kwargs)
...@@ -107,29 +101,24 @@ def generateColorByText(text): ...@@ -107,29 +101,24 @@ def generateColorByText(text):
s = ustr(text) s = ustr(text)
hashCode = int(hashlib.sha256(s.encode('utf-8')).hexdigest(), 16) hashCode = int(hashlib.sha256(s.encode('utf-8')).hexdigest(), 16)
r = int((hashCode / 255) % 255) r = int((hashCode / 255) % 255)
g = int((hashCode / 65025) % 255) g = int((hashCode / 65025) % 255)
b = int((hashCode / 16581375) % 255) b = int((hashCode / 16581375) % 255)
return QColor(r, g, b, 100) return QColor(r, g, b, 100)
def have_qstring(): def have_qstring():
'''p3/qt5 get rid of QString wrapper as py3 has native unicode str type''' '''p3/qt5 get rid of QString wrapper as py3 has native unicode str type'''
return not (sys.version_info.major >= 3 or QT_VERSION_STR.startswith('5.')) return not (sys.version_info.major >= 3 or QT_VERSION_STR.startswith('5.'))
def util_qt_strlistclass(): def util_qt_strlistclass():
return QStringList if have_qstring() else list return QStringList if have_qstring() else list
def natural_sort(list, key=lambda s:s):
def natural_sort(list, key=lambda s: s):
""" """
Sort the list into natural alphanumeric order. Sort the list into natural alphanumeric order.
""" """
def get_alphanum_key_func(key): def get_alphanum_key_func(key):
convert = lambda text: int(text) if text.isdigit() else text convert = lambda text: int(text) if text.isdigit() else text
return lambda s: [convert(c) for c in re.split('([0-9]+)', key(s))] return lambda s: [convert(c) for c in re.split('([0-9]+)', key(s))]
sort_key = get_alphanum_key_func(key) sort_key = get_alphanum_key_func(key)
list.sort(key=sort_key) list.sort(key=sort_key)
...@@ -161,7 +150,6 @@ def get_rotate_crop_image(img, points): ...@@ -161,7 +150,6 @@ def get_rotate_crop_image(img, points):
except Exception as e: except Exception as e:
print(e) print(e)
def stepsInfo(lang='en'): def stepsInfo(lang='en'):
if lang == 'ch': if lang == 'ch':
msg = "1. 安装与运行:使用上述命令安装与运行程序。\n" \ msg = "1. 安装与运行:使用上述命令安装与运行程序。\n" \
...@@ -191,4 +179,4 @@ def stepsInfo(lang='en'): ...@@ -191,4 +179,4 @@ def stepsInfo(lang='en'):
"9. Click 'Delete Image' and the image will be deleted to the recycle bin.\n"\ "9. Click 'Delete Image' and the image will be deleted to the recycle bin.\n"\
"10. Labeling result: After closing the application or switching the file path, the manually saved label will be stored in *Label.txt* under the opened picture folder.\n"\ "10. Labeling result: After closing the application or switching the file path, the manually saved label will be stored in *Label.txt* under the opened picture folder.\n"\
" Click PaddleOCR-Save Recognition Results in the menu bar, the recognition training data of such pictures will be saved in the *crop_img* folder, and the recognition label will be saved in *rec_gt.txt*.\n" " Click PaddleOCR-Save Recognition Results in the menu bar, the recognition training data of such pictures will be saved in the *crop_img* folder, and the recognition label will be saved in *rec_gt.txt*.\n"
return msg return msg
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册