Beispiel #1
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.__pixmap = QPixmap()
        self.__mode = PMode.IDLE
        self.__prevmode = PMode.IDLE
        self.__current = None
        self.__hShape = None
        self.__hVertex = None
        self.__shapes = []
        self.__drawingLineColor = QColor(45, 168, 179)
        self.__drawingRectColor = QColor(45, 168, 179)
        self.__line = Shape(line_color=self.drawingLineColor)
        self.__prevPoint = QPointF()
        self.__selectedShape = None
        self.__verified = False
        self.__hideBackground = False
        self.__toggleBackground = False
        self.__visible = {}
        self.scale = 1.0
        self._painter = QPainter()
        self._cursor = CURSOR_DEFAULT

        # Load string bundle for i18n
        self.__stringBundle = StringBundle.getBundle()

        self.setMouseTracking(True)
        self.setFocusPolicy(Qt.WheelFocus)
Beispiel #2
0
    def __init__(self, defaultFilename=None, defaaultPrefdefClassFile=None, defaultSaveDir=None):
        super(MainWindow, self).__init__()
        self.setWindowTitle(__appname__)

        #Load setting in the main thread
        self.settings = Settings()
        self.settings.load()
        settings = self.settings

        #load string bundle for i18n
        self.stringBundle = StringBundle.getBundle()
        getStr = lambda strId: self.stringBundle.getString(strId)

        #save as pascal voc xml
        self.defaultSaveDir = defaultSaveDir
        self.labelFileFormat = settings.get(SETTING_LABEL_FILE_FORMAT, LabelFileFormat.PASCAL_VOC)

        #for loading all image under a directory
        self.mImgList = []
        self.dirname = None
        self.labelHist = []
        self.lastOpenDir = None

        #NEED TO DO
        #whether we need to save or not
        self.dirty = False

        self._noSelectionSlot = False
        self._beginner = True
        self.screencastViewer = self.getAvailableScreencastViewer()
        self.screencast = "https://youtu.be/p0nR2YsCY_U"

        #Load predefined classes to the list
        self.loadPredefinedClasses(defaaultPrefdefClassFile)

        #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)

        self.useDefaultLableCheckbox = QCheckBox(getStr('useDefaultLabel'))
        self.useDefaultLableCheckbox.setChecked(False)
        self.defaultLabelTextLine = QLineEdit()
        useDefaultLabelQHBoxLayout = QHBoxLayout()
        useDefaultLabelQHBoxLayout.addWidget(self.useDefaultLableCheckbox)
        useDefaultLabelQHBoxLayout.addWidget(self.defaultLabelTextLine)
        useDefaultLabelContainer = QWidget()
        useDefaultLabelContainer.setLayout((useDefaultLabelQHBoxLayout))

        self.diffcButton = QCheckBox(getStr('useDifficult'))
        self.diffcButton.setChecked(False)
        self.diffcButton.stateChanged.connect(self.btnstate)
        self.editButton = QToolButton()
        self.editButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)

        listLayout.addWidget(self.editButton)
        listLayout.addWidget(self.diffcButton)
        listLayout.addWidget(useDefaultLabelContainer)

        self.comboBox = ComboBox(self)
        listLayout.addWidget(self.comboBox)

        # Create and add a widget for showing current label items
        self.labelList = QListWidget()
        labelListContainer = QWidget()
        labelListContainer.setLayout(listLayout)
        self.labelList.itemActivated.connect(self.labelSelectionChanged)
        self.labelList.itemSelectionChanged.connect(self.labelSelectionChanged)
        self.labelList.itemDoubleClicked.connect(self.editLabel)
        # Connect to itemChanged to detect checkbox changes.
        self.labelList.itemChanged.connect(self.labelItemChanged)
        listLayout.addWidget(self.labelList)

        self.dock = QDockWidget(getStr('boxLabelText'), self)
        self.dock.setObjectName(getStr('labels'))
        self.dock.setWidget(labelListContainer)

        self.fileListWidget = QListWidget()
        self.fileListWidget.itemDoubleClicked.connect(self.fileitemDoubleClicked)
        filelistLayout = QVBoxLayout()
        filelistLayout.setContentsMargins(0, 0, 0, 0)
        filelistLayout.addWidget(self.fileListWidget)
        fileListContainer = QWidget()
        fileListContainer.setLayout(filelistLayout)
        self.filedock = QDockWidget(getStr('fileList'), self)
        self.filedock.setObjectName(getStr('files'))
        self.filedock.setWidget(fileListContainer)

        self.zoomWidget = ZoomWidget()
        self.colorDialog = ColorDialog(parent=self)

        self.canvas = Canvas(parent=self)
        self.canvas.zoomRequest.connect(self.zoomRequest)
        self.canvas.setDrawingShapeToSquare(settings.get(SETTING_DRAW_SQUARE, False))

        scroll = QScrollArea()
        scroll.setWidget(self.canvas)
        scroll.setWidgetResizable(True)
        self.scrollBars = {
            Qt.Vertical: scroll.verticalScrollBar(),
            Qt.Horizontal: scroll.horizontalScrollBar()
        }
        self.scrollArea = scroll
        self.canvas.scrollRequest.connect(self.scrollRequest)

        self.canvas.newShape.connect(self.newShape)
        self.canvas.shapeMoved.connect(self.setDirty)
        self.canvas.selectionChanged.connect(self.shapeSelectionChanged)
        self.canvas.drawingPolygon.connect(self.toggleDrawingSensitive)

        self.setCentralWidget(scroll)
        self.addDockWidget(Qt.RightDockWidgetArea, self.dock)
        self.addDockWidget(Qt.RightDockWidgetArea, self.filedock)
        self.filedock.setFeatures(QDockWidget.DockWidgetFloatable)

        self.dockFeatures = QDockWidget.DockWidgetClosable | QDockWidget.DockWidgetFloatable
        self.dock.setFeatures(self.dock.features() ^ self.dockFeatures)
Beispiel #3
0
    def __init__(self, defaultFilename=None):
        super().__init__()
        self.setWindowTitle(__appname__)

        # Standard QT Parameter
        self.title = 'ROISA - Region of Interest Selector Automat'
        self.__left = 1
        self.__top = 30
        self.__width = 640
        self.__height = 480

        # Application state.
        self.__image = QImage()
        self.__filePath = defaultFilename

        # Load string bundle for i18n
        self.__stringBundle = StringBundle.getBundle()

        def getStr(strId):
            return self.__stringBundle.getString(strId)

        # Load Model classes
        self.__FileWrapper = FileWrapper(self, self.getPath())

        self.selectedClass = 0
        self.selectedFolder = '-'
        self.selectedNumIm = '-'
        self.selectedImSize = '-'
        self.selectedstrecth = 'cutting'

        # Create Canvas Widget
        self.__canvas = Canvas(parent=self)

        # Actions
        action = partial(newAction, self)

        quit = action(getStr('quit'), self.close, 'Ctrl+Q', 'quit',
                      getStr('quitApp'))

        open = action(getStr('file'), self.__FileWrapper.openFile, 'Ctrl+O',
                      'folder', getStr('openFile'))

        class0 = action(getStr('class0'), self.switchClass, 'Ctrl+1', 'class0',
                        getStr('class0'))

        # Store actions for further handling.
        self.__actions = struct(open=open,
                                fileMenuActions=(open, quit),
                                beginner=(),
                                advanced=(),
                                editMenu=(),
                                beginnerContext=(),
                                advancedContext=(),
                                onLoadActive=(),
                                onShapesPresent=())

        # Create Menus
        self.__menus = struct(file=self.menu('&File'),
                              edit=self.menu('&Edit'),
                              view=self.menu('&View'),
                              help=self.menu('&Help'),
                              recentFiles=QMenu('Open &Recent'))

        # Fill Menus
        addActions(self.__menus.file, (
            open,
            quit,
        ))
        # addActions(self.menus.help, (help, showInfo))
        # addActions(self.menus.view, (
        #     self.autoSaving,
        #     self.singleClassMode,
        #     self.displayLabelOption,
        #     labels, advancedMode, None,
        #     hideAll, showAll, None,
        #     zoomIn, zoomOut, zoomOrg, None,
        #     fitWindow, fitWidth))

        # Create Toolbars
        self.__tools = self.toolbar('Tools')
        self.__actions.beginner = (open, None, quit)

        addActions(self.__tools, self.__actions.beginner)

        self.statusBar().showMessage('%s started.' % __appname__)
        self.statusBar().show()
Beispiel #4
0
    def __init__(self,
                 defaultFilename=None,
                 defaultPrefdefClassFile=None,
                 defaultSaveDir=None):
        super(MainWindow, self).__init__()
        self.setupUi(self)

        # For loading all image under a directory
        self.mImgList = []
        self.dirname = None
        self.labelHist = []
        self.lastOpenDir = None

        self.filePath = ustr(defaultFilename)
        # Load setting in the main thread
        self.settings = Settings()
        self.settings.load()
        settings = self.settings

        # Whether we need to save or not.
        self.dirty = False
        self.statusBar().showMessage('%s started.' % __appname__)
        self.statusBar().show()

        # Load string bundle for i18n
        self.stringBundle = StringBundle.getBundle()
        getStr = lambda strId: self.stringBundle.getString(strId)  # 作用?
        # Save as Pascal voc xml
        self.defaultSaveDir = None  # defaultSaveDir
        self.labelFileFormat = settings.get(SETTING_LABEL_FILE_FORMAT,
                                            LabelFileFormat.PASCAL_VOC)

        # Auto saving : Enable auto saving if pressing next
        self.autoSaving = QAction(getStr('autoSaveMode'), self)
        self.autoSaving.setCheckable(True)
        self.autoSaving.setChecked(settings.get(SETTING_AUTO_SAVE,
                                                False))  # 未加入setting

        self.canvas = Canvas(parent=self)
        # self.canvas.zoomRequest.connect(self.zoomRequest)
        self.canvas.setDrawingShapeToSquare(
            settings.get(SETTING_DRAW_SQUARE, False))

        self.listView.itemDoubleClicked.connect(
            self.fileitemDoubleClicked)  # 双击

        self.open.triggered.connect(self.openFile)

        # Actions
        action = partial(newAction, self)
        quit = action(getStr('quit'), self.close, 'Ctrl+Q', 'quit',
                      getStr('quitApp'))

        open = action(getStr('openFile'), self.openFile, 'Ctrl+O', 'open',
                      getStr('openFileDetail'))

        opendir = action(getStr('openDir'), self.openDirDialog, 'Ctrl+u',
                         'open', getStr('openDir'))

        copyPrevBounding = action(getStr('copyPrevBounding'),
                                  self.copyPreviousBoundingBoxes, 'Ctrl+v',
                                  'paste', getStr('copyPrevBounding'))

        changeSavedir = action(getStr('changeSaveDir'),
                               self.changeSavedirDialog, 'Ctrl+r', 'open',
                               getStr('changeSavedAnnotationDir'))

        # openAnnotation = action(getStr('openAnnotation'), self.openAnnotationDialog,
        #                         'Ctrl+Shift+O', 'open', getStr('openAnnotationDetail'))

        openNextImg = action(getStr('nextImg'), self.openNextImg, 'd', 'next',
                             getStr('nextImgDetail'))

        openPrevImg = action(getStr('prevImg'), self.openPrevImg, 'a', 'prev',
                             getStr('prevImgDetail'))

        # verify = action(getStr('verifyImg'), self.verifyImg,
        #                 'space', 'verify', getStr('verifyImgDetail'))

        save = action(getStr('save'),
                      self.saveFile,
                      'Ctrl+S',
                      'save',
                      getStr('saveDetail'),
                      enabled=False)

        isUsingPascalVoc = self.labelFileFormat == LabelFileFormat.PASCAL_VOC
        # save_format = action('&PascalVOC' if isUsingPascalVoc else '&YOLO',
        #                      self.change_format, 'Ctrl+',
        #                      'format_voc' if isUsingPascalVoc else 'format_yolo',
        #                      getStr('changeSaveFormat'), enabled=True)

        saveAs = action(getStr('saveAs'),
                        self.saveFileAs,
                        'Ctrl+Shift+S',
                        'save-as',
                        getStr('saveAsDetail'),
                        enabled=False)

        close = action(getStr('closeCur'), self.closeFile, 'Ctrl+W', 'close',
                       getStr('closeCurDetail'))

        deleteImg = action(getStr('deleteImg'), self.deleteImg, 'Ctrl+D',
                           'close', getStr('deleteImgDetail'))

        resetAll = action(getStr('resetAll'), self.resetAll, None, 'resetall',
                          getStr('resetAllDetail'))

        # color1 = action(getStr('boxLineColor'), self.chooseColor1,
        #                 'Ctrl+L', 'color_line', getStr('boxLineColorDetail'))

        # createMode = action(getStr('crtBox'), self.setCreateMode,
        #                     'w', 'new', 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)

        # advancedMode = action(getStr('advancedMode'), self.toggleAdvancedMode,
        #                       'Ctrl+Shift+A', 'expert', getStr('advancedModeDetail'),
        #                       checkable=True)

        # hideAll = action('&Hide\nRectBox', partial(self.togglePolygons, False),
        #                  'Ctrl+H', 'hide', getStr('hideAllBoxDetail'),
        #                  enabled=False)
        # showAll = action('&Show\nRectBox', 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'))
        self.zoomWidget = ZoomWidget()
        zoom = QWidgetAction(self)
        zoom.setDefaultWidget(self.zoomWidget)
        self.zoomWidget.setWhatsThis(
            u"Zoom in or out of the image. Also accessible with"
            " %s and %s from the canvas." %
            (fmtShortcut("Ctrl+[-+]"), fmtShortcut("Ctrl+Wheel")))
        self.zoomWidget.setEnabled(False)

        # zoomIn = action(getStr('zoomin'), partial(self.addZoom, 10),
        #                 'Ctrl++', 'zoom-in', getStr('zoominDetail'), enabled=False)
        # zoomOut = action(getStr('zoomout'), partial(self.addZoom, -10),
        #                  'Ctrl+-', 'zoom-out', 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.
        # zoomActions = (self.zoomWidget, zoomIn, zoomOut,
        #                zoomOrg, fitWindow, fitWidth)
        # self.zoomMode = self.MANUAL_ZOOM
        # self.scalers = {
        #     self.FIT_WINDOW: self.scaleFitWindow,
        #     self.FIT_WIDTH: self.scaleFitWidth,
        #     # Set to one to scale to 100% when loading files.
        #     self.MANUAL_ZOOM: lambda: 1,
        # }

        # edit = action(getStr('editLabel'), self.editLabel,
        #               'Ctrl+E', 'edit', getStr('editLabelDetail'),
        #               enabled=False)
        # self.editButton.setDefaultAction(edit)

        # shapeLineColor = action(getStr('shapeLineColor'), self.chshapeLineColor,
        #                         icon='color_line', tip=getStr('shapeLineColorDetail'),
        #                         enabled=False)
        # shapeFillColor = action(getStr('shapeFillColor'), self.chshapeFillColor,
        #                         icon='color', tip=getStr('shapeFillColorDetail'),
        #                         enabled=False)

        # 文件夹
        # Store actions for further handling.
        self.actions = struct(
            save=save,
            saveAs=saveAs,
            open=open,
            close=close,  #save_format=save_format,
            resetAll=resetAll,
            deleteImg=deleteImg,
            #lineColor=color1, create=create, delete=delete, edit=edit, copy=copy,
            #createMode=createMode, editMode=editMode, advancedMode=advancedMode,
            # shapeLineColor=shapeLineColor, shapeFillColor=shapeFillColor,
            # zoom=zoom, zoomIn=zoomIn, zoomOut=zoomOut, zoomOrg=zoomOrg,
            # fitWindow=fitWindow, fitWidth=fitWidth,
            # zoomActions=zoomActions,
            fileMenuActions=(open, opendir, save, saveAs, close, resetAll,
                             quit),
            beginner=(),
            advanced=(),
            # editMenu=(edit, copy, delete,
            #           None, color1, self.drawSquaresOption),
            # beginnerContext=(create, edit, copy, delete),
            # advancedContext=(createMode, editMode, edit, copy,
            #                  delete, shapeLineColor, shapeFillColor),
            onLoadActive=(close),  #, create, createMode, editMode),
            onShapesPresent=(saveAs))  #, hideAll, showAll))
        # Custom context menu for the canvas widget:
        # addActions(self.canvas.menus[0], self.actions.beginnerContext)
        # addActions(self.canvas.menus[1], (
        #     action('&Copy here', self.copyShape),
        #     action('&Move here', self.moveShape)))

        # self.tools = self.toolbar('Tools')
        self.actions.beginner = (
            open,
            opendir,
            changeSavedir,
            openNextImg,
            openPrevImg,
            save,
            None,  #create, copy,  verify, save_format,
            #delete, None,
        )  # zoomIn, zoom, zoomOut, fitWindow, fitWidth)

        self.actions.advanced = (
            open,
            opendir,
            changeSavedir,
            openNextImg,
            openPrevImg,
            save,
            None,  #save_format,
            #createMode, editMode, None,
        )  # hideAll, showAll)

        scroll = QScrollArea()
        scroll.setWidget(self.canvas)
        scroll.setWidgetResizable(True)
        self.scrollBars = {
            Qt.Vertical: scroll.verticalScrollBar(),
            Qt.Horizontal: scroll.horizontalScrollBar()
        }
Beispiel #5
0
    def __init__(self, defaultFilename=None, defaultPrefdefClassFile=None, defaultSaveDir=None):
        super(MainWindow, self).__init__()
        self.setWindowTitle(__appname__)
        self.settings = Settings()
        self.settings.load()
        settings = self.settings
        self.stringBundle = StringBundle.getBundle()
        getStr = lambda strId: self.stringBundle.getString(strId)
        self.defaultSaveDir = defaultSaveDir
        self.mImgList = []
        self.dirname = None
        self.labelHist = []
        self.lastOpenDir = None
        self.dirty = False
        self.countEnable = 0
        self._noSelectionSlot = False
        self._beginner = True
        self.loadPredefinedClasses(defaultPrefdefClassFile)
        self.defaultPrefdefClassFile = defaultPrefdefClassFile
        self.labelDialog = LabelDialog(parent=self, listItem=self.labelHist)
        self.itemsToShapes = {}
        self.shapesToItems = {}
        self.prevLabelText = ''
        listLayout = QVBoxLayout()
        listLayout.setContentsMargins(0, 0, 0, 0)
        self.defaultLabelTextLine = QLineEdit()
        self.labelList = QListWidget()
        self.logContainer = QListWidget()
        labelListContainer = QWidget()
        labelListContainer.setLayout(listLayout)
        self.labelList.itemClicked.connect(self.labelSelectionChanged)
        listLayout.addWidget(self.labelList)
        self.logContainer.itemChanged.connect(self.pointListChanged)
        self.logContainer.itemClicked.connect(self.pointSelectionChange)
        self.dock = QDockWidget("Log", self)
        self.dock.setObjectName(getStr('labels'))
        self.dock.setWidget(self.logContainer)
        self.logDock = QDockWidget(getStr('boxLabelText'), self)
        self.logDock.setObjectName("Log")
        self.logDock.setWidget(labelListContainer)
        self.zoomWidget = ZoomWidget()
        self.canvas = Canvas(parent=self)
        self.canvas.zoomRequest.connect(self.zoomRequest)
        self.canvas.setDrawingShapeToSquare(settings.get(SETTING_DRAW_SQUARE, False))
        scroll = QScrollArea()
        scroll.setWidget(self.canvas)
        scroll.setWidgetResizable(True)
        self.scrollBars = {
            Qt.Vertical: scroll.verticalScrollBar(),
            Qt.Horizontal: scroll.horizontalScrollBar()
        }
        self.scrollArea = scroll
        self.canvas.scrollRequest.connect(self.scrollRequest)
        self.canvas.newShape.connect(self.newShape)
        self.canvas.shapeMoved.connect(self.setDirty)
        self.canvas.selectionChanged.connect(self.shapeSelectionChanged)
        self.canvas.drawingPolygon.connect(self.toggleDrawingSensitive)
        self.setCentralWidget(scroll)
        self.addDockWidget(Qt.RightDockWidgetArea, self.logDock)
        self.addDockWidget(Qt.RightDockWidgetArea, self.dock)
        self.dockFeatures = QDockWidget.DockWidgetClosable | QDockWidget.DockWidgetFloatable
        self.logDock.setFeatures(self.logDock.features() ^ self.dockFeatures)
        self.dock.setFeatures(self.dock.features() ^ self.dockFeatures)
        action = partial(newAction, self)
        quit = action(getStr('quit'), self.close,
                      '', 'quit', getStr('quitApp'))
        open = action(getStr('openFile'), self.openFile,
                      '', 'open', getStr('openFileDetail'))
        save = action(getStr('save'), self.saveFile,
                      '', 'save', getStr('saveDetail'), enabled=False)
        count = action('Count', self.countCell,
                      '', 'color_line', 'count', enabled=False)
        self.partition  = action("Auto Partition", self.createFixedPartition,
                             '', 'verify', "Partition", enabled=False)
        self.selectNone = action('Select None', self.selectFun,
                        '', 'done', 'select', enabled=False)
        openNextImg = action("Next Image", self.openNextImg,
                             '', 'next', "next image", enabled=False)
        create = action("Create RectBox", self.createShape,
                        '', 'new', getStr('crtBoxDetail'), enabled=False)
        delete = action("Delete RectBox", self.deleteSelectedShape,
                        'Delete', 'delete', getStr('delBoxDetail'), enabled=False)
        copy = action("Duplicate RectBox", self.copySelectedShape,
                      '', 'copy', getStr('dupBoxDetail'),
                      enabled=False)
        zoom = QWidgetAction(self)
        zoom.setDefaultWidget(self.zoomWidget)
        self.zoomWidget.setWhatsThis(
            u"Zoom in or out of the image. Also accessible with"
            " %s and %s from the canvas." % (fmtShortcut("Ctrl+[-+]"),
                                             fmtShortcut("Ctrl+Wheel")))
        self.zoomWidget.setEnabled(False)
        help = action('Help',self.helpDialog,None,'help')
        about = action('About',self.aboutDialog,None,'help')
        zoomIn = action(getStr('zoomin'), partial(self.addZoom, 10),
                        '', 'zoom-in', getStr('zoominDetail'), enabled=False)
        zoomOut = action(getStr('zoomout'), partial(self.addZoom, -10),
                         '', 'zoom-out', getStr('zoomoutDetail'), enabled=False)
        zoomOrg = action(getStr('originalsize'), partial(self.setZoom, 100),
                         '', 'zoom', getStr('originalsizeDetail'), enabled=False)
        fitWindow = action(getStr('fitWin'), self.setFitWindow,
                           '', 'fit-window', getStr('fitWinDetail'),
                           checkable=True, enabled=False)
        fitWidth = action(getStr('fitWidth'), self.setFitWidth,
                          '', 'fit-width', getStr('fitWidthDetail'),
                          checkable=True, enabled=False)
        zoomActions = (self.zoomWidget, zoomIn, zoomOut,
                       zoomOrg, fitWindow, fitWidth)
        self.zoomMode = self.MANUAL_ZOOM
        self.scalers = {
            self.FIT_WINDOW: self.scaleFitWindow,
            self.FIT_WIDTH: self.scaleFitWidth,
            self.MANUAL_ZOOM: lambda: 1,
        }
        labelMenu = QMenu()
        addActions(labelMenu, (delete,))
        self.labelList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.labelList.customContextMenuRequested.connect(
            self.popLabelListMenu)
        self.sporeCountOption = QAction('Spore count', self)
        self.sporeCountOption.setCheckable(True)
        self.sporeCountOption.setDisabled(True)
        self.sporeCountOption.triggered.connect(self.sporeCountFun)

        self.rbcCountOption = QAction('RBC count', self)
        self.rbcCountOption.setCheckable(True)
        self.rbcCountOption.setDisabled(True)
        self.rbcCountOption.triggered.connect(self.rbcCountFun)

        self.wbcCountOption = QAction('WBC count', self)
        self.wbcCountOption.setCheckable(True)
        self.wbcCountOption.setDisabled(True)
        self.wbcCountOption.triggered.connect(self.wbcCountFun)

        self.bacteriaCountOption = QAction('Bacteria count', self)
        self.bacteriaCountOption.setCheckable(True)
        self.bacteriaCountOption.setDisabled(True)
        self.bacteriaCountOption.triggered.connect(self.bacteriaCountFun)

        self.labelImage = QAction('Label Image', self)
        self.labelImage.setDisabled(True)
        self.labelImage.triggered.connect(self.labelImageFun)

        self.modifyLabel = QAction('Modify Label', self)
        self.modifyLabel.setDisabled(False)
        self.modifyLabel.triggered.connect(self.modifyLabelFun)

        self.createModel = QAction('Create Model', self)
        self.createModel.setDisabled(True)
        self.createModel.triggered.connect(self.createModelFun)

        self.useModel = QAction('Use Existing  Model', self)
        self.useModel.setDisabled(True)
        self.useModel.triggered.connect(self.useModelFun)

        self.actions = struct(save=save, open=open, count=(count,), selectNone=self.selectNone, partition=self.partition, create=create, delete=delete, copy=copy,
                              zoom=zoom, zoomIn=zoomIn, zoomOut=zoomOut, zoomOrg=zoomOrg,
                              fitWindow=fitWindow, fitWidth=fitWidth,
                              zoomActions=zoomActions,
                              beginner=(), advanced=(),
                              menuMenu=(self.sporeCountOption, self.rbcCountOption,
                                        self.wbcCountOption,
                                        self.bacteriaCountOption),
                              toolMenu=(self.labelImage, self.modifyLabel),
                              modelMenu=(self.createModel, self.useModel),
                              beginnerContext=(create, copy, delete),
                              advancedContext=(copy,
                                               delete),
                              onLoadActive=(create,),
                              onNullImage=(self.labelImage, self.sporeCountOption, self.rbcCountOption, self.bacteriaCountOption, self.createModel, self.useModel),
                              onLabelSelect=(openNextImg, ),
                              resetDeActive=(count, copy, delete, save, create, openNextImg, self.selectNone, self.partition))
        self.menus = struct(
            file=self.menu('&File'),
            menu=self.menu('&Menu'),
            tool=self.menu('&Tools'),
            model=self.menu('&Models'),
            help=self.menu('&Help'))
        self.lastLabel = None
        addActions(self.menus.file,
                   (open, save, quit))
        addActions(self.menus.help,(help,about))

        self.menus.file.aboutToShow.connect(self.updateFileMenu)
        addActions(self.canvas.menus[0], self.actions.beginnerContext)
        addActions(self.canvas.menus[1], (
            action('&Copy here', self.copyShape),
            action('&Move here', self.moveShape)))

        self.tools = self.toolbar('Tools')
        self.actions.beginner = (
            open, count, self.partition, self.selectNone, save, None, openNextImg, create, copy, delete, None,
            zoomIn, zoom, zoomOut, fitWindow, fitWidth)

        self.actions.advanced = (open, save, count, self.partition, self.selectNone, None)
        self.statusBar().showMessage('%s started.' % __appname__)
        self.statusBar().show()

        self.image = QImage()
        self.filePath = defaultFilename
        self.recentFiles = []
        self.maxRecent = 7
        self.lineColor = None
        self.fillColor = None
        self.zoom_level = 100
        self.fit_window = False
        self.difficult = False

        if settings.get(SETTING_RECENT_FILES):
            if have_qstring():
                recentFileQStringList = settings.get(SETTING_RECENT_FILES)
                self.recentFiles = [i for i in recentFileQStringList]
            else:
                self.recentFiles = recentFileQStringList = settings.get(SETTING_RECENT_FILES)

        size = settings.get(SETTING_WIN_SIZE, QSize(600, 500))
        position = QPoint(0, 0)
        saved_position = settings.get(SETTING_WIN_POSE, position)
        # Fix the multiple monitors issue
        for i in range(QApplication.desktop().screenCount()):
            if QApplication.desktop().availableGeometry(i).contains(saved_position):
                position = saved_position
                break
        self.resize(size)
        self.move(position)
        saveDir = settings.get(SETTING_SAVE_DIR, None)
        self.lastOpenDir = settings.get(SETTING_LAST_OPEN_DIR, None)
        if self.defaultSaveDir is None and saveDir is not None and os.path.exists(saveDir):
            self.defaultSaveDir = saveDir
            self.statusBar().showMessage('%s started. Annotation will be saved to %s' %
                                         (__appname__, self.defaultSaveDir))
            self.statusBar().show()
        self.restoreState(settings.get(SETTING_WIN_STATE, QByteArray()))
        Shape.line_color = self.lineColor = QColor(settings.get(SETTING_LINE_COLOR, DEFAULT_LINE_COLOR))
        Shape.fill_color = self.fillColor = QColor(settings.get(SETTING_FILL_COLOR, DEFAULT_FILL_COLOR))
        self.canvas.setDrawingColor(self.lineColor)
        Shape.difficult = self.difficult
        self.updateFileMenu()
        self.zoomWidget.valueChanged.connect(self.paintCanvas)
        self.populateModeActions()
        self.labelCoordinates = QLabel('')
        self.statusBar().addPermanentWidget(self.labelCoordinates)
Beispiel #6
0
    def __init__(self):

        super().__init__()

        # 전체 폼 박스
        formbox = QHBoxLayout()
        self.setLayout(formbox)

        # 좌, 우 레이아웃박스
        left = QVBoxLayout()
        right = QVBoxLayout()

        # 그룹박스1 생성 및 좌 레이아웃 배치
        gb = QGroupBox('그리기 종류')
        left.addWidget(gb)

        # 그룹박스1 에서 사용할 레이아웃
        box = QVBoxLayout()
        gb.setLayout(box)

        # 그룹박스 1 의 라디오 버튼 배치
        text = ['line', 'Curve', 'Rectange', 'Ellipse']
        self.radiobtns = []

        for i in range(len(text)):
            self.radiobtns.append(QRadioButton(text[i], self))
            self.radiobtns[i].clicked.connect(self.radioClicked)
            box.addWidget(self.radiobtns[i])

        self.radiobtns[0].setChecked(True)
        self.drawType = 0

        # 그룹박스2
        gb = QGroupBox('펜 설정')
        left.addWidget(gb)

        grid = QGridLayout()
        gb.setLayout(grid)

        label = QLabel('선굵기')
        grid.addWidget(label, 0, 0)

        self.combo = QComboBox()
        grid.addWidget(self.combo, 0, 1)

        for i in range(1, 21):
            self.combo.addItem(str(i))

        label = QLabel('선색상')
        grid.addWidget(label, 1, 0)

        self.pencolor = QColor(0, 0, 0)
        self.penbtn = QPushButton()
        self.penbtn.setStyleSheet('background-color: rgb(0,0,0)')
        self.penbtn.clicked.connect(self.showColorDlg)
        grid.addWidget(self.penbtn, 1, 1)

        # 그룹박스3
        gb = QGroupBox('붓 설정')
        left.addWidget(gb)

        hbox = QHBoxLayout()
        gb.setLayout(hbox)

        label = QLabel('붓색상')
        hbox.addWidget(label)

        self.brushcolor = QColor(255, 255, 255)
        self.brushbtn = QPushButton()
        self.brushbtn.setStyleSheet('background-color: rgb(255,255,255)')
        self.brushbtn.clicked.connect(self.showColorDlg)
        hbox.addWidget(self.brushbtn)

        # 그룹박스4
        gb = QGroupBox('지우개')
        left.addWidget(gb)

        hbox = QHBoxLayout()
        gb.setLayout(hbox)

        self.checkbox = QCheckBox('지우개 동작')
        self.checkbox.stateChanged.connect(self.checkClicked)
        hbox.addWidget(self.checkbox)

        left.addStretch(1)

        # 우 레이아웃 박스에 그래픽 뷰 추가
        self.view = CView(self)
        right.addWidget(self.view)

        # 전체 폼박스에 좌우 박스 배치
        formbox.addLayout(left)
        formbox.addLayout(right)

        formbox.setStretchFactor(left, 0)
        formbox.setStretchFactor(right, 1)

        self.setGeometry(100, 100, 800, 500)

        # sangkny
        # Load setting in the main thread
        self.settings = Settings()
        self.settings.load()
        settings = self.settings

        # Load string bundle for i18n
        self.stringBundle = StringBundle.getBundle()
        getStr = lambda strId: self.stringBundle.getString(strId)

        self.itemsToShapes = {}
        self.shapesToItems = {}
        self.prevLabelText = ''

        self.canvas = Canvas(parent=self)
        # self.canvas.zoomRequest.connect(self.zoomRequest)
        self.canvas.setDrawingShapeToSquare(
            settings.get(SETTING_DRAW_SQUARE, False))

        # Draw squares/rectangles
        self.drawSquaresOption = QAction('Draw Squares', self)
        self.drawSquaresOption.setShortcut('Ctrl+Shift+R')
        self.drawSquaresOption.setCheckable(True)
        self.drawSquaresOption.setChecked(
            settings.get(SETTING_DRAW_SQUARE, False))
        self.drawSquaresOption.triggered.connect(self.toogleDrawSquare)

        # Actions
        action = partial(newAction, self)
        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)
        createMode = action(getStr('crtBox'),
                            self.setCreateMode,
                            'w',
                            'new',
                            getStr('crtBoxDetail'),
                            enabled=False)
        editMode = action('&Edit\nRectBox',
                          self.setEditMode,
                          'Ctrl+J',
                          'edit',
                          u'Move and edit Boxs',
                          enabled=False)
        edit = action(getStr('editLabel'),
                      self.editLabel,
                      'Ctrl+E',
                      'edit',
                      getStr('editLabelDetail'),
                      enabled=False)
        shapeLineColor = action(getStr('shapeLineColor'),
                                self.chshapeLineColor,
                                icon='color_line',
                                tip=getStr('shapeLineColorDetail'),
                                enabled=False)
        shapeFillColor = action(getStr('shapeFillColor'),
                                self.chshapeFillColor,
                                icon='color',
                                tip=getStr('shapeFillColorDetail'),
                                enabled=False)
        advancedMode = action(getStr('advancedMode'),
                              self.toggleAdvancedMode,
                              'Ctrl+Shift+A',
                              'expert',
                              getStr('advancedModeDetail'),
                              checkable=True)

        # Store actions for further handling.
        self.actions = struct(
            create=create,
            delete=delete,
            edit=edit,
            copy=copy,
            createMode=createMode,
            editMode=editMode,
            advancedMode=advancedMode,
            shapeLineColor=shapeLineColor,
            shapeFillColor=shapeFillColor
            # editMenu=(edit, copy, delete,
            #           None, color1, self.drawSquaresOption),
            # beginnerContext=(create, edit, copy, delete),
            # advancedContext=(createMode, editMode, edit, copy,
            #                  delete, shapeLineColor, shapeFillColor),
            # onLoadActive=(
            #     close, create, createMode, editMode),
            # onShapesPresent=(saveAs, hideAll, showAll)
        )
Beispiel #7
0
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

from functools import partial
from collections import Counter
from functools import partial

from libs.utils import newAction, fmtShortcut
from libs.stringBundle import StringBundle
from libs.errors import ClassesError
from libs.settings import Settings
from libs.constants import *

# Load string bundle for i18n
stringBundle = StringBundle.getBundle()


def getStr(strId):
    return stringBundle.getString(strId)


def get_quit(self):
    quit = newAction(self, getStr('quit'), self.close, 'Ctrl+Q', 'quit',
                     getStr('quitFull'))
    return quit


def get_open(self):
    open = newAction(self, getStr('file'), self.openFile, 'Ctrl+O', 'folder',
                     getStr('fileFull'))
Beispiel #8
0
    def __init__(self,
                 defaultFilename=None,
                 defaaultPrefdefClassFile=None,
                 defaultSaveDir=None):
        super(MainWindow, self).__init__()
        self.setWindowTitle(__appname__)

        #Load setting in the main thread
        self.settings = Settings()
        self.settings.load()
        settings = self.settings

        #load string bundle for i18n
        self.stringBundle = StringBundle.getBundle()
        getStr = lambda strId: self.stringBundle.getString(strId)

        #save as pascal voc xml
        self.defaultSaveDir = defaultSaveDir
        self.labelFileFormat = settings.get(SETTING_LABEL_FILE_FORMAT,
                                            LabelFileFormat.PASCAL_VOC)

        #for loading all image under a directory
        self.mImgList = []
        self.dirname = None
        self.labelHist = []
        self.lastOpenDir = None

        #NEED TO DO
        #whether we need to save or not
        self.dirty = False

        self._noSelectionSlot = False
        self._beginner = True
        self.screencastViewer = self.getAvailableScreencastViewer()
        self.screencast = "https://youtu.be/p0nR2YsCY_U"

        #Load predefined classes to the list
        self.loadPredefinedClasses(defaaultPrefdefClassFile)

        #main widgets and related state
        self.labelDialog = LabelDialog(parent=self, listItem=self.labelHist)

        self.itemsToShapes = {}
        self.shapesToItems = {}
        self.prevLabelText = ''

        filelistLayout = QVBoxLayout()
        filelistLayout.setContentsMargins(0, 0, 0, 0)
        self.fileList = QListWidget()
        self.fileList.itemDoubleClicked.connect(self.fileitemDoubleClicked)
        filelistLayout.addWidget(self.fileList)
        fileListContainer = QWidget()
        fileListContainer.setLayout(filelistLayout)
        self.filedock = QDockWidget(getStr('fileList'), self)
        self.filedock.setObjectName(getStr('files'))
        self.filedock.setWidget(fileListContainer)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.filedock)

        self.zoomWidget = ZoomWidget()
        self.colorDialog = ColorDialog(parent=self)
        self.canvas = Canvas(parent=self)
        self.canvas.zoomRequest.connect(self.zoomRequest)
        self.canvas.setDrawingShapeToSquare(
            settings.get(SETTING_DRAW_SQUARE, False))
        scroll = QScrollArea()
        scroll.setWidget(self.canvas)
        scroll.setWidgetResizable(True)
        self.scrollBars = {
            Qt.Vertical: scroll.verticalScrollBar(),
            Qt.Horizontal: scroll.horizontalScrollBar()
        }
        self.scrollArea = scroll
        self.canvas.scrollRequest.connect(self.scrollRequest)
        self.canvas.newShape.connect(self.newShape)
        self.canvas.shapeMoved.connect(self.setDirty)
        self.canvas.selectionChanged.connect(self.shapeSelectionChanged)
        self.canvas.drawingPolygon.connect(self.toggleDrawingSensitive)
        self.setCentralWidget(scroll)

        rightListLayout = QVBoxLayout()

        self.addNewBboxBtn = QPushButton(getStr('addNewBbox'))
        self.addNewBboxBtn.setEnabled(True)
        self.addNewBboxBtn.clicked.connnect(self.createShape)
        self.reLabelBtn = QPushButton(getStr('reLabel'))
        self.reLabelBtn.setEnabled(True)
        self.reLabelBtn.clicked.connect(self.reLabel)
        rightUpLayout = QHBoxLayout()
        rightUpLayout.addWidget(self.addNewBboxBtn)
        rightUpLayout.addWidget(self.reLabelBtn)
Beispiel #9
0
    def __init__(self,
                 appname='defaultName',
                 defaultFilename=nonePath,
                 defaultPredefClassFile=nonePath,
                 defaultImageFolder=nonePath,
                 defaultLabelFolder=nonePath):
        super().__init__()
        self.__appname = appname
        self.setWindowTitle(appname)

        # Load string bundle for i18n
        self.__stringBundle = StringBundle.getBundle()

        def getStr(strId):
            return self.__stringBundle.getString(strId)

        # Load setting in the main thread
        self.settings = Settings()
        self.settings.load()
        settings = self.settings

        # Unsaved Status Flag
        self.__dirty = False

        # For loading all image under a directory
        self.__mImgList = []
        self.__foldername = nonePath
        self.__labelHist = []

        # Match Shapes and Labels
        self.__itemsToShapes = {}
        self.__shapesToItems = {}
        self.__prevLabelText = ''
        self.__noSelectionSlot = False

        # Application state.
        self.__selectedClass = None

        # File and path informations
        self.__image = QImage()
        self.__filePath = defaultFilename
        self.__imageFolder = defaultImageFolder
        self.__labelFolder = defaultLabelFolder
        self.__lastOpenFolder = nonePath
        self.__loadPredefinedClasses(defaultPredefClassFile)
        self.__recentFiles = []
        self.__maxRecent = 7

        # Application state
        self.__lineColor = None
        self.__fillColor = None

        # Save as Format Flags
        self.__usePascalVocFormat = True
        self.__useYoloFormat = False
        self.__useBoxSupFormat = False
        self.__useBoxSupMaskFormat = False
        self.__mask = False

        # ##############################WDIGETS############################## #

        # Create ZoomWidget
        self.zoomWidget = ZoomWidget()

        # ____________________    __________       _____
        # ___  ____/__(_)__  /_______  /__(_)________  /_
        # __  /_   __  /__  /_  _ \_  /__  /__  ___/  __/
        # _  __/   _  / _  / /  __/  / _  / _(__  )/ /_
        # /_/      /_/  /_/  \___//_/  /_/  /____/ \__/

        # Create FileListWidget
        listLayout = QVBoxLayout()
        listLayout.setContentsMargins(0, 0, 0, 0)

        # Create and add a widget for showing current label items
        self.labelList = QListWidget()
        labelListContainer = QWidget()
        labelListContainer.setLayout(listLayout)
        self.labelList.itemActivated.connect(self.labelSelectionChanged)
        self.labelList.itemSelectionChanged.connect(self.labelSelectionChanged)
        # self.labelList.itemDoubleClicked.connect(self.editLabel)
        # Connect to itemChanged to detect checkbox changes.
        self.labelList.itemChanged.connect(self.labelItemChanged)
        listLayout.addWidget(self.labelList)

        self.boxDock = QDockWidget(getStr('boxLabelText'), self)
        self.boxDock.setObjectName(getStr('labels'))
        self.boxDock.setWidget(labelListContainer)

        self.__fileListWidget = QListWidget()
        self.fileListWidget.itemDoubleClicked.\
            connect(self.fileitemDoubleClicked)
        filelistLayout = QVBoxLayout()
        filelistLayout.setContentsMargins(0, 0, 0, 0)
        filelistLayout.addWidget(self.fileListWidget)
        fileListContainer = QWidget()
        fileListContainer.setLayout(filelistLayout)
        self.fileDock = QDockWidget(getStr('fileList'), self)
        self.fileDock.setObjectName(getStr('files'))
        self.fileDock.setWidget(fileListContainer)

        # Create Canvas Widget
        self.__canvas = Canvas(parent=self)
        self.canvas.setEnabled(False)

        # Create Central Widget
        scroll = QScrollArea()
        scroll.setWidget(self.canvas)
        scroll.setWidgetResizable(True)
        self.scrollBars = {
            Qt.Vertical: scroll.verticalScrollBar(),
            Qt.Horizontal: scroll.horizontalScrollBar()
        }
        self.scrollArea = scroll

        # ____________                      ______
        # __  ___/__(_)______ _____________ ___  /_______
        # _____ \__  /__  __ `/_  __ \  __ `/_  /__  ___/
        # ____/ /_  / _  /_/ /_  / / / /_/ /_  / _(__  )
        # /____/ /_/  _\__, / /_/ /_/\__,_/ /_/  /____/

        self.canvas.newShape.connect(self.newShape)
        self.canvas.shapeMoved.connect(self.shapeMoved)
        self.canvas.selectionChanged.connect(self.shapeSelectionChanged)
        self.canvas.finishedDrawing.connect(self.finishedDrawing)

        self.setCentralWidget(scroll)
        self.addDockWidget(Qt.RightDockWidgetArea, self.boxDock)
        self.addDockWidget(Qt.RightDockWidgetArea, self.fileDock)
        self.fileDock.setFeatures(QDockWidget.DockWidgetFloatable)

        self.dockFeatures = QDockWidget.DockWidgetClosable \
            | QDockWidget.DockWidgetFloatable
        self.boxDock.setFeatures(self.boxDock.features() ^ self.dockFeatures)

        # _______      __________
        # ___    |_______  /___(_)____________________
        # __  /| |  ___/  __/_  /_  __ \_  __ \_  ___/
        # _  ___ / /__ / /_ _  / / /_/ /  / / /(__  )
        # /_/  |_\___/ \__/ /_/  \____//_/ /_//____/

        # Load Actions

        # Manage File system
        quit = self.get_quit()
        open = self.get_open()
        openfolder = self.get_openfolder()
        start = self.get_startlabel()
        delete = self.get_delete()
        save = self.get_save()
        changesavefolder = self.get_changesavefolder()
        autosaving = self.get_autosaving()
        saveformat = self.get_saveformat()
        openNextImg = self.get_openNextImg()
        openPrevImg = self.get_openPrevImg()

        # Load Settings
        autosaving.setChecked(settings.get(SETTING_AUTO_SAVE, False))
        if settings.get(SETTING_RECENT_FILES):
            self.recentFiles = settings.get(SETTING_RECENT_FILES)

        # Manage Window Zoom
        zoom = self.get_zoom()
        zoomIn = self.get_zoomin()
        zoomOut = self.get_zoomout()
        zoomOrg = self.get_zoomorg()
        fitWindow = self.get_fitwindow()
        fitWidth = self.get_fitwidth()

        # Formats
        voc = self.get_voc()
        yolo = self.get_yolo()
        boxsup = self.get_boxsup()
        boxsupMask = self.get_boxsupMask()

        # Store actions for further handling.
        self.__actions = struct(open=open,
                                openfolder=openfolder,
                                quit=quit,
                                zoom=zoom,
                                zoomIn=zoomIn,
                                zoomOut=zoomOut,
                                zoomOrg=zoomOrg,
                                start=start,
                                fitWindow=fitWindow,
                                fitWidth=fitWidth,
                                autosaving=autosaving,
                                save=save,
                                saveformat=saveformat,
                                changesavefolder=changesavefolder,
                                openNextImg=openNextImg,
                                openPrevImg=openPrevImg,
                                voc=voc,
                                yolo=yolo,
                                boxsup=boxsup,
                                boxsupMask=boxsupMask,
                                fileMenuActions=(open, openfolder, quit),
                                beginner=(),
                                advanced=(),
                                classes=(),
                                editMenu=(start, delete),
                                beginnerContext=(),
                                advancedContext=(),
                                onLoadActive=(start, delete),
                                onShapesPresent=(),
                                zoomActions=(self.zoomWidget, zoomIn, zoomOut,
                                             zoomOrg, fitWindow, fitWidth))

        # Store class Actions
        self.classes = struct(activeClass=None)
        self.create_classes()

        # Create Menus
        self.menus = struct(file=self.menu('&File'),
                            edit=self.menu('&Edit'),
                            view=self.menu('&View'),
                            help=self.menu('&Help'),
                            recentFiles=QMenu('Open &Recent'),
                            formats=QMenu('Change &Formats'))

        # Fill Menus
        addActions(self.menus.file, (
            open,
            openfolder,
            changesavefolder,
            self.menus.recentFiles,
            save,
            self.menus.formats,
            autosaving,
            openNextImg,
            openPrevImg,
            quit,
        ))
        addActions(self.menus.edit, (start, delete))
        addActions(self.menus.view,
                   (zoomIn, zoomOut, zoomOrg, None, fitWindow, fitWidth))
        addActions(self.menus.formats, (voc, yolo, boxsup, boxsupMask))
        # self.autoSaving,
        # self.singleClassMode,
        # self.displayLabelOption,
        # labels, advancedMode, None,
        # hideAll, showAll, None,
        # zoomIn, zoomOut, zoomOrg, None,
        # addActions(self.menus.help, (help, showInfo))

        self.menus.file.aboutToShow.connect(self.updateFileMenu)

        # Create Toolbars
        self.tools = self.toolbar('Tools', position='left')
        self.classtools = self.toolbar('Classes', position='top')
        self.actions.beginner = (open, openfolder, changesavefolder,
                                 saveformat, None, start, None, zoomIn, zoom,
                                 zoomOrg, zoomOut, fitWindow, fitWidth, None,
                                 quit)

        self.actions.classes = self.get_classes()

        addActions(self.tools, self.actions.beginner)
        addActions(self.classtools, self.actions.classes)

        self.statusBar().showMessage('%s started.' % appname)
        self.statusBar().show()

        self.zoomMode = self.MANUAL_ZOOM
        self.scalers = {
            self.FIT_WINDOW:
            self.scaleFitWindow,
            self.FIT_WIDTH:
            self.scaleFitWidth,
            # Set to one to scale to 100% when loading files.
            self.MANUAL_ZOOM:
            lambda: 1,
        }

        # Display cursor coordinates at the right of status bar
        self.labelCoordinates = QLabel('')
        self.statusBar().addPermanentWidget(self.labelCoordinates)

        # Resize and Position Application
        size = settings.get(SETTING_WIN_SIZE, QSize(820, 800))
        position = QPoint(0, 0)
        saved_position = settings.get(SETTING_WIN_POSE, position)
        for i in range(QApplication.desktop().screenCount()):
            desktop = QApplication.desktop().availableGeometry(i)
            if desktop.contains(saved_position):
                position = saved_position
                break
        self.resize(size)
        self.move(position)

        # Load Default Save settings
        LabelDir = settings.get(SETTING_LABEL_DIR, nonePath)
        if LabelDir is None:
            LabelDir = nonePath  # TODO make nonePath pickable
        TemplastOpenFolder = settings.get(SETTING_LAST_OPEN_FOLDER, nonePath)
        if TemplastOpenFolder is None:
            self.lastOpenFolder = nonePath  # TODO make nonePath picklable
        else:
            self.lastOpenFolder = TemplastOpenFolder
        if self.labelFolder is nonePath and LabelDir is not nonePath and \
                LabelDir.exists():
            self.labelFolder = LabelDir
            self.statusBar().showMessage(
                '%s started. Annotation will be saved to %s' %
                (self.appname, self.labelFolder))
            self.statusBar().show()

        self.restoreState(settings.get(SETTING_WIN_STATE, QByteArray()))

        Shape.line_color = self.lineColor = QColor(
            settings.get(SETTING_LINE_COLOR, DEFAULT_LINE_COLOR))
        Shape.fill_color = self.fillColor = QColor(
            settings.get(SETTING_FILL_COLOR, DEFAULT_FILL_COLOR))
        self.canvas.setDrawingColor(self.lineColor)

        self.zoomWidget.valueChanged.connect(self.paintCanvas)