Exemple #1
0
    def __init__(self, defaultFilename=None, defaultPrefdefClassFile=None):
        super(MainWindow, self).__init__()
        self.setWindowTitle(__appname__)

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

        self.defaultSaveDir = None

        # Whether we need to save or not.
        self.dirty = False

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

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

        # File and Notes
        self.noteArea = QPlainTextEdit()
        self.fileListWidget = QListWidget()
        self.fileListWidget.itemDoubleClicked.connect(
            self.fileitemDoubleClicked)
        self.fileNoteLayout = QVBoxLayout()
        self.fileNoteLayout.addWidget(self.fileListWidget)
        self.fileNoteLayout.addWidget(self.noteArea)
        self.fileNoteArea = QWidget()
        self.fileNoteArea.setLayout(self.fileNoteLayout)
        # File and Notes to Dock
        self.fileNoteDock = QDockWidget(u'Files and Notes', self)
        self.fileNoteDock.setObjectName(u'file_note')
        self.fileNoteDock.setWidget(self.fileNoteArea)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.fileNoteDock)

        #First Search
        self.firstText = QLineEdit()
        self.firsrSearchResultArea = QListWidget()
        self.firsrSearchResultArea.itemDoubleClicked.connect(
            self.fileitemDoubleClicked)
        self.firstSearchLayout = QVBoxLayout()
        self.firstSearchLayout.addWidget(self.firstText)
        self.firstSearchLayout.addWidget(self.firsrSearchResultArea)
        self.firstSearchArea = QWidget()
        self.firstSearchArea.setLayout(self.firstSearchLayout)
        #Locode Search
        self.locodeText = QLineEdit()
        self.locodeDataLayout = QFormLayout()
        self.storeKw = QLineEdit()
        self.locodeDataLayout.addRow('Store KeyWord', self.storeKw)
        self.mallKw = QLineEdit()
        self.locodeDataLayout.addRow('Mall KeyWord', self.mallKw)
        self.gstNo = QLineEdit()
        self.locodeDataLayout.addRow('GST NO', self.gstNo)
        self.locodeSearchLayout = QVBoxLayout()
        self.locodeDataArea = QWidget()
        self.locodeDataArea.setLayout(self.locodeDataLayout)
        self.locodeSearchLayout.addWidget(self.locodeText)
        self.locodeSearchLayout.addWidget(self.locodeDataArea)
        self.locodeSearchArea = QWidget()
        self.locodeSearchArea.setLayout(self.locodeSearchLayout)
        # FirstchSearch and LocodeSearch to Doct
        self.inputAreaLayout = QHBoxLayout()
        self.inputAreaLayout.addWidget(self.firstSearchArea)
        self.inputAreaLayout.addWidget(self.locodeSearchArea)
        self.inputArea = QWidget()
        self.inputArea.setLayout(self.inputAreaLayout)
        self.inputDock = QDockWidget(u'Input Area', self)
        self.inputDock.setObjectName(u'input_area')
        self.inputDock.setWidget(self.inputArea)
        self.addDockWidget(Qt.RightDockWidgetArea, self.inputDock)

        #Canvas
        self.zoomWidget = ZoomWidget()
        self.canvas = Canvas(parent=self)
        self.canvas.zoomRequest.connect(self.zoomRequest)
        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.setCentralWidget(scroll)

        # Actions
        action = partial(newAction, self)
        quit = action('&Quit', self.close, 'Ctrl+Q', 'quit',
                      u'Quit application')

        opendir = action('&Open Dir', self.openDirDialog, 'Ctrl+o', 'open',
                         u'Open Dir')

        changeSavedir = action('&Change Save Dir', self.changeSavedirDialog,
                               'Ctrl+r', 'open',
                               u'Change default saved Annotation dir')

        openNextImg = action('&Next Image', self.openNextImg, 'd', 'next',
                             u'Open Next')

        openPrevImg = action('&Prev Image', self.openPrevImg, 'a', 'prev',
                             u'Open Prev')

        saveAs = action('&Save As',
                        self.saveFileAs,
                        'Ctrl+s',
                        'save-as',
                        u'Save labels to a different file',
                        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)
        fitWidth = action('Fit &Width',
                          self.setFitWidth,
                          'Ctrl+Shift+F',
                          'fit-width',
                          u'Zoom follows window width',
                          checkable=True,
                          enabled=False)
        # Group zoom controls into a list for easier toggling.
        zoomActions = (self.zoomWidget, fitWidth)
        self.zoomMode = self.MANUAL_ZOOM
        self.scalers = {
            self.FIT_WIDTH:
            self.scaleFitWidth,
            # Set to one to scale to 100% when loading files.
            self.MANUAL_ZOOM:
            lambda: 1,
        }

        # Store actions for further handling.
        self.actions = struct(saveAs=saveAs,
                              zoom=zoom,
                              fitWidth=fitWidth,
                              zoomActions=zoomActions,
                              fileMenuActions=(open, saveAs, quit))

        self.menus = struct(file=self.menu('&File'),
                            edit=self.menu('&Edit'),
                            view=self.menu('&View'))
        addActions(self.menus.file, (opendir, changeSavedir, saveAs, quit))
        addActions(self.menus.view, (fitWidth, openPrevImg, openNextImg))

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

        # Application state.
        self.image = QImage()
        self.filePath = ustr(defaultFilename)
        self.recentFiles = []
        self.maxRecent = 7
        self.lineColor = None
        self.fillColor = None
        self.zoom_level = 100
        self.fit_window = False
        # Add Chris
        self.difficult = False

        size = settings.get(SETTING_WIN_SIZE, QSize(600, 500))
        position = settings.get(SETTING_WIN_POSE, QPoint(0, 0))
        self.resize(size)
        self.move(position)
        saveDir = ustr(settings.get(SETTING_SAVE_DIR, None))
        self.lastOpenDir = ustr(settings.get(SETTING_LAST_OPEN_DIR, None))
        if 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()))
        print self.filePath
        # Since loading the file may take some time, make sure it runs in the background.
        if self.filePath and os.path.isdir(self.filePath):
            self.queueEvent(partial(self.importDirImages, self.filePath or ""))
        elif self.filePath:
            self.queueEvent(partial(self.loadFile, self.filePath or ""))

        # Callbacks:
        self.zoomWidget.valueChanged.connect(self.paintCanvas)

        # Display cursor coordinates at the right of status bar
        self.labelCoordinates = QLabel('')
        self.statusBar().addPermanentWidget(self.labelCoordinates)
        # Open Dir if deafult file
        if self.filePath and os.path.isdir(self.filePath):
            self.openDirDialog(dirpath=self.filePath)
Exemple #2
0
    def __init__(self):
        QWidget.__init__(self)

        # self.setFixedSize(800, 600)
        # self.descisionDlg = ouput(self)
        self.setWindowTitle("Label Master")
        self.labelCoordinates = QLabel('')
        self.statusBar().addPermanentWidget(self.labelCoordinates)
        # intit
        self.cvMat = None
        self.qImage = None
        self.dirty = False
        self.saveFolder = None
        self.filePath = None
        self.lastOpenDir = None
        self.mImgList = []
        self.prevLabel = "Enter object label"
        self.bLoopImplement = True
        self.bAutoImplement = False
        self.bSaveOutput = False
        self.bShowResult = True
        self.bSelectionChanged = False
        self.pool = Pool(5)
        self.output = []
        self.bEndThreads = []
        self.t0 = 0

        # self.stringBundle = StringBundle.getBundle()
        # getStr = lambda strId: self.stringBundle.getString(strId)

        self.labelDialog = LabelDialog(listItem=listLabel)
        self.colorDialog = ColorDialog(parent=self)
        self.lineColor = None
        self.textColor = None

        self.itemsToShapes = {}
        self.shapesToItems = {}
        self._noSelectionSlot = []
        self._beginner = True

        self.statusBar().showMessage('%s' % __appname__)
        # self.statusBar().show()
        #============ menu=========
        self.menus = struct(file=self.menu('&File'),
                            edit=self.menu('&Edit'),
                            view=self.menu('&View'),
                            help=self.menu('&Help'),
                            labelList=QMenu(),
                            fileLog=QMenu())

        #================init UI ==============
        action = partial(newAction, self)

        #=======toolBar==========
        openFile = action("Open", self.open, OPEN_FILE, "res/open.png",
                          "Open image file")
        openDir = action("Open Dir", self.openDirDialog, OPEN_DIR,
                         "res/openDir.png", "Open image folder")
        createShape = action("Create rect box", self.createShape, CREATE,
                             "res/draw.png", "Start draw rectangle")
        createPolygon = action("Create polygon", self.createPolygon, POLYGON,
                               "res/polygon.png", "Start draw polygon")
        copy = action('copy',
                      self.copySelectedShape,
                      COPY,
                      'res/copy.png',
                      'dupBoxDetail',
                      enabled=False)
        saveFile = action("Save", self.save, SAVE, "res/save.png",
                          "Save parameters")
        editLabel = action("Edit label",
                           self.editLabel,
                           EDIT,
                           "res/edit.png",
                           "Editting label",
                           enabled=False)
        deleteShape = action("Delete shape",
                             self.deleteSelectedShape,
                             DLETE,
                             "res/delete.png",
                             "Delete shape selected",
                             enabled=False)
        implement = action("Implement",
                           self.implement,
                           IMPLEMENT,
                           "res/event.png",
                           "Implement",
                           enabled=False)
        lineColor = action("Line color",
                           lambda: self.boxColor("line"),
                           LINE_COLOR,
                           "res/lineColor.png",
                           "Box line color",
                           enabled=True)
        textColor = action("Text color",
                           lambda: self.boxColor("text"),
                           TEXT_COLOR,
                           "res/textColor.png",
                           "Box text color",
                           enabled=True)
        font = action("Font",
                      self.boxFont,
                      TEXT_FONT,
                      "res/font.png",
                      "Box font text",
                      enabled=True)
        nextImage = action("Next Image",
                           self.openNextImg,
                           NEXT,
                           "res/next.png",
                           "Next image",
                           enabled=True)
        backImage = action("Back Image",
                           self.openPrevImg,
                           BACK,
                           "res/back.png",
                           "Back image",
                           enabled=True)
        zoomIn = action('zoomin',
                        partial(self.addZoom, 10),
                        ZOOM_IN,
                        'res/zoom-in.png',
                        'zoominDetail',
                        enabled=False)
        zoomOut = action('zoomout',
                         partial(self.addZoom, -10),
                         ZOOM_OUT,
                         'res/zoom-out.png',
                         'zoomoutDetail',
                         enabled=False)
        zoomOrg = action('originalsize',
                         partial(self.setZoom, 100),
                         ZOOM_ORG,
                         'res/zoom.png',
                         'originalsizeDetail',
                         enabled=False)
        fitWindow = action('fitWin',
                           self.setFitWindow,
                           FIT_WINDOW,
                           'res/fit-window.png',
                           'fitWinDetail',
                           checkable=True,
                           enabled=False)
        fitWidth = action('fitWidth',
                          self.setFitWidth,
                          FIT_WIDTH,
                          'res/fit-width.png',
                          'fitWidthDetail',
                          checkable=True,
                          enabled=False)
        clearAll = action('clearAll',
                          self.clearList,
                          CLEAR_ALL,
                          'res/clear-all.png',
                          'Clear all list items',
                          checkable=True,
                          enabled=True)

        showCamera = action('camera',
                            self.showCamera,
                            SHOW_CAMERA,
                            'res/camera2.png',
                            'Camera',
                            checkable=True,
                            enabled=True)

        actionMenuFile = [openFile, openDir, saveFile]
        addActions(self.menus.file, actionMenuFile)

        actionMenuEdit = [
            createShape, implement, editLabel, copy, lineColor, textColor,
            font, deleteShape
        ]
        addActions(self.menus.edit, actionMenuEdit)

        actionToolbar = (openFile, openDir, saveFile, createShape,
                         createPolygon, editLabel, implement, nextImage,
                         backImage)
        self.toolbar("Tools", actions=actionToolbar)

        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)

        # Group zoom controls into a list for easier toggling.
        beginner = (implement, editLabel, copy, deleteShape)
        self.actions = struct(openFile=openFile,
                              openDir=openDir,
                              saveFile=saveFile,
                              createShape=createShape,
                              createPolygon=createPolygon,
                              editLabel=editLabel,
                              deleteShape=deleteShape,
                              copy=copy,
                              implement=implement,
                              lineColor=lineColor,
                              textColor=textColor,
                              font=font,
                              nextImage=nextImage,
                              backImage=backImage,
                              zoomIn=zoomIn,
                              zoomOut=zoomOut,
                              zoomOrg=zoomOrg,
                              fitWidth=fitWidth,
                              fitWindow=fitWindow,
                              beginner=beginner,
                              clearAll=clearAll)

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

        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,
        }
        listLayout = QVBoxLayout()
        listLayout.setContentsMargins(0, 0, 0, 0)

        # Create a widget for using default label
        self.useDefaultLabelCheckbox = QCheckBox('useDefaultLabel')
        self.useDefaultLabelCheckbox.setChecked(False)

        self.defaultLabelTextLine = QLineEdit()

        self.autoImplement = QCheckBox('autoImplement')
        self.autoImplement.setChecked(False)

        self.saveOutput = QCheckBox('saveOutput')
        self.saveOutput.setChecked(False)

        self.updateOuput = QCheckBox('showOutput')
        self.updateOuput.setChecked(True)

        self.autoImplement.stateChanged.connect(self.stateChanged)
        self.saveOutput.stateChanged.connect(self.stateChanged)
        self.updateOuput.stateChanged.connect(self.stateChanged)

        useDefaultLabelQHBoxLayout = QVBoxLayout()
        useDefaultLabelQHBoxLayout.addWidget(self.useDefaultLabelCheckbox)
        useDefaultLabelQHBoxLayout.addWidget(self.defaultLabelTextLine)
        useDefaultLabelQHBoxLayout.addWidget(self.saveOutput)
        useDefaultLabelQHBoxLayout.addWidget(self.updateOuput)
        useDefaultLabelQHBoxLayout.addWidget(self.autoImplement)

        useDefaultLabelContainer = QWidget()
        useDefaultLabelContainer.setLayout(useDefaultLabelQHBoxLayout)

        # Create a widget for edit and diffc buttonp
        self.editButton = QToolButton()
        self.editButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        self.editButton.setDefaultAction(editLabel)

        self.implementButton = QToolButton()
        self.implementButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        self.implementButton.setDefaultAction(implement)

        buttonLayout = QHBoxLayout()
        buttonLayout.setContentsMargins(0, 0, 0, 0)

        # Add some of widgets to listLayout
        buttonLayout.addWidget(self.editButton)
        buttonLayout.addWidget(self.implementButton)
        listLayout.addLayout(buttonLayout)

        listLayout.addWidget(useDefaultLabelContainer)

        # Create and add a dock widget for showing current label items
        self.labelList = QListWidget()
        addActions(self.menus.labelList, (editLabel, deleteShape))
        self.labelList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.labelList.customContextMenuRequested.connect(
            self.popLabelListMenu)
        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)

        labelListContainer = QWidget()
        labelListContainer.setLayout(listLayout)

        self.fileLogWidget = QListWidget()
        addActions(self.menus.fileLog, [clearAll])
        self.fileLogWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.fileLogWidget.customContextMenuRequested.connect(
            self.popfileLogMenu)
        self.fileLogWidget.itemDoubleClicked.connect(
            self.fileitemDoubleClicked)
        # self.fileLogWidget.itemChanged.connect(self.fileLogRowChanged)
        fileLogLayout = QVBoxLayout()
        fileLogLayout.setContentsMargins(0, 0, 0, 0)
        fileLogLayout.addWidget(self.fileLogWidget)
        fileLogContainer = QWidget()
        fileLogContainer.setLayout(fileLogLayout)

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

        self.filedock = QDockWidget('fileLog', self)
        self.filedock.setObjectName('files')
        self.filedock.setWidget(fileLogContainer)

        self.parameterdock = QDockWidget('paramsVision', self)
        self.parameterdock.setObjectName('params')
        self.paramerterWidget = ParamerterDialog(self)
        # self.paramerterWidget.ln_kThresh.textChanged.connect(self.textChanged)
        self.parameterdock.setWidget(self.paramerterWidget)

        # self.cameradock = QDockWidget('camera', self)
        # self.cameradock.setObjectName('cameara')
        # self.cameraDlg = cameraDialog(self)
        # self.cameradock.setWidget(self.cameraDlg)

        self.addDockWidget(Qt.RightDockWidgetArea, self.dock)
        self.dockFeatures = QDockWidget.DockWidgetClosable | QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable
        # self.dock.setFeatures(self.dock.features() ^ self.dockFeatures)
        self.dock.setFeatures(self.dockFeatures)

        self.addDockWidget(Qt.RightDockWidgetArea, self.filedock)
        self.filedock.setFeatures(self.dockFeatures)

        self.addDockWidget(Qt.RightDockWidgetArea, self.parameterdock)
        self.parameterdock.setFeatures(self.dockFeatures)

        # self.addDockWidget(Qt.RightDockWidgetArea, self.cameradock)
        # self.cameradock.setFeatures(self.dockFeatures)

        toggleDock = self.dock.toggleViewAction()
        toggleDock.setText('boxLabel')
        toggleDock.setShortcut(TOGGLE_LABEL_LIST)

        toggleFileDock = self.filedock.toggleViewAction()
        toggleFileDock.setText('logFile')
        toggleFileDock.setShortcut(TOGGLE_LOG_FILE)

        toggleParaDock = self.parameterdock.toggleViewAction()
        toggleParaDock.setText('parameter')
        toggleParaDock.setShortcut(TOGGLE_PARAMETER)

        # toggleCamDock = self.cameradock.toggleViewAction()
        # toggleCamDock.setText('camera')
        # toggleCamDock.setShortcut(TOGGLE_SHOW_CAMERA)

        # self.dock.hide()
        self.filedock.hide()
        self.parameterdock.hide()
        # self.cameradock.hide()

        addActions(self.menus.view,
                   [toggleDock, toggleFileDock, toggleParaDock, showCamera])

        # ==============Canvas================
        self.canvas = Canvas(self)
        # load params
        self.loadParams()
        # contextMenu
        addActions(self.canvas.menus[0], self.actions.beginner)
        #=================
        qImage = QImage(640, 480, QImage.Format_RGBA8888)
        self.canvas.loadPixmap(QPixmap.fromImage(qImage))

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

        #signal Canvas
        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.zoomRequest.connect(self.zoomRequest)
        self.canvas.drawingPolygon.connect(self.toggleDrawingSensitive)

        self.setCentralWidget(scroll)

        self.fitState()
        #
        # ==============================

        palette = self.palette()
        role = self.backgroundRole()
        palette.setColor(role, QColor(200, 232, 232, 255))
        self.setPalette(palette)

        palette = self.canvas.palette()
        role = self.canvas.backgroundRole()
        palette.setColor(role, QColor(200, 232, 232, 255))
        self.canvas.setPalette(palette)

        #==start thead implement
        self.myThread(target=self.loopImplement, args=())
Exemple #3
0
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setWindowTitle(__appname__)

        self.settings = Settings()
        self.settings.load()
        settings = self.settings

        # init annotation dir
        self.annotDir = None

        # init image dir, wait to be set by user in self.loadImagefolder
        self.imageDir = None

        self.zoomWidget = ZoomWidget()
        scroll = QScrollArea()
        self.canvas = Canvas()
        self.setCentralWidget(self.canvas)

        # add scroll widget
        scroll = QScrollArea()
        scroll.setWidget(self.canvas)
        scroll.setWidgetResizable(True)
        self.setCentralWidget(scroll)
        self.canvas.resize(self.canvas.sizeHint())

        # add and populate menubar
        bar = self.menuBar()
        file = bar.addMenu("File")
        loadDir = QAction("Open Image Folder", self)
        loadAnnotDir = QAction("Open Annotation Folder", self)
        save = QAction("Save Annotation", self)
        save.setShortcut('Ctrl+S')
        quit = QAction("Close Annotator", self)

        file.addAction(loadDir)
        file.addAction(loadAnnotDir)
        file.addAction(save)
        file.addAction(quit)

        # set actions
        loadDir.triggered.connect(self.loadImageFolder)
        loadAnnotDir.triggered.connect(self.loadAnnotFolder)
        save.triggered.connect(self.save)
        # load.triggered.connect(self.canvas.load)
        quit.triggered.connect(self.quitApp)

        self.loadedFiles = []

        # add navigation sidebar
        self.items = QDockWidget("Annotations", self)
        self.annotList = QListWidget()
        self.annotList.itemActivated.connect(self.updateActivatedAnnotation)
        self.items.setWidget(self.annotList)
        self.items.setFloating(False)
        self.addDockWidget(Qt.RightDockWidgetArea, self.items)

        size = settings.get(SETTING_WIN_SIZE, QSize(640, 480))
        position = settings.get(SETTING_WIN_POSE, QPoint(0, 0))
        self.resize(size)
        self.move(position)

        self.queueEvent(self.loadImage)
Exemple #4
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)
Exemple #5
0
    def __init__(self, defaultFilename=None, defaultPrefdefClassFile=None):
        super(MainWindow, self).__init__()

        self.setWindowTitle(__appname__)
        self.defaultSaveDir = None
        self.usingPascalVocFormat = True
        self.mImgList = []
        self.dirname = None
        self.labelHist = []
        self.lastOpenDir = None
        self.dirty = False
        self._noSelectionSlot = False
        self._beginner = True

        self.screencastViewer = "firefox"
        self.screencast = "https://www.youtube.com/?gl=UA&hl=ru"

        self.loadPredefinedClasses(defaultPrefdefClassFile)
        self.labelDialog = LabelDialog(parent=self, listItem=self.labelHist)

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

        listLayout = QVBoxLayout()
        listLayout.setContentsMargins(0, 0, 0, 0)

        self.useDefaultLabelCheckbox = QCheckBox(u'Default label')
        self.useDefaultLabelCheckbox.setChecked(True)
        self.defaultLabelTextLine = QLineEdit('Object')

        useDefaultLabelQHBoxLayout = QHBoxLayout()
        useDefaultLabelQHBoxLayout.addWidget(self.useDefaultLabelCheckbox)
        useDefaultLabelQHBoxLayout.addWidget(self.defaultLabelTextLine)
        useDefaultLabelContainer = QWidget()
        useDefaultLabelContainer.setLayout(useDefaultLabelQHBoxLayout)

        self.editButton = QToolButton()
        self.editButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)

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

        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)

        self.labelList.itemChanged.connect(self.labelItemChanged)

        listLayout.addWidget(self.labelList)

        self.dock = QDockWidget(u'Label List', self)
        self.dock.setObjectName(u'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(u'File List', self)
        self.filedock.setObjectName(u'Files')
        self.filedock.setWidget(fileListContainer)

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

        self.canvas = Canvas()
        self.canvas.zoomRequest.connect(self.zoomRequest)

        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.dockFeatures = QDockWidget.DockWidgetClosable | QDockWidget.DockWidgetFloatable
        self.dock.setFeatures(self.dock.features() ^ self.dockFeatures)

        action = partial(newAction, self)

        open = action('&Open Image', self.openFile, 'I', 'open',
                      u'Open image file')

        opendir = action('&Open Folder', self.openDir, 'F', 'open',
                         u'Open directory')

        openNextImg = action('&Next Image', self.openNextImg, 'D', 'next',
                             u'Open next image')

        openPrevImg = action('&Previous Image', self.openPrevImg, 'A', 'prev',
                             u'Open previous image')

        save = action('&Save Label',
                      self.saveFile,
                      'S',
                      'save',
                      u'Save labels to file',
                      enabled=False)

        createMode = action('Create Label',
                            self.setCreateMode,
                            'W',
                            'new',
                            u'Create new label',
                            enabled=False)

        editMode = action('&Edit Label',
                          self.setEditMode,
                          'E',
                          'edit',
                          u'Move and edit label',
                          enabled=False)

        delete = action('Delete label',
                        self.deleteSelectedShape,
                        'Delete',
                        'delete',
                        u'Delete label',
                        enabled=False)

        advancedMode = action('&Advanced Mode',
                              self.toggleAdvancedMode,
                              'Ctrl+Shift+A',
                              'expert',
                              u'Switch to advanced mode',
                              checkable=True)

        help = action('&Tutorial', self.tutorial, 'T', 'help',
                      u'Show demo video')

        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('Zoom &In',
                        partial(self.addZoom, 10),
                        'Ctrl++',
                        'zoom-in',
                        u'Increase zoom level',
                        enabled=False)

        zoomOut = action('&Zoom Out',
                         partial(self.addZoom, -10),
                         'Ctrl+-',
                         'zoom-out',
                         u'Decrease zoom level',
                         enabled=False)

        zoomOrg = action('&Original size',
                         partial(self.setZoom, 100),
                         'Ctrl+=',
                         'zoom',
                         u'Zoom to original size',
                         enabled=False)

        fitWindow = action('&Fit Window',
                           self.setFitWindow,
                           'Ctrl+F',
                           'fit-window',
                           u'Zoom follows window size',
                           checkable=True,
                           enabled=False)

        fitWidth = action('Fit &Width',
                          self.setFitWidth,
                          'Ctrl+Shift+F',
                          'fit-width',
                          u'Zoom follows window width',
                          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,
        }

        edit = action('&Edit Label',
                      self.editLabel,
                      'Ctrl+E',
                      'edit',
                      u'Modify the label of the selected Box',
                      enabled=False)

        self.editButton.setDefaultAction(edit)

        shapeLineColor = action(
            'Shape &Line Color',
            self.chshapeLineColor,
            icon='color_line',
            tip=u'Change the line color for this specific shape',
            enabled=False)

        shapeFillColor = action(
            'Shape &Fill Color',
            self.chshapeFillColor,
            icon='color',
            tip=u'Change the fill color for this specific shape',
            enabled=False)

        labels = self.dock.toggleViewAction()

        labels.setText('Label Panel')
        labels.setShortcut('Ctrl+Shift+L')

        files = self.filedock.toggleViewAction()
        files.setText('File Panel')
        files.setShortcut('Ctrl+Shift+F')

        labelMenu = QMenu()
        addActions(labelMenu, (edit, delete))

        self.labelList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.labelList.customContextMenuRequested.connect(
            self.popLabelListMenu)

        self.actions = struct(save=save,
                              open=open,
                              create=createMode,
                              delete=delete,
                              edit=edit,
                              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),
                              beginner=(),
                              advanced=(),
                              editMenu=(edit, delete),
                              beginnerContext=(edit, delete),
                              advancedContext=(save, createMode, editMode),
                              onLoadActive=(createMode, editMode))

        self.menus = struct(file=self.menu('&File'),
                            edit=self.menu('&Edit'),
                            view=self.menu('&View'),
                            help=self.menu('&Help'),
                            recentFiles=QMenu('Open &Recent'),
                            labelList=labelMenu)

        self.autoSaving = QAction("Auto Saving", self)
        self.autoSaving.setCheckable(True)

        self.singleClassMode = QAction("Single Class Mode", self)
        self.singleClassMode.setShortcut("Ctrl+Shift+S")
        self.singleClassMode.setCheckable(True)
        self.lastLabel = None

        addActions(self.menus.file, (open, opendir, openNextImg, openPrevImg))
        addActions(self.menus.help, (help, ))
        addActions(self.menus.view, (labels, files, zoomIn, zoomOut))

        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.advanced = (None, open, opendir, None, openNextImg,
                                 openPrevImg, None, save, createMode, editMode,
                                 None, zoomIn, zoomOut, None)

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

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

        self.settings = Settings()
        self.settings.load()

        settings = self.settings

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

        size = settings.get(SETTING_WIN_SIZE, QSize(300, 500))
        position = settings.get(SETTING_WIN_POSE, QPoint(0, 0))

        self.resize(size)
        self.move(position)

        saveDir = ustr(settings.get(SETTING_SAVE_DIR, None))

        self.lastOpenDir = ustr(settings.get(SETTING_LAST_OPEN_DIR, None))

        if 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()))
        self.lineColor = QColor(
            settings.get(SETTING_LINE_COLOR, Shape.line_color))
        self.fillColor = QColor(
            settings.get(SETTING_FILL_COLOR, Shape.fill_color))

        Shape.line_color = self.lineColor
        Shape.fill_color = self.fillColor
        Shape.difficult = self.difficult

        def xbool(x):
            if isinstance(x, QVariant):
                return x.toBool()

            return bool(x)

        if xbool(settings.get(SETTING_ADVANCE_MODE, False)):
            self.actions.advancedMode.setChecked(True)
            self.toggleAdvancedMode()

        self.updateFileMenu()
        self.queueEvent(partial(self.loadFile, self.filePath or ""))
        self.zoomWidget.valueChanged.connect(self.paintCanvas)
        self.populateModeActions()
Exemple #6
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()
        }
Exemple #7
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)
Exemple #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)
Exemple #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)