From 923e98202bf40a92110edf2b7c8b9dcba3258783 Mon Sep 17 00:00:00 2001 From: Cerno_b Date: Mon, 8 Mar 2021 00:46:55 +0100 Subject: [PATCH 01/13] rename local variables in main file --- labelImg.py | 388 ++++++++++++++++++++++++++-------------------------- 1 file changed, 194 insertions(+), 194 deletions(-) diff --git a/labelImg.py b/labelImg.py index 739c7f092..a246b31e1 100755 --- a/labelImg.py +++ b/labelImg.py @@ -115,18 +115,18 @@ def __init__(self, defaultFilename=None, defaultPrefdefClassFile=None, defaultSa self.shapesToItems = {} self.prevLabelText = '' - listLayout = QVBoxLayout() - listLayout.setContentsMargins(0, 0, 0, 0) + list_layout = QVBoxLayout() + list_layout.setContentsMargins(0, 0, 0, 0) # Create a widget for using default label self.useDefaultLabelCheckbox = QCheckBox(getStr('useDefaultLabel')) self.useDefaultLabelCheckbox.setChecked(False) self.defaultLabelTextLine = QLineEdit() - useDefaultLabelQHBoxLayout = QHBoxLayout() - useDefaultLabelQHBoxLayout.addWidget(self.useDefaultLabelCheckbox) - useDefaultLabelQHBoxLayout.addWidget(self.defaultLabelTextLine) - useDefaultLabelContainer = QWidget() - useDefaultLabelContainer.setLayout(useDefaultLabelQHBoxLayout) + use_default_label_qhbox_layout = QHBoxLayout() + use_default_label_qhbox_layout.addWidget(self.useDefaultLabelCheckbox) + use_default_label_qhbox_layout.addWidget(self.defaultLabelTextLine) + use_default_label_container = QWidget() + use_default_label_container.setLayout(use_default_label_qhbox_layout) # Create a widget for edit and diffc button self.diffcButton = QCheckBox(getStr('useDifficult')) @@ -135,42 +135,42 @@ def __init__(self, defaultFilename=None, defaultPrefdefClassFile=None, defaultSa self.editButton = QToolButton() self.editButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) - # Add some of widgets to listLayout - listLayout.addWidget(self.editButton) - listLayout.addWidget(self.diffcButton) - listLayout.addWidget(useDefaultLabelContainer) + # Add some of widgets to list_layout + list_layout.addWidget(self.editButton) + list_layout.addWidget(self.diffcButton) + list_layout.addWidget(use_default_label_container) # Create and add combobox for showing unique labels in group self.comboBox = ComboBox(self) - listLayout.addWidget(self.comboBox) + list_layout.addWidget(self.comboBox) # Create and add a widget for showing current label items self.labelList = QListWidget() - labelListContainer = QWidget() - labelListContainer.setLayout(listLayout) + label_list_container = QWidget() + label_list_container.setLayout(list_layout) 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) + list_layout.addWidget(self.labelList) self.dock = QDockWidget(getStr('boxLabelText'), self) self.dock.setObjectName(getStr('labels')) - self.dock.setWidget(labelListContainer) + self.dock.setWidget(label_list_container) 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) + file_list_layout = QVBoxLayout() + file_list_layout.setContentsMargins(0, 0, 0, 0) + file_list_layout.addWidget(self.fileListWidget) + file_list_container = QWidget() + file_list_container.setLayout(file_list_layout) self.filedock = QDockWidget(getStr('fileList'), self) self.filedock.setObjectName(getStr('files')) - self.filedock.setWidget(fileListContainer) + self.filedock.setWidget(file_list_container) self.zoomWidget = ZoomWidget() self.colorDialog = ColorDialog(parent=self) @@ -213,19 +213,19 @@ def __init__(self, defaultFilename=None, defaultPrefdefClassFile=None, defaultSa opendir = action(getStr('openDir'), self.openDirDialog, 'Ctrl+u', 'open', getStr('openDir')) - copyPrevBounding = action(getStr('copyPrevBounding'), self.copyPreviousBoundingBoxes, + copy_prev_bounding = action(getStr('copyPrevBounding'), self.copyPreviousBoundingBoxes, 'Ctrl+v', 'paste', getStr('copyPrevBounding')) - changeSavedir = action(getStr('changeSaveDir'), self.changeSavedirDialog, + change_save_dir = action(getStr('changeSaveDir'), self.changeSavedirDialog, 'Ctrl+r', 'open', getStr('changeSavedAnnotationDir')) - openAnnotation = action(getStr('openAnnotation'), self.openAnnotationDialog, + open_annotation = action(getStr('openAnnotation'), self.openAnnotationDialog, 'Ctrl+Shift+O', 'open', getStr('openAnnotationDetail')) - openNextImg = action(getStr('nextImg'), self.openNextImg, + open_next_image = action(getStr('nextImg'), self.openNextImg, 'd', 'next', getStr('nextImgDetail')) - openPrevImg = action(getStr('prevImg'), self.openPrevImg, + open_prev_image = action(getStr('prevImg'), self.openPrevImg, 'a', 'prev', getStr('prevImgDetail')) verify = action(getStr('verifyImg'), self.verifyImg, @@ -250,21 +250,21 @@ def getFormatMeta(format): getFormatMeta(self.labelFileFormat)[1], getStr('changeSaveFormat'), enabled=True) - saveAs = action(getStr('saveAs'), self.saveFileAs, + save_as = 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+Shift+D', 'close', getStr('deleteImgDetail')) + delete_image = action(getStr('deleteImg'), self.deleteImg, 'Ctrl+Shift+D', 'close', getStr('deleteImgDetail')) - resetAll = action(getStr('resetAll'), self.resetAll, None, 'resetall', getStr('resetAllDetail')) + reset_all = 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, + create_mode = action(getStr('crtBox'), self.setCreateMode, 'w', 'new', getStr('crtBoxDetail'), enabled=False) - editMode = action('&Edit\nRectBox', self.setEditMode, + edit_mode = action('&Edit\nRectBox', self.setEditMode, 'Ctrl+J', 'edit', u'Move and edit Boxs', enabled=False) create = action(getStr('crtBox'), self.createShape, @@ -275,19 +275,19 @@ def getFormatMeta(format): 'Ctrl+D', 'copy', getStr('dupBoxDetail'), enabled=False) - advancedMode = action(getStr('advancedMode'), self.toggleAdvancedMode, + advanced_mode = action(getStr('advancedMode'), self.toggleAdvancedMode, 'Ctrl+Shift+A', 'expert', getStr('advancedModeDetail'), checkable=True) - hideAll = action('&Hide\nRectBox', partial(self.togglePolygons, False), + hide_all = action('&Hide\nRectBox', partial(self.togglePolygons, False), 'Ctrl+H', 'hide', getStr('hideAllBoxDetail'), enabled=False) - showAll = action('&Show\nRectBox', partial(self.togglePolygons, True), + show_all = 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')) + show_info = action(getStr('info'), self.showInfoDialog, None, 'help', getStr('info')) zoom = QWidgetAction(self) zoom.setDefaultWidget(self.zoomWidget) @@ -297,21 +297,21 @@ def getFormatMeta(format): fmtShortcut("Ctrl+Wheel"))) self.zoomWidget.setEnabled(False) - zoomIn = action(getStr('zoomin'), partial(self.addZoom, 10), + zoom_in = action(getStr('zoomin'), partial(self.addZoom, 10), 'Ctrl++', 'zoom-in', getStr('zoominDetail'), enabled=False) - zoomOut = action(getStr('zoomout'), partial(self.addZoom, -10), + zoom_out = action(getStr('zoomout'), partial(self.addZoom, -10), 'Ctrl+-', 'zoom-out', getStr('zoomoutDetail'), enabled=False) - zoomOrg = action(getStr('originalsize'), partial(self.setZoom, 100), + zoom_org = action(getStr('originalsize'), partial(self.setZoom, 100), 'Ctrl+=', 'zoom', getStr('originalsizeDetail'), enabled=False) - fitWindow = action(getStr('fitWin'), self.setFitWindow, + fit_window = action(getStr('fitWin'), self.setFitWindow, 'Ctrl+F', 'fit-window', getStr('fitWinDetail'), checkable=True, enabled=False) - fitWidth = action(getStr('fitWidth'), self.setFitWidth, + fit_width = 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) + zoom_actions = (self.zoomWidget, zoom_in, zoom_out, + zoom_org, fit_window, fit_width) self.zoomMode = self.MANUAL_ZOOM self.scalers = { self.FIT_WINDOW: self.scaleFitWindow, @@ -325,10 +325,10 @@ def getFormatMeta(format): enabled=False) self.editButton.setDefaultAction(edit) - shapeLineColor = action(getStr('shapeLineColor'), self.chshapeLineColor, + shape_line_color = action(getStr('shapeLineColor'), self.chshapeLineColor, icon='color_line', tip=getStr('shapeLineColorDetail'), enabled=False) - shapeFillColor = action(getStr('shapeFillColor'), self.chshapeFillColor, + shape_fill_color = action(getStr('shapeFillColor'), self.chshapeFillColor, icon='color', tip=getStr('shapeFillColorDetail'), enabled=False) @@ -337,8 +337,8 @@ def getFormatMeta(format): labels.setShortcut('Ctrl+Shift+L') # Label list context menu. - labelMenu = QMenu() - addActions(labelMenu, (edit, delete)) + label_menu = QMenu() + addActions(label_menu, (edit, delete)) self.labelList.setContextMenuPolicy(Qt.CustomContextMenu) self.labelList.customContextMenuRequested.connect( self.popLabelListMenu) @@ -351,24 +351,24 @@ def getFormatMeta(format): self.drawSquaresOption.triggered.connect(self.toogleDrawSquare) # Store actions for further handling. - self.actions = struct(save=save, save_format=save_format, saveAs=saveAs, open=open, close=close, resetAll = resetAll, deleteImg = deleteImg, + self.actions = struct(save=save, save_format=save_format, saveAs=save_as, open=open, close=close, resetAll = reset_all, deleteImg = delete_image, 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, + createMode=create_mode, editMode=edit_mode, advancedMode=advanced_mode, + shapeLineColor=shape_line_color, shapeFillColor=shape_fill_color, + zoom=zoom, zoomIn=zoom_in, zoomOut=zoom_out, zoomOrg=zoom_org, + fitWindow=fit_window, fitWidth=fit_width, + zoomActions=zoom_actions, fileMenuActions=( - open, opendir, save, saveAs, close, resetAll, quit), + open, opendir, save, save_as, close, reset_all, quit), beginner=(), advanced=(), editMenu=(edit, copy, delete, None, color1, self.drawSquaresOption), beginnerContext=(create, edit, copy, delete), - advancedContext=(createMode, editMode, edit, copy, - delete, shapeLineColor, shapeFillColor), + advancedContext=(create_mode, edit_mode, edit, copy, + delete, shape_line_color, shape_fill_color), onLoadActive=( - close, create, createMode, editMode), - onShapesPresent=(saveAs, hideAll, showAll)) + close, create, create_mode, edit_mode), + onShapesPresent=(save_as, hide_all, show_all)) self.menus = struct( file=self.menu(getStr('menu_file')), @@ -376,7 +376,7 @@ def getFormatMeta(format): view=self.menu(getStr('menu_view')), help=self.menu(getStr('menu_help')), recentFiles=QMenu(getStr('menu_openRecent')), - labelList=labelMenu) + labelList=label_menu) # Auto saving : Enable auto saving if pressing next self.autoSaving = QAction(getStr('autoSaveMode'), self) @@ -396,16 +396,16 @@ def getFormatMeta(format): self.displayLabelOption.triggered.connect(self.togglePaintLabelsOption) addActions(self.menus.file, - (open, opendir, copyPrevBounding, changeSavedir, openAnnotation, self.menus.recentFiles, save, save_format, saveAs, close, resetAll, deleteImg, quit)) - addActions(self.menus.help, (help, showInfo)) + (open, opendir, copy_prev_bounding, change_save_dir, open_annotation, self.menus.recentFiles, save, save_format, save_as, close, reset_all, delete_image, quit)) + addActions(self.menus.help, (help, show_info)) addActions(self.menus.view, ( self.autoSaving, self.singleClassMode, self.displayLabelOption, - labels, advancedMode, None, - hideAll, showAll, None, - zoomIn, zoomOut, zoomOrg, None, - fitWindow, fitWidth)) + labels, advanced_mode, None, + hide_all, show_all, None, + zoom_in, zoom_out, zoom_org, None, + fit_window, fit_width)) self.menus.file.aboutToShow.connect(self.updateFileMenu) @@ -417,13 +417,13 @@ def getFormatMeta(format): self.tools = self.toolbar('Tools') self.actions.beginner = ( - open, opendir, changeSavedir, openNextImg, openPrevImg, verify, save, save_format, None, create, copy, delete, None, - zoomIn, zoom, zoomOut, fitWindow, fitWidth) + open, opendir, change_save_dir, open_next_image, open_prev_image, verify, save, save_format, None, create, copy, delete, None, + zoom_in, zoom, zoom_out, fit_window, fit_width) self.actions.advanced = ( - open, opendir, changeSavedir, openNextImg, openPrevImg, save, save_format, None, - createMode, editMode, None, - hideAll, showAll) + open, opendir, change_save_dir, open_next_image, open_prev_image, save, save_format, None, + create_mode, edit_mode, None, + hide_all, show_all) self.statusBar().showMessage('%s started.' % __appname__) self.statusBar().show() @@ -444,10 +444,10 @@ def getFormatMeta(format): ## Fix the compatible issue for qt4 and qt5. Convert the QStringList to python list if settings.get(SETTING_RECENT_FILES): if have_qstring(): - recentFileQStringList = settings.get(SETTING_RECENT_FILES) - self.recentFiles = [ustr(i) for i in recentFileQStringList] + recent_file_qstring_list = settings.get(SETTING_RECENT_FILES) + self.recentFiles = [ustr(i) for i in recent_file_qstring_list] else: - self.recentFiles = recentFileQStringList = settings.get(SETTING_RECENT_FILES) + self.recentFiles = recent_file_qstring_list = settings.get(SETTING_RECENT_FILES) size = settings.get(SETTING_WIN_SIZE, QSize(600, 500)) position = QPoint(0, 0) @@ -459,10 +459,10 @@ def getFormatMeta(format): break self.resize(size) self.move(position) - saveDir = ustr(settings.get(SETTING_SAVE_DIR, None)) + save_dir = ustr(settings.get(SETTING_SAVE_DIR, None)) self.lastOpenDir = ustr(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 + if self.defaultSaveDir is None and save_dir is not None and os.path.exists(save_dir): + self.defaultSaveDir = save_dir self.statusBar().showMessage('%s started. Annotation will be saved to %s' % (__appname__, self.defaultSaveDir)) self.statusBar().show() @@ -683,14 +683,14 @@ def setEditMode(self): self.labelSelectionChanged() def updateFileMenu(self): - currFilePath = self.filePath + curr_file_path = self.filePath def exists(filename): return os.path.exists(filename) menu = self.menus.recentFiles menu.clear() files = [f for f in self.recentFiles if f != - currFilePath and exists(f)] + curr_file_path and exists(f)] for i, f in enumerate(files): icon = newIcon('labels') action = QAction( @@ -716,9 +716,9 @@ def editLabel(self): # Tzutalin 20160906 : Add file list and dock to move faster def fileitemDoubleClicked(self, item=None): - currIndex = self.mImgList.index(ustr(item.text())) - if currIndex < len(self.mImgList): - filename = self.mImgList[currIndex] + current_index = self.mImgList.index(ustr(item.text())) + if current_index < len(self.mImgList): + filename = self.mImgList[current_index] if filename: self.loadFile(filename) @@ -820,17 +820,17 @@ def loadLabels(self, shapes): def updateComboBox(self): # Get the unique labels and add them to the Combobox. - itemsTextList = [str(self.labelList.item(i).text()) for i in range(self.labelList.count())] + items_text_list = [str(self.labelList.item(i).text()) for i in range(self.labelList.count())] - uniqueTextList = list(set(itemsTextList)) + unique_text_list = list(set(items_text_list)) # Add a null row for showing all the labels - uniqueTextList.append("") - uniqueTextList.sort() + unique_text_list.append("") + unique_text_list.sort() - self.comboBox.update_items(uniqueTextList) + self.comboBox.update_items(unique_text_list) - def saveLabels(self, annotationFilePath): - annotationFilePath = ustr(annotationFilePath) + def saveLabels(self, annotation_file_path): + annotation_file_path = ustr(annotation_file_path) if self.labelFile is None: self.labelFile = LabelFile() self.labelFile.verified = self.canvas.verified @@ -847,24 +847,24 @@ def format_shape(s): # Can add differrent annotation formats here try: if self.labelFileFormat == LabelFileFormat.PASCAL_VOC: - if annotationFilePath[-4:].lower() != ".xml": - annotationFilePath += XML_EXT - self.labelFile.savePascalVocFormat(annotationFilePath, shapes, self.filePath, self.imageData, + if annotation_file_path[-4:].lower() != ".xml": + annotation_file_path += XML_EXT + self.labelFile.savePascalVocFormat(annotation_file_path, shapes, self.filePath, self.imageData, self.lineColor.getRgb(), self.fillColor.getRgb()) elif self.labelFileFormat == LabelFileFormat.YOLO: - if annotationFilePath[-4:].lower() != ".txt": - annotationFilePath += TXT_EXT - self.labelFile.saveYoloFormat(annotationFilePath, shapes, self.filePath, self.imageData, self.labelHist, + if annotation_file_path[-4:].lower() != ".txt": + annotation_file_path += TXT_EXT + self.labelFile.saveYoloFormat(annotation_file_path, shapes, self.filePath, self.imageData, self.labelHist, self.lineColor.getRgb(), self.fillColor.getRgb()) elif self.labelFileFormat == LabelFileFormat.CREATE_ML: - if annotationFilePath[-5:].lower() != ".json": - annotationFilePath += JSON_EXT - self.labelFile.saveCreateMLFormat(annotationFilePath, shapes, self.filePath, self.imageData, + if annotation_file_path[-5:].lower() != ".json": + annotation_file_path += JSON_EXT + self.labelFile.saveCreateMLFormat(annotation_file_path, shapes, self.filePath, self.imageData, self.labelHist, self.lineColor.getRgb(), self.fillColor.getRgb()) else: - self.labelFile.save(annotationFilePath, shapes, self.filePath, self.imageData, + self.labelFile.save(annotation_file_path, shapes, self.filePath, self.imageData, self.lineColor.getRgb(), self.fillColor.getRgb()) - print('Image:{0} -> Annotation:{1}'.format(self.filePath, annotationFilePath)) + print('Image:{0} -> Annotation:{1}'.format(self.filePath, annotation_file_path)) return True except LabelFileError as e: self.errorMessage(u'Error saving label data', u'%s' % e) @@ -1026,40 +1026,40 @@ def togglePolygons(self, value): for item, shape in self.itemsToShapes.items(): item.setCheckState(Qt.Checked if value else Qt.Unchecked) - def loadFile(self, filePath=None): + def loadFile(self, file_path=None): """Load the specified file, or the last opened file if None.""" self.resetState() self.canvas.setEnabled(False) - if filePath is None: - filePath = self.settings.get(SETTING_FILENAME) + if file_path is None: + file_path = self.settings.get(SETTING_FILENAME) # Make sure that filePath is a regular python string, rather than QString - filePath = ustr(filePath) + file_path = ustr(file_path) # Fix bug: An index error after select a directory when open a new file. - unicodeFilePath = ustr(filePath) - unicodeFilePath = os.path.abspath(unicodeFilePath) + unicode_file_path = ustr(file_path) + unicode_file_path = os.path.abspath(unicode_file_path) # Tzutalin 20160906 : Add file list and dock to move faster # Highlight the file item - if unicodeFilePath and self.fileListWidget.count() > 0: - if unicodeFilePath in self.mImgList: - index = self.mImgList.index(unicodeFilePath) - fileWidgetItem = self.fileListWidget.item(index) - fileWidgetItem.setSelected(True) + if unicode_file_path and self.fileListWidget.count() > 0: + if unicode_file_path in self.mImgList: + index = self.mImgList.index(unicode_file_path) + file_widget_item = self.fileListWidget.item(index) + file_widget_item.setSelected(True) else: self.fileListWidget.clear() self.mImgList.clear() - if unicodeFilePath and os.path.exists(unicodeFilePath): - if LabelFile.isLabelFile(unicodeFilePath): + if unicode_file_path and os.path.exists(unicode_file_path): + if LabelFile.isLabelFile(unicode_file_path): try: - self.labelFile = LabelFile(unicodeFilePath) + self.labelFile = LabelFile(unicode_file_path) except LabelFileError as e: self.errorMessage(u'Error opening file', (u"

%s

" u"

Make sure %s is a valid label file.") - % (e, unicodeFilePath)) - self.status("Error reading %s" % unicodeFilePath) + % (e, unicode_file_path)) + self.status("Error reading %s" % unicode_file_path) return False self.imageData = self.labelFile.imageData self.lineColor = QColor(*self.labelFile.lineColor) @@ -1068,7 +1068,7 @@ def loadFile(self, filePath=None): else: # Load image: # read data first and store for saving into label file. - self.imageData = read(unicodeFilePath, None) + self.imageData = read(unicode_file_path, None) self.labelFile = None self.canvas.verified = False @@ -1078,12 +1078,12 @@ def loadFile(self, filePath=None): image = QImage.fromData(self.imageData) if image.isNull(): self.errorMessage(u'Error opening file', - u"

Make sure %s is a valid image file." % unicodeFilePath) - self.status("Error reading %s" % unicodeFilePath) + u"

Make sure %s is a valid image file." % unicode_file_path) + self.status("Error reading %s" % unicode_file_path) return False - self.status("Loaded %s" % os.path.basename(unicodeFilePath)) + self.status("Loaded %s" % os.path.basename(unicode_file_path)) self.image = image - self.filePath = unicodeFilePath + self.filePath = unicode_file_path self.canvas.loadPixmap(QPixmap.fromImage(image)) if self.labelFile: self.loadLabels(self.labelFile.shapes) @@ -1093,9 +1093,9 @@ def loadFile(self, filePath=None): self.paintCanvas() self.addRecentFile(self.filePath) self.toggleActions(True) - self.showBoundingBoxFromAnnotationFile(filePath) + self.showBoundingBoxFromAnnotationFile(file_path) - self.setWindowTitle(__appname__ + ' ' + filePath) + self.setWindowTitle(__appname__ + ' ' + file_path) # Default : select last item if there is at least one item if self.labelList.count(): @@ -1109,28 +1109,28 @@ def loadFile(self, filePath=None): def showBoundingBoxFromAnnotationFile(self, filePath): if self.defaultSaveDir is not None: basename = os.path.basename(os.path.splitext(filePath)[0]) - filedir = filePath.split(basename)[0].split(os.path.sep)[-2:-1][0] - xmlPath = os.path.join(self.defaultSaveDir, basename + XML_EXT) - txtPath = os.path.join(self.defaultSaveDir, basename + TXT_EXT) - jsonPath = os.path.join(self.defaultSaveDir, filedir + JSON_EXT) + file_dir = filePath.split(basename)[0].split(os.path.sep)[-2:-1][0] + xml_path = os.path.join(self.defaultSaveDir, basename + XML_EXT) + txt_path = os.path.join(self.defaultSaveDir, basename + TXT_EXT) + json_path = os.path.join(self.defaultSaveDir, file_dir + JSON_EXT) """Annotation file priority: PascalXML > YOLO """ - if os.path.isfile(xmlPath): - self.loadPascalXMLByFilename(xmlPath) - elif os.path.isfile(txtPath): - self.loadYOLOTXTByFilename(txtPath) - elif os.path.isfile(jsonPath): - self.loadCreateMLJSONByFilename(jsonPath, filePath) + if os.path.isfile(xml_path): + self.loadPascalXMLByFilename(xml_path) + elif os.path.isfile(txt_path): + self.loadYOLOTXTByFilename(txt_path) + elif os.path.isfile(json_path): + self.loadCreateMLJSONByFilename(json_path, filePath) else: - xmlPath = os.path.splitext(filePath)[0] + XML_EXT - txtPath = os.path.splitext(filePath)[0] + TXT_EXT - if os.path.isfile(xmlPath): - self.loadPascalXMLByFilename(xmlPath) - elif os.path.isfile(txtPath): - self.loadYOLOTXTByFilename(txtPath) + xml_path = os.path.splitext(filePath)[0] + XML_EXT + txt_path = os.path.splitext(filePath)[0] + TXT_EXT + if os.path.isfile(xml_path): + self.loadPascalXMLByFilename(xml_path) + elif os.path.isfile(txt_path): + self.loadYOLOTXTByFilename(txt_path) def resizeEvent(self, event): if self.canvas and not self.image.isNull()\ @@ -1211,8 +1211,8 @@ def scanAllImages(self, folderPath): for root, dirs, files in os.walk(folderPath): for file in files: if file.lower().endswith(tuple(extensions)): - relativePath = os.path.join(root, file) - path = ustr(os.path.abspath(relativePath)) + relative_path = os.path.join(root, file) + path = ustr(os.path.abspath(relative_path)) images.append(path) natural_sort(images, key=lambda x: x.lower()) return images @@ -1223,12 +1223,12 @@ def changeSavedirDialog(self, _value=False): else: path = '.' - dirpath = ustr(QFileDialog.getExistingDirectory(self, + dir_path = ustr(QFileDialog.getExistingDirectory(self, '%s - Save annotations to the directory' % __appname__, path, QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks)) - if dirpath is not None and len(dirpath) > 1: - self.defaultSaveDir = dirpath + if dir_path is not None and len(dir_path) > 1: + self.defaultSaveDir = dir_path self.statusBar().showMessage('%s . Annotation will be saved to %s' % ('Change saved folder', self.defaultSaveDir)) @@ -1254,19 +1254,19 @@ def openDirDialog(self, _value=False, dirpath=None, silent=False): if not self.mayContinue(): return - defaultOpenDirPath = dirpath if dirpath else '.' + default_open_dir_path = dirpath if dirpath else '.' if self.lastOpenDir and os.path.exists(self.lastOpenDir): - defaultOpenDirPath = self.lastOpenDir + default_open_dir_path = self.lastOpenDir else: - defaultOpenDirPath = os.path.dirname(self.filePath) if self.filePath else '.' + default_open_dir_path = os.path.dirname(self.filePath) if self.filePath else '.' if silent!=True : - targetDirPath = ustr(QFileDialog.getExistingDirectory(self, - '%s - Open Directory' % __appname__, defaultOpenDirPath, - QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks)) + target_dir_path = ustr(QFileDialog.getExistingDirectory(self, + '%s - Open Directory' % __appname__, default_open_dir_path, + QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks)) else: - targetDirPath = ustr(defaultOpenDirPath) - self.lastOpenDir = targetDirPath - self.importDirImages(targetDirPath) + target_dir_path = ustr(default_open_dir_path) + self.lastOpenDir = target_dir_path + self.importDirImages(target_dir_path) def importDirImages(self, dirpath): if not self.mayContinue() or not dirpath: @@ -1319,9 +1319,9 @@ def openPrevImg(self, _value=False): if self.filePath is None: return - currIndex = self.mImgList.index(self.filePath) - if currIndex - 1 >= 0: - filename = self.mImgList[currIndex - 1] + current_index = self.mImgList.index(self.filePath) + if current_index - 1 >= 0: + filename = self.mImgList[current_index - 1] if filename: self.loadFile(filename) @@ -1345,9 +1345,9 @@ def openNextImg(self, _value=False): if self.filePath is None: filename = self.mImgList[0] else: - currIndex = self.mImgList.index(self.filePath) - if currIndex + 1 < len(self.mImgList): - filename = self.mImgList[currIndex + 1] + current_index = self.mImgList.index(self.filePath) + if current_index + 1 < len(self.mImgList): + filename = self.mImgList[current_index + 1] if filename: self.loadFile(filename) @@ -1367,16 +1367,16 @@ def openFile(self, _value=False): def saveFile(self, _value=False): if self.defaultSaveDir is not None and len(ustr(self.defaultSaveDir)): if self.filePath: - imgFileName = os.path.basename(self.filePath) - savedFileName = os.path.splitext(imgFileName)[0] - savedPath = os.path.join(ustr(self.defaultSaveDir), savedFileName) - self._saveFile(savedPath) + image_file_name = os.path.basename(self.filePath) + saved_file_name = os.path.splitext(image_file_name)[0] + saved_path = os.path.join(ustr(self.defaultSaveDir), saved_file_name) + self._saveFile(saved_path) else: - imgFileDir = os.path.dirname(self.filePath) - imgFileName = os.path.basename(self.filePath) - savedFileName = os.path.splitext(imgFileName)[0] - savedPath = os.path.join(imgFileDir, savedFileName) - self._saveFile(savedPath if self.labelFile + image_file_dir = os.path.dirname(self.filePath) + image_file_name = os.path.basename(self.filePath) + saved_file_name = os.path.splitext(image_file_name)[0] + saved_path = os.path.join(image_file_dir, saved_file_name) + self._saveFile(saved_path if self.labelFile else self.saveFileDialog(removeExt=False)) def saveFileAs(self, _value=False): @@ -1386,19 +1386,19 @@ def saveFileAs(self, _value=False): def saveFileDialog(self, removeExt=True): caption = '%s - Choose File' % __appname__ filters = 'File (*%s)' % LabelFile.suffix - openDialogPath = self.currentPath() - dlg = QFileDialog(self, caption, openDialogPath, filters) + open_dialog_path = self.currentPath() + dlg = QFileDialog(self, caption, open_dialog_path, filters) dlg.setDefaultSuffix(LabelFile.suffix[1:]) dlg.setAcceptMode(QFileDialog.AcceptSave) - filenameWithoutExtension = os.path.splitext(self.filePath)[0] - dlg.selectFile(filenameWithoutExtension) + filename_without_extension = os.path.splitext(self.filePath)[0] + dlg.selectFile(filename_without_extension) dlg.setOption(QFileDialog.DontUseNativeDialog, False) if dlg.exec_(): - fullFilePath = ustr(dlg.selectedFiles()[0]) + full_file_path = ustr(dlg.selectedFiles()[0]) if removeExt: - return os.path.splitext(fullFilePath)[0] # Return file path without the extension. + return os.path.splitext(full_file_path)[0] # Return file path without the extension. else: - return fullFilePath + return full_file_path return '' def _saveFile(self, annotationFilePath): @@ -1417,11 +1417,11 @@ def closeFile(self, _value=False): self.actions.saveAs.setEnabled(False) def deleteImg(self): - deletePath = self.filePath - if deletePath is not None: + delete_path = self.filePath + if delete_path is not None: self.openNextImg() - if os.path.exists(deletePath): - os.remove(deletePath) + if os.path.exists(delete_path): + os.remove(delete_path) self.importDirImages(self.lastOpenDir) def resetAll(self): @@ -1434,10 +1434,10 @@ def mayContinue(self): if not self.dirty: return True else: - discardChanges = self.discardChangesDialog() - if discardChanges == QMessageBox.No: + discard_changes = self.discardChangesDialog() + if discard_changes == QMessageBox.No: return True - elif discardChanges == QMessageBox.Yes: + elif discard_changes == QMessageBox.Yes: self.saveFile() return True else: @@ -1515,10 +1515,10 @@ def loadPascalXMLByFilename(self, xmlPath): self.set_format(FORMAT_PASCALVOC) - tVocParseReader = PascalVocReader(xmlPath) - shapes = tVocParseReader.getShapes() + t_voc_parse_reader = PascalVocReader(xmlPath) + shapes = t_voc_parse_reader.getShapes() self.loadLabels(shapes) - self.canvas.verified = tVocParseReader.verified + self.canvas.verified = t_voc_parse_reader.verified def loadYOLOTXTByFilename(self, txtPath): if self.filePath is None: @@ -1527,11 +1527,11 @@ def loadYOLOTXTByFilename(self, txtPath): return self.set_format(FORMAT_YOLO) - tYoloParseReader = YoloReader(txtPath, self.image) - shapes = tYoloParseReader.getShapes() + t_yolo_parse_reader = YoloReader(txtPath, self.image) + shapes = t_yolo_parse_reader.getShapes() print (shapes) self.loadLabels(shapes) - self.canvas.verified = tYoloParseReader.verified + self.canvas.verified = t_yolo_parse_reader.verified def loadCreateMLJSONByFilename(self, jsonPath, filePath): if self.filePath is None: @@ -1541,16 +1541,16 @@ def loadCreateMLJSONByFilename(self, jsonPath, filePath): self.set_format(FORMAT_CREATEML) - crmlParseReader = CreateMLReader(jsonPath, filePath) - shapes = crmlParseReader.get_shapes() + crml_parse_reader = CreateMLReader(jsonPath, filePath) + shapes = crml_parse_reader.get_shapes() self.loadLabels(shapes) - self.canvas.verified = crmlParseReader.verified + self.canvas.verified = crml_parse_reader.verified def copyPreviousBoundingBoxes(self): - currIndex = self.mImgList.index(self.filePath) - if currIndex - 1 >= 0: - prevFilePath = self.mImgList[currIndex - 1] - self.showBoundingBoxFromAnnotationFile(prevFilePath) + current_index = self.mImgList.index(self.filePath) + if current_index - 1 >= 0: + prev_file_path = self.mImgList[current_index - 1] + self.showBoundingBoxFromAnnotationFile(prev_file_path) self.saveFile() def togglePaintLabelsOption(self): From d5fcc23e137bb2663b5f85499e04e341dd09071e Mon Sep 17 00:00:00 2001 From: Cerno_b Date: Mon, 8 Mar 2021 01:07:18 +0100 Subject: [PATCH 02/13] additional renaming of functions and variables --- labelImg.py | 208 ++++++++++++++++++++++++++-------------------------- 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/labelImg.py b/labelImg.py index a246b31e1..a429dd3e2 100755 --- a/labelImg.py +++ b/labelImg.py @@ -85,7 +85,7 @@ def __init__(self, defaultFilename=None, defaultPrefdefClassFile=None, defaultSa # Load string bundle for i18n self.stringBundle = StringBundle.getBundle() - getStr = lambda strId: self.stringBundle.getString(strId) + get_str = lambda str_id: self.stringBundle.getString(str_id) # Save as Pascal voc xml self.defaultSaveDir = defaultSaveDir @@ -119,7 +119,7 @@ def __init__(self, defaultFilename=None, defaultPrefdefClassFile=None, defaultSa list_layout.setContentsMargins(0, 0, 0, 0) # Create a widget for using default label - self.useDefaultLabelCheckbox = QCheckBox(getStr('useDefaultLabel')) + self.useDefaultLabelCheckbox = QCheckBox(get_str('useDefaultLabel')) self.useDefaultLabelCheckbox.setChecked(False) self.defaultLabelTextLine = QLineEdit() use_default_label_qhbox_layout = QHBoxLayout() @@ -129,7 +129,7 @@ def __init__(self, defaultFilename=None, defaultPrefdefClassFile=None, defaultSa use_default_label_container.setLayout(use_default_label_qhbox_layout) # Create a widget for edit and diffc button - self.diffcButton = QCheckBox(getStr('useDifficult')) + self.diffcButton = QCheckBox(get_str('useDifficult')) self.diffcButton.setChecked(False) self.diffcButton.stateChanged.connect(self.btnstate) self.editButton = QToolButton() @@ -157,8 +157,8 @@ def __init__(self, defaultFilename=None, defaultPrefdefClassFile=None, defaultSa - self.dock = QDockWidget(getStr('boxLabelText'), self) - self.dock.setObjectName(getStr('labels')) + self.dock = QDockWidget(get_str('boxLabelText'), self) + self.dock.setObjectName(get_str('labels')) self.dock.setWidget(label_list_container) self.fileListWidget = QListWidget() @@ -168,8 +168,8 @@ def __init__(self, defaultFilename=None, defaultPrefdefClassFile=None, defaultSa file_list_layout.addWidget(self.fileListWidget) file_list_container = QWidget() file_list_container.setLayout(file_list_layout) - self.filedock = QDockWidget(getStr('fileList'), self) - self.filedock.setObjectName(getStr('files')) + self.filedock = QDockWidget(get_str('fileList'), self) + self.filedock.setObjectName(get_str('files')) self.filedock.setWidget(file_list_container) self.zoomWidget = ZoomWidget() @@ -204,37 +204,37 @@ def __init__(self, defaultFilename=None, defaultPrefdefClassFile=None, defaultSa # Actions action = partial(newAction, self) - quit = action(getStr('quit'), self.close, - 'Ctrl+Q', 'quit', getStr('quitApp')) + quit = action(get_str('quit'), self.close, + 'Ctrl+Q', 'quit', get_str('quitApp')) - open = action(getStr('openFile'), self.openFile, - 'Ctrl+O', 'open', getStr('openFileDetail')) + open = action(get_str('openFile'), self.openFile, + 'Ctrl+O', 'open', get_str('openFileDetail')) - opendir = action(getStr('openDir'), self.openDirDialog, - 'Ctrl+u', 'open', getStr('openDir')) + open_dir = action(get_str('openDir'), self.openDirDialog, + 'Ctrl+u', 'open', get_str('openDir')) - copy_prev_bounding = action(getStr('copyPrevBounding'), self.copyPreviousBoundingBoxes, - 'Ctrl+v', 'paste', getStr('copyPrevBounding')) + copy_prev_bounding = action(get_str('copyPrevBounding'), self.copyPreviousBoundingBoxes, + 'Ctrl+v', 'paste', get_str('copyPrevBounding')) - change_save_dir = action(getStr('changeSaveDir'), self.changeSavedirDialog, - 'Ctrl+r', 'open', getStr('changeSavedAnnotationDir')) + change_save_dir = action(get_str('changeSaveDir'), self.changeSavedirDialog, + 'Ctrl+r', 'open', get_str('changeSavedAnnotationDir')) - open_annotation = action(getStr('openAnnotation'), self.openAnnotationDialog, - 'Ctrl+Shift+O', 'open', getStr('openAnnotationDetail')) + open_annotation = action(get_str('openAnnotation'), self.openAnnotationDialog, + 'Ctrl+Shift+O', 'open', get_str('openAnnotationDetail')) - open_next_image = action(getStr('nextImg'), self.openNextImg, - 'd', 'next', getStr('nextImgDetail')) + open_next_image = action(get_str('nextImg'), self.openNextImg, + 'd', 'next', get_str('nextImgDetail')) - open_prev_image = action(getStr('prevImg'), self.openPrevImg, - 'a', 'prev', getStr('prevImgDetail')) + open_prev_image = action(get_str('prevImg'), self.openPrevImg, + 'a', 'prev', get_str('prevImgDetail')) - verify = action(getStr('verifyImg'), self.verifyImg, - 'space', 'verify', getStr('verifyImgDetail')) + verify = action(get_str('verifyImg'), self.verifyImg, + 'space', 'verify', get_str('verifyImgDetail')) - save = action(getStr('save'), self.saveFile, - 'Ctrl+S', 'save', getStr('saveDetail'), enabled=False) + save = action(get_str('save'), self.saveFile, + 'Ctrl+S', 'save', get_str('saveDetail'), enabled=False) - def getFormatMeta(format): + def get_format_meta(format): """ returns a tuple containing (title, icon_name) of the selected format """ @@ -245,49 +245,49 @@ def getFormatMeta(format): elif format == LabelFileFormat.CREATE_ML: return ('&CreateML', 'format_createml') - save_format = action(getFormatMeta(self.labelFileFormat)[0], + save_format = action(get_format_meta(self.labelFileFormat)[0], self.change_format, 'Ctrl+', - getFormatMeta(self.labelFileFormat)[1], - getStr('changeSaveFormat'), enabled=True) + get_format_meta(self.labelFileFormat)[1], + get_str('changeSaveFormat'), enabled=True) - save_as = action(getStr('saveAs'), self.saveFileAs, - 'Ctrl+Shift+S', 'save-as', getStr('saveAsDetail'), enabled=False) + save_as = action(get_str('saveAs'), self.saveFileAs, + 'Ctrl+Shift+S', 'save-as', get_str('saveAsDetail'), enabled=False) - close = action(getStr('closeCur'), self.closeFile, 'Ctrl+W', 'close', getStr('closeCurDetail')) + close = action(get_str('closeCur'), self.closeFile, 'Ctrl+W', 'close', get_str('closeCurDetail')) - delete_image = action(getStr('deleteImg'), self.deleteImg, 'Ctrl+Shift+D', 'close', getStr('deleteImgDetail')) + delete_image = action(get_str('deleteImg'), self.deleteImg, 'Ctrl+Shift+D', 'close', get_str('deleteImgDetail')) - reset_all = action(getStr('resetAll'), self.resetAll, None, 'resetall', getStr('resetAllDetail')) + reset_all = action(get_str('resetAll'), self.resetAll, None, 'resetall', get_str('resetAllDetail')) - color1 = action(getStr('boxLineColor'), self.chooseColor1, - 'Ctrl+L', 'color_line', getStr('boxLineColorDetail')) + color1 = action(get_str('boxLineColor'), self.chooseColor1, + 'Ctrl+L', 'color_line', get_str('boxLineColorDetail')) - create_mode = action(getStr('crtBox'), self.setCreateMode, - 'w', 'new', getStr('crtBoxDetail'), enabled=False) + create_mode = action(get_str('crtBox'), self.setCreateMode, + 'w', 'new', get_str('crtBoxDetail'), enabled=False) edit_mode = 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'), + 'Ctrl+J', 'edit', u'Move and edit Boxs', enabled=False) + + create = action(get_str('crtBox'), self.createShape, + 'w', 'new', get_str('crtBoxDetail'), enabled=False) + delete = action(get_str('delBox'), self.deleteSelectedShape, + 'Delete', 'delete', get_str('delBoxDetail'), enabled=False) + copy = action(get_str('dupBox'), self.copySelectedShape, + 'Ctrl+D', 'copy', get_str('dupBoxDetail'), enabled=False) - advanced_mode = action(getStr('advancedMode'), self.toggleAdvancedMode, - 'Ctrl+Shift+A', 'expert', getStr('advancedModeDetail'), - checkable=True) + advanced_mode = action(get_str('advancedMode'), self.toggleAdvancedMode, + 'Ctrl+Shift+A', 'expert', get_str('advancedModeDetail'), + checkable=True) hide_all = action('&Hide\nRectBox', partial(self.togglePolygons, False), - 'Ctrl+H', 'hide', getStr('hideAllBoxDetail'), - enabled=False) + 'Ctrl+H', 'hide', get_str('hideAllBoxDetail'), + enabled=False) show_all = action('&Show\nRectBox', partial(self.togglePolygons, True), - 'Ctrl+A', 'hide', getStr('showAllBoxDetail'), - enabled=False) + 'Ctrl+A', 'hide', get_str('showAllBoxDetail'), + enabled=False) - help = action(getStr('tutorial'), self.showTutorialDialog, None, 'help', getStr('tutorialDetail')) - show_info = action(getStr('info'), self.showInfoDialog, None, 'help', getStr('info')) + help = action(get_str('tutorial'), self.showTutorialDialog, None, 'help', get_str('tutorialDetail')) + show_info = action(get_str('info'), self.showInfoDialog, None, 'help', get_str('info')) zoom = QWidgetAction(self) zoom.setDefaultWidget(self.zoomWidget) @@ -297,21 +297,21 @@ def getFormatMeta(format): fmtShortcut("Ctrl+Wheel"))) self.zoomWidget.setEnabled(False) - zoom_in = action(getStr('zoomin'), partial(self.addZoom, 10), - 'Ctrl++', 'zoom-in', getStr('zoominDetail'), enabled=False) - zoom_out = action(getStr('zoomout'), partial(self.addZoom, -10), - 'Ctrl+-', 'zoom-out', getStr('zoomoutDetail'), enabled=False) - zoom_org = action(getStr('originalsize'), partial(self.setZoom, 100), - 'Ctrl+=', 'zoom', getStr('originalsizeDetail'), enabled=False) - fit_window = action(getStr('fitWin'), self.setFitWindow, - 'Ctrl+F', 'fit-window', getStr('fitWinDetail'), + zoom_in = action(get_str('zoomin'), partial(self.addZoom, 10), + 'Ctrl++', 'zoom-in', get_str('zoominDetail'), enabled=False) + zoom_out = action(get_str('zoomout'), partial(self.addZoom, -10), + 'Ctrl+-', 'zoom-out', get_str('zoomoutDetail'), enabled=False) + zoom_org = action(get_str('originalsize'), partial(self.setZoom, 100), + 'Ctrl+=', 'zoom', get_str('originalsizeDetail'), enabled=False) + fit_window = action(get_str('fitWin'), self.setFitWindow, + 'Ctrl+F', 'fit-window', get_str('fitWinDetail'), + checkable=True, enabled=False) + fit_width = action(get_str('fitWidth'), self.setFitWidth, + 'Ctrl+Shift+F', 'fit-width', get_str('fitWidthDetail'), checkable=True, enabled=False) - fit_width = 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. zoom_actions = (self.zoomWidget, zoom_in, zoom_out, - zoom_org, fit_window, fit_width) + zoom_org, fit_window, fit_width) self.zoomMode = self.MANUAL_ZOOM self.scalers = { self.FIT_WINDOW: self.scaleFitWindow, @@ -320,20 +320,20 @@ def getFormatMeta(format): self.MANUAL_ZOOM: lambda: 1, } - edit = action(getStr('editLabel'), self.editLabel, - 'Ctrl+E', 'edit', getStr('editLabelDetail'), + edit = action(get_str('editLabel'), self.editLabel, + 'Ctrl+E', 'edit', get_str('editLabelDetail'), enabled=False) self.editButton.setDefaultAction(edit) - shape_line_color = action(getStr('shapeLineColor'), self.chshapeLineColor, - icon='color_line', tip=getStr('shapeLineColorDetail'), - enabled=False) - shape_fill_color = action(getStr('shapeFillColor'), self.chshapeFillColor, - icon='color', tip=getStr('shapeFillColorDetail'), - enabled=False) + shape_line_color = action(get_str('shapeLineColor'), self.chshapeLineColor, + icon='color_line', tip=get_str('shapeLineColorDetail'), + enabled=False) + shape_fill_color = action(get_str('shapeFillColor'), self.chshapeFillColor, + icon='color', tip=get_str('shapeFillColorDetail'), + enabled=False) labels = self.dock.toggleViewAction() - labels.setText(getStr('showHide')) + labels.setText(get_str('showHide')) labels.setShortcut('Ctrl+Shift+L') # Label list context menu. @@ -359,7 +359,7 @@ def getFormatMeta(format): fitWindow=fit_window, fitWidth=fit_width, zoomActions=zoom_actions, fileMenuActions=( - open, opendir, save, save_as, close, reset_all, quit), + open, open_dir, save, save_as, close, reset_all, quit), beginner=(), advanced=(), editMenu=(edit, copy, delete, None, color1, self.drawSquaresOption), @@ -371,32 +371,32 @@ def getFormatMeta(format): onShapesPresent=(save_as, hide_all, show_all)) self.menus = struct( - file=self.menu(getStr('menu_file')), - edit=self.menu(getStr('menu_edit')), - view=self.menu(getStr('menu_view')), - help=self.menu(getStr('menu_help')), - recentFiles=QMenu(getStr('menu_openRecent')), + file=self.menu(get_str('menu_file')), + edit=self.menu(get_str('menu_edit')), + view=self.menu(get_str('menu_view')), + help=self.menu(get_str('menu_help')), + recentFiles=QMenu(get_str('menu_openRecent')), labelList=label_menu) # Auto saving : Enable auto saving if pressing next - self.autoSaving = QAction(getStr('autoSaveMode'), self) + self.autoSaving = QAction(get_str('autoSaveMode'), self) self.autoSaving.setCheckable(True) self.autoSaving.setChecked(settings.get(SETTING_AUTO_SAVE, False)) # Sync single class mode from PR#106 - self.singleClassMode = QAction(getStr('singleClsMode'), self) + self.singleClassMode = QAction(get_str('singleClsMode'), self) self.singleClassMode.setShortcut("Ctrl+Shift+S") self.singleClassMode.setCheckable(True) self.singleClassMode.setChecked(settings.get(SETTING_SINGLE_CLASS, False)) self.lastLabel = None # Add option to enable/disable labels being displayed at the top of bounding boxes - self.displayLabelOption = QAction(getStr('displayLabel'), self) + self.displayLabelOption = QAction(get_str('displayLabel'), self) self.displayLabelOption.setShortcut("Ctrl+Shift+P") self.displayLabelOption.setCheckable(True) self.displayLabelOption.setChecked(settings.get(SETTING_PAINT_LABEL, False)) self.displayLabelOption.triggered.connect(self.togglePaintLabelsOption) addActions(self.menus.file, - (open, opendir, copy_prev_bounding, change_save_dir, open_annotation, self.menus.recentFiles, save, save_format, save_as, close, reset_all, delete_image, quit)) + (open, open_dir, copy_prev_bounding, change_save_dir, open_annotation, self.menus.recentFiles, save, save_format, save_as, close, reset_all, delete_image, quit)) addActions(self.menus.help, (help, show_info)) addActions(self.menus.view, ( self.autoSaving, @@ -417,11 +417,11 @@ def getFormatMeta(format): self.tools = self.toolbar('Tools') self.actions.beginner = ( - open, opendir, change_save_dir, open_next_image, open_prev_image, verify, save, save_format, None, create, copy, delete, None, + open, open_dir, change_save_dir, open_next_image, open_prev_image, verify, save, save_format, None, create, copy, delete, None, zoom_in, zoom, zoom_out, fit_window, fit_width) self.actions.advanced = ( - open, opendir, change_save_dir, open_next_image, open_prev_image, save, save_format, None, + open, open_dir, change_save_dir, open_next_image, open_prev_image, save, save_format, None, create_mode, edit_mode, None, hide_all, show_all) @@ -501,7 +501,7 @@ def xbool(x): self.labelCoordinates = QLabel('') self.statusBar().addPermanentWidget(self.labelCoordinates) - # Open Dir if deafult file + # Open Dir if default file if self.filePath and os.path.isdir(self.filePath): self.openDirDialog(dirpath=self.filePath, silent=True) @@ -635,13 +635,13 @@ def advanced(self): return not self.beginner() def getAvailableScreencastViewer(self): - osName = platform.system() + os_name = platform.system() - if osName == 'Windows': + if os_name == 'Windows': return ['C:\\Program Files\\Internet Explorer\\iexplore.exe'] - elif osName == 'Linux': + elif os_name == 'Linux': return ['xdg-open'] - elif osName == 'Darwin': + elif os_name == 'Darwin': return ['open'] ## Callbacks ## @@ -723,14 +723,14 @@ def fileitemDoubleClicked(self, item=None): self.loadFile(filename) # Add chris - def btnstate(self, item= None): + def btnstate(self, item=None): """ Function to handle difficult examples Update on each object """ if not self.canvas.editing(): return item = self.currentItem() - if not item: # If not selected Item, take the first one + if not item: # If not selected Item, take the first one item = self.labelList.item(self.labelList.count()-1) difficult = self.diffcButton.isChecked() @@ -840,11 +840,11 @@ def format_shape(s): line_color=s.line_color.getRgb(), fill_color=s.fill_color.getRgb(), points=[(p.x(), p.y()) for p in s.points], - # add chris + # add chris difficult = s.difficult) shapes = [format_shape(shape) for shape in self.canvas.shapes] - # Can add differrent annotation formats here + # Can add different annotation formats here try: if self.labelFileFormat == LabelFileFormat.PASCAL_VOC: if annotation_file_path[-4:].lower() != ".xml": @@ -1224,8 +1224,8 @@ def changeSavedirDialog(self, _value=False): path = '.' dir_path = ustr(QFileDialog.getExistingDirectory(self, - '%s - Save annotations to the directory' % __appname__, path, QFileDialog.ShowDirsOnly - | QFileDialog.DontResolveSymlinks)) + '%s - Save annotations to the directory' % __appname__, path, QFileDialog.ShowDirsOnly + | QFileDialog.DontResolveSymlinks)) if dir_path is not None and len(dir_path) > 1: self.defaultSaveDir = dir_path @@ -1261,8 +1261,8 @@ def openDirDialog(self, _value=False, dirpath=None, silent=False): default_open_dir_path = os.path.dirname(self.filePath) if self.filePath else '.' if silent!=True : target_dir_path = ustr(QFileDialog.getExistingDirectory(self, - '%s - Open Directory' % __appname__, default_open_dir_path, - QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks)) + '%s - Open Directory' % __appname__, default_open_dir_path, + QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks)) else: target_dir_path = ustr(default_open_dir_path) self.lastOpenDir = target_dir_path @@ -1598,7 +1598,7 @@ def get_main_app(argv=[]): def main(): - '''construct main app and run it''' + """construct main app and run it""" app, _win = get_main_app(sys.argv) return app.exec_() From 85d3b3d1448647b04cba18c75f5bf7afd1765164 Mon Sep 17 00:00:00 2001 From: Cerno_b Date: Mon, 8 Mar 2021 01:27:28 +0100 Subject: [PATCH 03/13] Rename main file functions --- labelImg.py | 574 +++++++++++++++++++++++------------------------ libs/combobox.py | 2 +- 2 files changed, 288 insertions(+), 288 deletions(-) diff --git a/labelImg.py b/labelImg.py index a429dd3e2..c54834d94 100755 --- a/labelImg.py +++ b/labelImg.py @@ -74,7 +74,7 @@ def toolbar(self, title, actions=None): class MainWindow(QMainWindow, WindowMixin): FIT_WINDOW, FIT_WIDTH, MANUAL_ZOOM = list(range(3)) - def __init__(self, defaultFilename=None, defaultPrefdefClassFile=None, defaultSaveDir=None): + def __init__(self, default_filename=None, default_prefdef_class_file=None, default_save_dir=None): super(MainWindow, self).__init__() self.setWindowTitle(__appname__) @@ -88,7 +88,7 @@ def __init__(self, defaultFilename=None, defaultPrefdefClassFile=None, defaultSa get_str = lambda str_id: self.stringBundle.getString(str_id) # Save as Pascal voc xml - self.defaultSaveDir = defaultSaveDir + self.defaultSaveDir = default_save_dir self.labelFileFormat = settings.get(SETTING_LABEL_FILE_FORMAT, LabelFileFormat.PASCAL_VOC) # For loading all image under a directory @@ -102,11 +102,11 @@ def __init__(self, defaultFilename=None, defaultPrefdefClassFile=None, defaultSa self._noSelectionSlot = False self._beginner = True - self.screencastViewer = self.getAvailableScreencastViewer() + self.screencastViewer = self.get_available_screencast_viewer() self.screencast = "https://youtu.be/p0nR2YsCY_U" # Load predefined classes to the list - self.loadPredefinedClasses(defaultPrefdefClassFile) + self.load_predefined_classes(default_prefdef_class_file) # Main widgets and related state. self.labelDialog = LabelDialog(parent=self, listItem=self.labelHist) @@ -131,7 +131,7 @@ def __init__(self, defaultFilename=None, defaultPrefdefClassFile=None, defaultSa # Create a widget for edit and diffc button self.diffcButton = QCheckBox(get_str('useDifficult')) self.diffcButton.setChecked(False) - self.diffcButton.stateChanged.connect(self.btnstate) + self.diffcButton.stateChanged.connect(self.button_state) self.editButton = QToolButton() self.editButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) @@ -148,11 +148,11 @@ def __init__(self, defaultFilename=None, defaultPrefdefClassFile=None, defaultSa self.labelList = QListWidget() label_list_container = QWidget() label_list_container.setLayout(list_layout) - self.labelList.itemActivated.connect(self.labelSelectionChanged) - self.labelList.itemSelectionChanged.connect(self.labelSelectionChanged) - self.labelList.itemDoubleClicked.connect(self.editLabel) + self.labelList.itemActivated.connect(self.label_selection_changed) + self.labelList.itemSelectionChanged.connect(self.label_selection_changed) + self.labelList.itemDoubleClicked.connect(self.edit_label) # Connect to itemChanged to detect checkbox changes. - self.labelList.itemChanged.connect(self.labelItemChanged) + self.labelList.itemChanged.connect(self.label_item_changed) list_layout.addWidget(self.labelList) @@ -162,7 +162,7 @@ def __init__(self, defaultFilename=None, defaultPrefdefClassFile=None, defaultSa self.dock.setWidget(label_list_container) self.fileListWidget = QListWidget() - self.fileListWidget.itemDoubleClicked.connect(self.fileitemDoubleClicked) + self.fileListWidget.itemDoubleClicked.connect(self.file_item_double_clicked) file_list_layout = QVBoxLayout() file_list_layout.setContentsMargins(0, 0, 0, 0) file_list_layout.addWidget(self.fileListWidget) @@ -176,7 +176,7 @@ def __init__(self, defaultFilename=None, defaultPrefdefClassFile=None, defaultSa self.colorDialog = ColorDialog(parent=self) self.canvas = Canvas(parent=self) - self.canvas.zoomRequest.connect(self.zoomRequest) + self.canvas.zoomRequest.connect(self.zoom_request) self.canvas.setDrawingShapeToSquare(settings.get(SETTING_DRAW_SQUARE, False)) scroll = QScrollArea() @@ -187,12 +187,12 @@ def __init__(self, defaultFilename=None, defaultPrefdefClassFile=None, defaultSa Qt.Horizontal: scroll.horizontalScrollBar() } self.scrollArea = scroll - self.canvas.scrollRequest.connect(self.scrollRequest) + self.canvas.scrollRequest.connect(self.scroll_request) - 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.canvas.newShape.connect(self.new_shape) + self.canvas.shapeMoved.connect(self.set_dirty) + self.canvas.selectionChanged.connect(self.shape_selection_changed) + self.canvas.drawingPolygon.connect(self.toggle_drawing_sensitive) self.setCentralWidget(scroll) self.addDockWidget(Qt.RightDockWidgetArea, self.dock) @@ -207,31 +207,31 @@ def __init__(self, defaultFilename=None, defaultPrefdefClassFile=None, defaultSa quit = action(get_str('quit'), self.close, 'Ctrl+Q', 'quit', get_str('quitApp')) - open = action(get_str('openFile'), self.openFile, + open = action(get_str('openFile'), self.open_file, 'Ctrl+O', 'open', get_str('openFileDetail')) - open_dir = action(get_str('openDir'), self.openDirDialog, + open_dir = action(get_str('openDir'), self.open_dir_dialog, 'Ctrl+u', 'open', get_str('openDir')) - copy_prev_bounding = action(get_str('copyPrevBounding'), self.copyPreviousBoundingBoxes, + copy_prev_bounding = action(get_str('copyPrevBounding'), self.copy_previous_bounding_boxes, 'Ctrl+v', 'paste', get_str('copyPrevBounding')) - change_save_dir = action(get_str('changeSaveDir'), self.changeSavedirDialog, + change_save_dir = action(get_str('changeSaveDir'), self.change_save_dir_dialog, 'Ctrl+r', 'open', get_str('changeSavedAnnotationDir')) - open_annotation = action(get_str('openAnnotation'), self.openAnnotationDialog, + open_annotation = action(get_str('openAnnotation'), self.open_annotation_dialog, 'Ctrl+Shift+O', 'open', get_str('openAnnotationDetail')) - open_next_image = action(get_str('nextImg'), self.openNextImg, + open_next_image = action(get_str('nextImg'), self.open_next_image, 'd', 'next', get_str('nextImgDetail')) - open_prev_image = action(get_str('prevImg'), self.openPrevImg, + open_prev_image = action(get_str('prevImg'), self.open_prev_image, 'a', 'prev', get_str('prevImgDetail')) - verify = action(get_str('verifyImg'), self.verifyImg, + verify = action(get_str('verifyImg'), self.verify_image, 'space', 'verify', get_str('verifyImgDetail')) - save = action(get_str('save'), self.saveFile, + save = action(get_str('save'), self.save_file, 'Ctrl+S', 'save', get_str('saveDetail'), enabled=False) def get_format_meta(format): @@ -239,55 +239,55 @@ def get_format_meta(format): returns a tuple containing (title, icon_name) of the selected format """ if format == LabelFileFormat.PASCAL_VOC: - return ('&PascalVOC', 'format_voc') + return '&PascalVOC', 'format_voc' elif format == LabelFileFormat.YOLO: - return ('&YOLO', 'format_yolo') + return '&YOLO', 'format_yolo' elif format == LabelFileFormat.CREATE_ML: - return ('&CreateML', 'format_createml') + return '&CreateML', 'format_createml' save_format = action(get_format_meta(self.labelFileFormat)[0], self.change_format, 'Ctrl+', get_format_meta(self.labelFileFormat)[1], get_str('changeSaveFormat'), enabled=True) - save_as = action(get_str('saveAs'), self.saveFileAs, + save_as = action(get_str('saveAs'), self.save_file_as, 'Ctrl+Shift+S', 'save-as', get_str('saveAsDetail'), enabled=False) - close = action(get_str('closeCur'), self.closeFile, 'Ctrl+W', 'close', get_str('closeCurDetail')) + close = action(get_str('closeCur'), self.close_file, 'Ctrl+W', 'close', get_str('closeCurDetail')) - delete_image = action(get_str('deleteImg'), self.deleteImg, 'Ctrl+Shift+D', 'close', get_str('deleteImgDetail')) + delete_image = action(get_str('deleteImg'), self.delete_image, 'Ctrl+Shift+D', 'close', get_str('deleteImgDetail')) - reset_all = action(get_str('resetAll'), self.resetAll, None, 'resetall', get_str('resetAllDetail')) + reset_all = action(get_str('resetAll'), self.reset_all, None, 'resetall', get_str('resetAllDetail')) - color1 = action(get_str('boxLineColor'), self.chooseColor1, + color1 = action(get_str('boxLineColor'), self.choose_color1, 'Ctrl+L', 'color_line', get_str('boxLineColorDetail')) - create_mode = action(get_str('crtBox'), self.setCreateMode, + create_mode = action(get_str('crtBox'), self.set_create_mode, 'w', 'new', get_str('crtBoxDetail'), enabled=False) - edit_mode = action('&Edit\nRectBox', self.setEditMode, + edit_mode = action('&Edit\nRectBox', self.set_edit_mode, 'Ctrl+J', 'edit', u'Move and edit Boxs', enabled=False) - create = action(get_str('crtBox'), self.createShape, + create = action(get_str('crtBox'), self.create_shape, 'w', 'new', get_str('crtBoxDetail'), enabled=False) - delete = action(get_str('delBox'), self.deleteSelectedShape, + delete = action(get_str('delBox'), self.delete_selected_shape, 'Delete', 'delete', get_str('delBoxDetail'), enabled=False) - copy = action(get_str('dupBox'), self.copySelectedShape, + copy = action(get_str('dupBox'), self.copy_selected_shape, 'Ctrl+D', 'copy', get_str('dupBoxDetail'), enabled=False) - advanced_mode = action(get_str('advancedMode'), self.toggleAdvancedMode, + advanced_mode = action(get_str('advancedMode'), self.toggle_advanced_mode, 'Ctrl+Shift+A', 'expert', get_str('advancedModeDetail'), checkable=True) - hide_all = action('&Hide\nRectBox', partial(self.togglePolygons, False), + hide_all = action('&Hide\nRectBox', partial(self.toggle_polygons, False), 'Ctrl+H', 'hide', get_str('hideAllBoxDetail'), enabled=False) - show_all = action('&Show\nRectBox', partial(self.togglePolygons, True), + show_all = action('&Show\nRectBox', partial(self.toggle_polygons, True), 'Ctrl+A', 'hide', get_str('showAllBoxDetail'), enabled=False) - help = action(get_str('tutorial'), self.showTutorialDialog, None, 'help', get_str('tutorialDetail')) - show_info = action(get_str('info'), self.showInfoDialog, None, 'help', get_str('info')) + help = action(get_str('tutorial'), self.show_tutorial_dialog, None, 'help', get_str('tutorialDetail')) + show_info = action(get_str('info'), self.show_info_dialog, None, 'help', get_str('info')) zoom = QWidgetAction(self) zoom.setDefaultWidget(self.zoomWidget) @@ -297,16 +297,16 @@ def get_format_meta(format): fmtShortcut("Ctrl+Wheel"))) self.zoomWidget.setEnabled(False) - zoom_in = action(get_str('zoomin'), partial(self.addZoom, 10), + zoom_in = action(get_str('zoomin'), partial(self.add_zoom, 10), 'Ctrl++', 'zoom-in', get_str('zoominDetail'), enabled=False) - zoom_out = action(get_str('zoomout'), partial(self.addZoom, -10), + zoom_out = action(get_str('zoomout'), partial(self.add_zoom, -10), 'Ctrl+-', 'zoom-out', get_str('zoomoutDetail'), enabled=False) - zoom_org = action(get_str('originalsize'), partial(self.setZoom, 100), + zoom_org = action(get_str('originalsize'), partial(self.set_zoom, 100), 'Ctrl+=', 'zoom', get_str('originalsizeDetail'), enabled=False) - fit_window = action(get_str('fitWin'), self.setFitWindow, + fit_window = action(get_str('fitWin'), self.set_fit_window, 'Ctrl+F', 'fit-window', get_str('fitWinDetail'), checkable=True, enabled=False) - fit_width = action(get_str('fitWidth'), self.setFitWidth, + fit_width = action(get_str('fitWidth'), self.set_fit_width, 'Ctrl+Shift+F', 'fit-width', get_str('fitWidthDetail'), checkable=True, enabled=False) # Group zoom controls into a list for easier toggling. @@ -314,21 +314,21 @@ def get_format_meta(format): zoom_org, fit_window, fit_width) self.zoomMode = self.MANUAL_ZOOM self.scalers = { - self.FIT_WINDOW: self.scaleFitWindow, - self.FIT_WIDTH: self.scaleFitWidth, + self.FIT_WINDOW: self.scale_fit_window, + self.FIT_WIDTH: self.scale_fit_width, # Set to one to scale to 100% when loading files. self.MANUAL_ZOOM: lambda: 1, } - edit = action(get_str('editLabel'), self.editLabel, + edit = action(get_str('editLabel'), self.edit_label, 'Ctrl+E', 'edit', get_str('editLabelDetail'), enabled=False) self.editButton.setDefaultAction(edit) - shape_line_color = action(get_str('shapeLineColor'), self.chshapeLineColor, + shape_line_color = action(get_str('shapeLineColor'), self.choose_shape_line_color, icon='color_line', tip=get_str('shapeLineColorDetail'), enabled=False) - shape_fill_color = action(get_str('shapeFillColor'), self.chshapeFillColor, + shape_fill_color = action(get_str('shapeFillColor'), self.choose_shape_fill_color, icon='color', tip=get_str('shapeFillColorDetail'), enabled=False) @@ -341,17 +341,17 @@ def get_format_meta(format): addActions(label_menu, (edit, delete)) self.labelList.setContextMenuPolicy(Qt.CustomContextMenu) self.labelList.customContextMenuRequested.connect( - self.popLabelListMenu) + self.pop_label_list_menu) # 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) + self.drawSquaresOption.triggered.connect(self.toggle_draw_square) # Store actions for further handling. - self.actions = struct(save=save, save_format=save_format, saveAs=save_as, open=open, close=close, resetAll = reset_all, deleteImg = delete_image, + self.actions = struct(save=save, save_format=save_format, saveAs=save_as, open=open, close=close, resetAll=reset_all, deleteImg=delete_image, lineColor=color1, create=create, delete=delete, edit=edit, copy=copy, createMode=create_mode, editMode=edit_mode, advancedMode=advanced_mode, shapeLineColor=shape_line_color, shapeFillColor=shape_fill_color, @@ -393,7 +393,7 @@ def get_format_meta(format): self.displayLabelOption.setShortcut("Ctrl+Shift+P") self.displayLabelOption.setCheckable(True) self.displayLabelOption.setChecked(settings.get(SETTING_PAINT_LABEL, False)) - self.displayLabelOption.triggered.connect(self.togglePaintLabelsOption) + self.displayLabelOption.triggered.connect(self.toggle_paint_labels_option) addActions(self.menus.file, (open, open_dir, copy_prev_bounding, change_save_dir, open_annotation, self.menus.recentFiles, save, save_format, save_as, close, reset_all, delete_image, quit)) @@ -407,13 +407,13 @@ def get_format_meta(format): zoom_in, zoom_out, zoom_org, None, fit_window, fit_width)) - self.menus.file.aboutToShow.connect(self.updateFileMenu) + self.menus.file.aboutToShow.connect(self.update_file_menu) # 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))) + action('&Copy here', self.copy_shape), + action('&Move here', self.move_shape))) self.tools = self.toolbar('Tools') self.actions.beginner = ( @@ -430,8 +430,8 @@ def get_format_meta(format): # Application state. self.image = QImage() - self.filePath = ustr(defaultFilename) - self.lastOpenDir= None + self.filePath = ustr(default_filename) + self.lastOpenDir = None self.recentFiles = [] self.maxRecent = 7 self.lineColor = None @@ -441,7 +441,7 @@ def get_format_meta(format): # Add Chris self.difficult = False - ## Fix the compatible issue for qt4 and qt5. Convert the QStringList to python list + # Fix the compatible issue for qt4 and qt5. Convert the QStringList to python list if settings.get(SETTING_RECENT_FILES): if have_qstring(): recent_file_qstring_list = settings.get(SETTING_RECENT_FILES) @@ -481,21 +481,21 @@ def xbool(x): if xbool(settings.get(SETTING_ADVANCE_MODE, False)): self.actions.advancedMode.setChecked(True) - self.toggleAdvancedMode() + self.toggle_advanced_mode() # Populate the File menu dynamically. - self.updateFileMenu() + self.update_file_menu() # 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 "")) + self.queue_event(partial(self.import_dir_images, self.filePath or "")) elif self.filePath: - self.queueEvent(partial(self.loadFile, self.filePath or "")) + self.queue_event(partial(self.load_file, self.filePath or "")) # Callbacks: - self.zoomWidget.valueChanged.connect(self.paintCanvas) + self.zoomWidget.valueChanged.connect(self.paint_canvas) - self.populateModeActions() + self.populate_mode_actions() # Display cursor coordinates at the right of status bar self.labelCoordinates = QLabel('') @@ -503,7 +503,7 @@ def xbool(x): # Open Dir if default file if self.filePath and os.path.isdir(self.filePath): - self.openDirDialog(dirpath=self.filePath, silent=True) + self.open_dir_dialog(dir_path=self.filePath, silent=True) def keyReleaseEvent(self, event): if event.key() == Qt.Key_Control: @@ -514,7 +514,7 @@ def keyPressEvent(self, event): # Draw rectangle if Ctrl is pressed self.canvas.setDrawingShapeToSquare(True) - ## Support Functions ## + # Support Functions # def set_format(self, save_format): if save_format == FORMAT_PASCALVOC: self.actions.save_format.setText(FORMAT_PASCALVOC) @@ -543,15 +543,15 @@ def change_format(self): self.set_format(FORMAT_PASCALVOC) else: raise ValueError('Unknown label file format.') - self.setDirty() + self.set_dirty() - def noShapes(self): + def no_shapes(self): return not self.itemsToShapes - def toggleAdvancedMode(self, value=True): + def toggle_advanced_mode(self, value=True): self._beginner = not value self.canvas.setEditing(True) - self.populateModeActions() + self.populate_mode_actions() self.editButton.setVisible(not value) if value: self.actions.createMode.setEnabled(True) @@ -560,7 +560,7 @@ def toggleAdvancedMode(self, value=True): else: self.dock.setFeatures(self.dock.features() ^ self.dockFeatures) - def populateModeActions(self): + def populate_mode_actions(self): if self.beginner(): tool, menu = self.actions.beginner, self.actions.beginnerContext else: @@ -574,37 +574,37 @@ def populateModeActions(self): else (self.actions.createMode, self.actions.editMode) addActions(self.menus.edit, actions + self.actions.editMenu) - def setBeginner(self): + def set_beginner(self): self.tools.clear() addActions(self.tools, self.actions.beginner) - def setAdvanced(self): + def set_advanced(self): self.tools.clear() addActions(self.tools, self.actions.advanced) - def setDirty(self): + def set_dirty(self): self.dirty = True self.actions.save.setEnabled(True) - def setClean(self): + def set_clean(self): self.dirty = False self.actions.save.setEnabled(False) self.actions.create.setEnabled(True) - def toggleActions(self, value=True): + def toggle_actions(self, value=True): """Enable/Disable widgets which depend on an opened image.""" for z in self.actions.zoomActions: z.setEnabled(value) for action in self.actions.onLoadActive: action.setEnabled(value) - def queueEvent(self, function): + def queue_event(self, function): QTimer.singleShot(0, function) def status(self, message, delay=5000): self.statusBar().showMessage(message, delay) - def resetState(self): + def reset_state(self): self.itemsToShapes.clear() self.shapesToItems.clear() self.labelList.clear() @@ -615,18 +615,18 @@ def resetState(self): self.labelCoordinates.clear() self.comboBox.cb.clear() - def currentItem(self): + def current_item(self): items = self.labelList.selectedItems() if items: return items[0] return None - def addRecentFile(self, filePath): - if filePath in self.recentFiles: - self.recentFiles.remove(filePath) + def add_recent_file(self, file_path): + if file_path in self.recentFiles: + self.recentFiles.remove(file_path) elif len(self.recentFiles) >= self.maxRecent: self.recentFiles.pop() - self.recentFiles.insert(0, filePath) + self.recentFiles.insert(0, file_path) def beginner(self): return self._beginner @@ -634,7 +634,7 @@ def beginner(self): def advanced(self): return not self.beginner() - def getAvailableScreencastViewer(self): + def get_available_screencast_viewer(self): os_name = platform.system() if os_name == 'Windows': @@ -644,21 +644,21 @@ def getAvailableScreencastViewer(self): elif os_name == 'Darwin': return ['open'] - ## Callbacks ## - def showTutorialDialog(self): + # Callbacks # + def show_tutorial_dialog(self): subprocess.Popen(self.screencastViewer + [self.screencast]) - def showInfoDialog(self): + def show_info_dialog(self): from libs.__init__ import __version__ msg = u'Name:{0} \nApp Version:{1} \n{2} '.format(__appname__, __version__, sys.version_info) QMessageBox.information(self, u'Information', msg) - def createShape(self): + def create_shape(self): assert self.beginner() self.canvas.setEditing(False) self.actions.create.setEnabled(False) - def toggleDrawingSensitive(self, drawing=True): + def toggle_drawing_sensitive(self, drawing=True): """In the middle of drawing, toggling between modes should be disabled.""" self.actions.editMode.setEnabled(not drawing) if not drawing and self.beginner(): @@ -668,21 +668,21 @@ def toggleDrawingSensitive(self, drawing=True): self.canvas.restoreCursor() self.actions.create.setEnabled(True) - def toggleDrawMode(self, edit=True): + def toggle_draw_mode(self, edit=True): self.canvas.setEditing(edit) self.actions.createMode.setEnabled(edit) self.actions.editMode.setEnabled(not edit) - def setCreateMode(self): + def set_create_mode(self): assert self.advanced() - self.toggleDrawMode(False) + self.toggle_draw_mode(False) - def setEditMode(self): + def set_edit_mode(self): assert self.advanced() - self.toggleDrawMode(True) - self.labelSelectionChanged() + self.toggle_draw_mode(True) + self.label_selection_changed() - def updateFileMenu(self): + def update_file_menu(self): curr_file_path = self.filePath def exists(filename): @@ -695,41 +695,41 @@ def exists(filename): icon = newIcon('labels') action = QAction( icon, '&%d %s' % (i + 1, QFileInfo(f).fileName()), self) - action.triggered.connect(partial(self.loadRecent, f)) + action.triggered.connect(partial(self.load_recent, f)) menu.addAction(action) - def popLabelListMenu(self, point): + def pop_label_list_menu(self, point): self.menus.labelList.exec_(self.labelList.mapToGlobal(point)) - def editLabel(self): + def edit_label(self): if not self.canvas.editing(): return - item = self.currentItem() + item = self.current_item() if not item: return text = self.labelDialog.popUp(item.text()) if text is not None: item.setText(text) item.setBackground(generateColorByText(text)) - self.setDirty() - self.updateComboBox() + self.set_dirty() + self.update_combo_box() # Tzutalin 20160906 : Add file list and dock to move faster - def fileitemDoubleClicked(self, item=None): + def file_item_double_clicked(self, item=None): current_index = self.mImgList.index(ustr(item.text())) if current_index < len(self.mImgList): filename = self.mImgList[current_index] if filename: - self.loadFile(filename) + self.load_file(filename) # Add chris - def btnstate(self, item=None): + def button_state(self, item=None): """ Function to handle difficult examples Update on each object """ if not self.canvas.editing(): return - item = self.currentItem() + item = self.current_item() if not item: # If not selected Item, take the first one item = self.labelList.item(self.labelList.count()-1) @@ -743,14 +743,14 @@ def btnstate(self, item=None): try: if difficult != shape.difficult: shape.difficult = difficult - self.setDirty() + self.set_dirty() else: # User probably changed item visibility self.canvas.setShapeVisible(shape, item.checkState() == Qt.Checked) except: pass # React to canvas signals. - def shapeSelectionChanged(self, selected=False): + def shape_selection_changed(self, selected=False): if self._noSelectionSlot: self._noSelectionSlot = False else: @@ -765,7 +765,7 @@ def shapeSelectionChanged(self, selected=False): self.actions.shapeLineColor.setEnabled(selected) self.actions.shapeFillColor.setEnabled(selected) - def addLabel(self, shape): + def add_label(self, shape): shape.paintLabel = self.displayLabelOption.isChecked() item = HashableQListWidgetItem(shape.label) item.setFlags(item.flags() | Qt.ItemIsUserCheckable) @@ -776,9 +776,9 @@ def addLabel(self, shape): self.labelList.addItem(item) for action in self.actions.onShapesPresent: action.setEnabled(True) - self.updateComboBox() + self.update_combo_box() - def remLabel(self, shape): + def remove_label(self, shape): if shape is None: # print('rm empty label') return @@ -786,9 +786,9 @@ def remLabel(self, shape): self.labelList.takeItem(self.labelList.row(item)) del self.shapesToItems[shape] del self.itemsToShapes[item] - self.updateComboBox() + self.update_combo_box() - def loadLabels(self, shapes): + def load_labels(self, shapes): s = [] for label, points, line_color, fill_color, difficult in shapes: shape = Shape(label=label) @@ -797,7 +797,7 @@ def loadLabels(self, shapes): # Ensure the labels are within the bounds of the image. If not, fix them. x, y, snapped = self.canvas.snapPointToCanvas(x, y) if snapped: - self.setDirty() + self.set_dirty() shape.addPoint(QPointF(x, y)) shape.difficult = difficult @@ -814,11 +814,11 @@ def loadLabels(self, shapes): else: shape.fill_color = generateColorByText(label) - self.addLabel(shape) - self.updateComboBox() + self.add_label(shape) + self.update_combo_box() self.canvas.loadShapes(s) - def updateComboBox(self): + def update_combo_box(self): # Get the unique labels and add them to the Combobox. items_text_list = [str(self.labelList.item(i).text()) for i in range(self.labelList.count())] @@ -829,7 +829,7 @@ def updateComboBox(self): self.comboBox.update_items(unique_text_list) - def saveLabels(self, annotation_file_path): + def save_labels(self, annotation_file_path): annotation_file_path = ustr(annotation_file_path) if self.labelFile is None: self.labelFile = LabelFile() @@ -841,7 +841,7 @@ def format_shape(s): fill_color=s.fill_color.getRgb(), points=[(p.x(), p.y()) for p in s.points], # add chris - difficult = s.difficult) + difficult=s.difficult) shapes = [format_shape(shape) for shape in self.canvas.shapes] # Can add different annotation formats here @@ -867,15 +867,15 @@ def format_shape(s): print('Image:{0} -> Annotation:{1}'.format(self.filePath, annotation_file_path)) return True except LabelFileError as e: - self.errorMessage(u'Error saving label data', u'%s' % e) + self.error_message(u'Error saving label data', u'%s' % e) return False - def copySelectedShape(self): - self.addLabel(self.canvas.copySelectedShape()) + def copy_selected_shape(self): + self.add_label(self.canvas.copySelectedShape()) # fix copy and delete - self.shapeSelectionChanged(True) + self.shape_selection_changed(True) - def comboSelectionChanged(self, index): + def combo_selection_changed(self, index): text = self.comboBox.cb.itemText(index) for i in range(self.labelList.count()): if text == "": @@ -885,8 +885,8 @@ def comboSelectionChanged(self, index): else: self.labelList.item(i).setCheckState(2) - def labelSelectionChanged(self): - item = self.currentItem() + def label_selection_changed(self): + item = self.current_item() if item and self.canvas.editing(): self._noSelectionSlot = True self.canvas.selectShape(self.itemsToShapes[item]) @@ -894,18 +894,18 @@ def labelSelectionChanged(self): # Add Chris self.diffcButton.setChecked(shape.difficult) - def labelItemChanged(self, item): + def label_item_changed(self, item): shape = self.itemsToShapes[item] label = item.text() if label != shape.label: shape.label = item.text() shape.line_color = generateColorByText(shape.label) - self.setDirty() + self.set_dirty() else: # User probably changed item visibility self.canvas.setShapeVisible(shape, item.checkState() == Qt.Checked) # Callback functions: - def newShape(self): + def new_shape(self): """Pop-up and give focus to the label editor. position MUST be in global coordinates. @@ -930,13 +930,13 @@ def newShape(self): self.prevLabelText = text generate_color = generateColorByText(text) shape = self.canvas.setLastLabel(text, generate_color, generate_color) - self.addLabel(shape) + self.add_label(shape) if self.beginner(): # Switch to edit mode. self.canvas.setEditing(True) self.actions.create.setEnabled(True) else: self.actions.editMode.setEnabled(True) - self.setDirty() + self.set_dirty() if text not in self.labelHist: self.labelHist.append(text) @@ -944,21 +944,21 @@ def newShape(self): # self.canvas.undoLastLine() self.canvas.resetAllLines() - def scrollRequest(self, delta, orientation): + def scroll_request(self, delta, orientation): units = - delta / (8 * 15) bar = self.scrollBars[orientation] bar.setValue(bar.value() + bar.singleStep() * units) - def setZoom(self, value): + def set_zoom(self, value): self.actions.fitWidth.setChecked(False) self.actions.fitWindow.setChecked(False) self.zoomMode = self.MANUAL_ZOOM self.zoomWidget.setValue(value) - def addZoom(self, increment=10): - self.setZoom(self.zoomWidget.value() + increment) + def add_zoom(self, increment=10): + self.set_zoom(self.zoomWidget.value() + increment) - def zoomRequest(self, delta): + def zoom_request(self, delta): # get the current scrollbar positions # calculate the percentages ~ coordinates h_bar = self.scrollBars[Qt.Horizontal] @@ -996,7 +996,7 @@ def zoomRequest(self, delta): # zoom in units = delta / (8 * 15) scale = 10 - self.addZoom(scale * units) + self.add_zoom(scale * units) # get the difference in scrollbar values # this is how far we can move @@ -1010,25 +1010,25 @@ def zoomRequest(self, delta): h_bar.setValue(new_h_bar_value) v_bar.setValue(new_v_bar_value) - def setFitWindow(self, value=True): + def set_fit_window(self, value=True): if value: self.actions.fitWidth.setChecked(False) self.zoomMode = self.FIT_WINDOW if value else self.MANUAL_ZOOM - self.adjustScale() + self.adjust_scale() - def setFitWidth(self, value=True): + def set_fit_width(self, value=True): if value: self.actions.fitWindow.setChecked(False) self.zoomMode = self.FIT_WIDTH if value else self.MANUAL_ZOOM - self.adjustScale() + self.adjust_scale() - def togglePolygons(self, value): + def toggle_polygons(self, value): for item, shape in self.itemsToShapes.items(): item.setCheckState(Qt.Checked if value else Qt.Unchecked) - def loadFile(self, file_path=None): + def load_file(self, file_path=None): """Load the specified file, or the last opened file if None.""" - self.resetState() + self.reset_state() self.canvas.setEnabled(False) if file_path is None: file_path = self.settings.get(SETTING_FILENAME) @@ -1055,10 +1055,10 @@ def loadFile(self, file_path=None): try: self.labelFile = LabelFile(unicode_file_path) except LabelFileError as e: - self.errorMessage(u'Error opening file', - (u"

%s

" - u"

Make sure %s is a valid label file.") - % (e, unicode_file_path)) + self.error_message(u'Error opening file', + (u"

%s

" + u"

Make sure %s is a valid label file.") + % (e, unicode_file_path)) self.status("Error reading %s" % unicode_file_path) return False self.imageData = self.labelFile.imageData @@ -1077,8 +1077,8 @@ def loadFile(self, file_path=None): else: image = QImage.fromData(self.imageData) if image.isNull(): - self.errorMessage(u'Error opening file', - u"

Make sure %s is a valid image file." % unicode_file_path) + self.error_message(u'Error opening file', + u"

Make sure %s is a valid image file." % unicode_file_path) self.status("Error reading %s" % unicode_file_path) return False self.status("Loaded %s" % os.path.basename(unicode_file_path)) @@ -1086,14 +1086,14 @@ def loadFile(self, file_path=None): self.filePath = unicode_file_path self.canvas.loadPixmap(QPixmap.fromImage(image)) if self.labelFile: - self.loadLabels(self.labelFile.shapes) - self.setClean() + self.load_labels(self.labelFile.shapes) + self.set_clean() self.canvas.setEnabled(True) - self.adjustScale(initial=True) - self.paintCanvas() - self.addRecentFile(self.filePath) - self.toggleActions(True) - self.showBoundingBoxFromAnnotationFile(file_path) + self.adjust_scale(initial=True) + self.paint_canvas() + self.add_recent_file(self.filePath) + self.toggle_actions(True) + self.show_bounding_box_from_annotation_file(file_path) self.setWindowTitle(__appname__ + ' ' + file_path) @@ -1106,10 +1106,10 @@ def loadFile(self, file_path=None): return True return False - def showBoundingBoxFromAnnotationFile(self, filePath): + def show_bounding_box_from_annotation_file(self, file_path): if self.defaultSaveDir is not None: - basename = os.path.basename(os.path.splitext(filePath)[0]) - file_dir = filePath.split(basename)[0].split(os.path.sep)[-2:-1][0] + basename = os.path.basename(os.path.splitext(file_path)[0]) + file_dir = file_path.split(basename)[0].split(os.path.sep)[-2:-1][0] xml_path = os.path.join(self.defaultSaveDir, basename + XML_EXT) txt_path = os.path.join(self.defaultSaveDir, basename + TXT_EXT) json_path = os.path.join(self.defaultSaveDir, file_dir + JSON_EXT) @@ -1118,38 +1118,38 @@ def showBoundingBoxFromAnnotationFile(self, filePath): PascalXML > YOLO """ if os.path.isfile(xml_path): - self.loadPascalXMLByFilename(xml_path) + self.load_pascal_xml_by_filename(xml_path) elif os.path.isfile(txt_path): - self.loadYOLOTXTByFilename(txt_path) + self.load_yolo_txt_by_filename(txt_path) elif os.path.isfile(json_path): - self.loadCreateMLJSONByFilename(json_path, filePath) + self.load_create_ml_json_by_filename(json_path, file_path) else: - xml_path = os.path.splitext(filePath)[0] + XML_EXT - txt_path = os.path.splitext(filePath)[0] + TXT_EXT + xml_path = os.path.splitext(file_path)[0] + XML_EXT + txt_path = os.path.splitext(file_path)[0] + TXT_EXT if os.path.isfile(xml_path): - self.loadPascalXMLByFilename(xml_path) + self.load_pascal_xml_by_filename(xml_path) elif os.path.isfile(txt_path): - self.loadYOLOTXTByFilename(txt_path) + self.load_yolo_txt_by_filename(txt_path) def resizeEvent(self, event): if self.canvas and not self.image.isNull()\ and self.zoomMode != self.MANUAL_ZOOM: - self.adjustScale() + self.adjust_scale() super(MainWindow, self).resizeEvent(event) - def paintCanvas(self): + def paint_canvas(self): assert not self.image.isNull(), "cannot paint null image" self.canvas.scale = 0.01 * self.zoomWidget.value() self.canvas.labelFontSize = int(0.02 * max(self.image.width(), self.image.height())) self.canvas.adjustSize() self.canvas.update() - def adjustScale(self, initial=False): + def adjust_scale(self, initial=False): value = self.scalers[self.FIT_WINDOW if initial else self.zoomMode]() self.zoomWidget.setValue(int(100 * value)) - def scaleFitWindow(self): + def scale_fit_window(self): """Figure out the size of the pixmap in order to fit the main widget.""" e = 2.0 # So that no scrollbars are generated. w1 = self.centralWidget().width() - e @@ -1161,16 +1161,16 @@ def scaleFitWindow(self): a2 = w2 / h2 return w1 / w2 if a2 >= a1 else h1 / h2 - def scaleFitWidth(self): + def scale_fit_width(self): # The epsilon does not seem to work too well here. w = self.centralWidget().width() - 2.0 return w / self.canvas.pixmap.width() def closeEvent(self, event): - if not self.mayContinue(): + if not self.may_continue(): event.ignore() settings = self.settings - # If it loads images from dir, don't load it at the begining + # If it loads images from dir, don't load it at the beginning if self.dirname is None: settings[SETTING_FILENAME] = self.filePath if self.filePath else '' else: @@ -1200,15 +1200,15 @@ def closeEvent(self, event): settings[SETTING_LABEL_FILE_FORMAT] = self.labelFileFormat settings.save() - def loadRecent(self, filename): - if self.mayContinue(): - self.loadFile(filename) + def load_recent(self, filename): + if self.may_continue(): + self.load_file(filename) - def scanAllImages(self, folderPath): + def scan_all_images(self, folder_path): extensions = ['.%s' % fmt.data().decode("ascii").lower() for fmt in QImageReader.supportedImageFormats()] images = [] - for root, dirs, files in os.walk(folderPath): + for root, dirs, files in os.walk(folder_path): for file in files: if file.lower().endswith(tuple(extensions)): relative_path = os.path.join(root, file) @@ -1217,7 +1217,7 @@ def scanAllImages(self, folderPath): natural_sort(images, key=lambda x: x.lower()) return images - def changeSavedirDialog(self, _value=False): + def change_save_dir_dialog(self, _value=False): if self.defaultSaveDir is not None: path = ustr(self.defaultSaveDir) else: @@ -1234,7 +1234,7 @@ def changeSavedirDialog(self, _value=False): ('Change saved folder', self.defaultSaveDir)) self.statusBar().show() - def openAnnotationDialog(self, _value=False): + def open_annotation_dialog(self, _value=False): if self.filePath is None: self.statusBar().showMessage('Please select image first') self.statusBar().show() @@ -1244,73 +1244,73 @@ def openAnnotationDialog(self, _value=False): if self.filePath else '.' if self.labelFileFormat == LabelFileFormat.PASCAL_VOC: filters = "Open Annotation XML file (%s)" % ' '.join(['*.xml']) - filename = ustr(QFileDialog.getOpenFileName(self,'%s - Choose a xml file' % __appname__, path, filters)) + filename = ustr(QFileDialog.getOpenFileName(self, '%s - Choose a xml file' % __appname__, path, filters)) if filename: if isinstance(filename, (tuple, list)): filename = filename[0] - self.loadPascalXMLByFilename(filename) + self.load_pascal_xml_by_filename(filename) - def openDirDialog(self, _value=False, dirpath=None, silent=False): - if not self.mayContinue(): + def open_dir_dialog(self, _value=False, dir_path=None, silent=False): + if not self.may_continue(): return - default_open_dir_path = dirpath if dirpath else '.' + default_open_dir_path = dir_path if dir_path else '.' if self.lastOpenDir and os.path.exists(self.lastOpenDir): default_open_dir_path = self.lastOpenDir else: default_open_dir_path = os.path.dirname(self.filePath) if self.filePath else '.' - if silent!=True : + if silent != True: target_dir_path = ustr(QFileDialog.getExistingDirectory(self, '%s - Open Directory' % __appname__, default_open_dir_path, QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks)) else: target_dir_path = ustr(default_open_dir_path) self.lastOpenDir = target_dir_path - self.importDirImages(target_dir_path) + self.import_dir_images(target_dir_path) - def importDirImages(self, dirpath): - if not self.mayContinue() or not dirpath: + def import_dir_images(self, dir_path): + if not self.may_continue() or not dir_path: return - self.lastOpenDir = dirpath - self.dirname = dirpath + self.lastOpenDir = dir_path + self.dirname = dir_path self.filePath = None self.fileListWidget.clear() - self.mImgList = self.scanAllImages(dirpath) - self.openNextImg() + self.mImgList = self.scan_all_images(dir_path) + self.open_next_image() for imgPath in self.mImgList: item = QListWidgetItem(imgPath) self.fileListWidget.addItem(item) - def verifyImg(self, _value=False): - # Proceding next image without dialog if having any label + def verify_image(self, _value=False): + # Proceeding next image without dialog if having any label if self.filePath is not None: try: self.labelFile.toggleVerify() except AttributeError: # If the labelling file does not exist yet, create if and # re-save it with the verified attribute. - self.saveFile() - if self.labelFile != None: + self.save_file() + if self.labelFile is not None: self.labelFile.toggleVerify() else: return self.canvas.verified = self.labelFile.verified - self.paintCanvas() - self.saveFile() + self.paint_canvas() + self.save_file() - def openPrevImg(self, _value=False): - # Proceding prev image without dialog if having any label + def open_prev_image(self, _value=False): + # Proceeding prev image without dialog if having any label if self.autoSaving.isChecked(): if self.defaultSaveDir is not None: if self.dirty is True: - self.saveFile() + self.save_file() else: - self.changeSavedirDialog() + self.change_save_dir_dialog() return - if not self.mayContinue(): + if not self.may_continue(): return if len(self.mImgList) <= 0: @@ -1323,19 +1323,19 @@ def openPrevImg(self, _value=False): if current_index - 1 >= 0: filename = self.mImgList[current_index - 1] if filename: - self.loadFile(filename) + self.load_file(filename) - def openNextImg(self, _value=False): - # Proceding prev image without dialog if having any label + def open_next_image(self, _value=False): + # Proceeding prev image without dialog if having any label if self.autoSaving.isChecked(): if self.defaultSaveDir is not None: if self.dirty is True: - self.saveFile() + self.save_file() else: - self.changeSavedirDialog() + self.change_save_dir_dialog() return - if not self.mayContinue(): + if not self.may_continue(): return if len(self.mImgList) <= 0: @@ -1350,10 +1350,10 @@ def openNextImg(self, _value=False): filename = self.mImgList[current_index + 1] if filename: - self.loadFile(filename) + self.load_file(filename) - def openFile(self, _value=False): - if not self.mayContinue(): + def open_file(self, _value=False): + if not self.may_continue(): return path = os.path.dirname(ustr(self.filePath)) if self.filePath else '.' formats = ['*.%s' % fmt.data().decode("ascii").lower() for fmt in QImageReader.supportedImageFormats()] @@ -1362,31 +1362,31 @@ def openFile(self, _value=False): if filename: if isinstance(filename, (tuple, list)): filename = filename[0] - self.loadFile(filename) + self.load_file(filename) - def saveFile(self, _value=False): + def save_file(self, _value=False): if self.defaultSaveDir is not None and len(ustr(self.defaultSaveDir)): if self.filePath: image_file_name = os.path.basename(self.filePath) saved_file_name = os.path.splitext(image_file_name)[0] saved_path = os.path.join(ustr(self.defaultSaveDir), saved_file_name) - self._saveFile(saved_path) + self._save_file(saved_path) else: image_file_dir = os.path.dirname(self.filePath) image_file_name = os.path.basename(self.filePath) saved_file_name = os.path.splitext(image_file_name)[0] saved_path = os.path.join(image_file_dir, saved_file_name) - self._saveFile(saved_path if self.labelFile - else self.saveFileDialog(removeExt=False)) + self._save_file(saved_path if self.labelFile + else self.save_file_dialog(remove_ext=False)) - def saveFileAs(self, _value=False): + def save_file_as(self, _value=False): assert not self.image.isNull(), "cannot save empty image" - self._saveFile(self.saveFileDialog()) + self._save_file(self.save_file_dialog()) - def saveFileDialog(self, removeExt=True): + def save_file_dialog(self, remove_ext=True): caption = '%s - Choose File' % __appname__ filters = 'File (*%s)' % LabelFile.suffix - open_dialog_path = self.currentPath() + open_dialog_path = self.current_path() dlg = QFileDialog(self, caption, open_dialog_path, filters) dlg.setDefaultSuffix(LabelFile.suffix[1:]) dlg.setAcceptMode(QFileDialog.AcceptSave) @@ -1395,67 +1395,67 @@ def saveFileDialog(self, removeExt=True): dlg.setOption(QFileDialog.DontUseNativeDialog, False) if dlg.exec_(): full_file_path = ustr(dlg.selectedFiles()[0]) - if removeExt: - return os.path.splitext(full_file_path)[0] # Return file path without the extension. + if remove_ext: + return os.path.splitext(full_file_path)[0] # Return file path without the extension. else: return full_file_path return '' - def _saveFile(self, annotationFilePath): - if annotationFilePath and self.saveLabels(annotationFilePath): - self.setClean() - self.statusBar().showMessage('Saved to %s' % annotationFilePath) + def _save_file(self, annotation_file_path): + if annotation_file_path and self.save_labels(annotation_file_path): + self.set_clean() + self.statusBar().showMessage('Saved to %s' % annotation_file_path) self.statusBar().show() - def closeFile(self, _value=False): - if not self.mayContinue(): + def close_file(self, _value=False): + if not self.may_continue(): return - self.resetState() - self.setClean() - self.toggleActions(False) + self.reset_state() + self.set_clean() + self.toggle_actions(False) self.canvas.setEnabled(False) self.actions.saveAs.setEnabled(False) - def deleteImg(self): + def delete_image(self): delete_path = self.filePath if delete_path is not None: - self.openNextImg() + self.open_next_image() if os.path.exists(delete_path): os.remove(delete_path) - self.importDirImages(self.lastOpenDir) + self.import_dir_images(self.lastOpenDir) - def resetAll(self): + def reset_all(self): self.settings.reset() self.close() proc = QProcess() proc.startDetached(os.path.abspath(__file__)) - def mayContinue(self): + def may_continue(self): if not self.dirty: return True else: - discard_changes = self.discardChangesDialog() + discard_changes = self.discard_changes_dialog() if discard_changes == QMessageBox.No: return True elif discard_changes == QMessageBox.Yes: - self.saveFile() + self.save_file() return True else: return False - def discardChangesDialog(self): + def discard_changes_dialog(self): yes, no, cancel = QMessageBox.Yes, QMessageBox.No, QMessageBox.Cancel msg = u'You have unsaved changes, would you like to save them and proceed?\nClick "No" to undo all changes.' return QMessageBox.warning(self, u'Attention', msg, yes | no | cancel) - def errorMessage(self, title, message): + def error_message(self, title, message): return QMessageBox.critical(self, title, '

%s

%s' % (title, message)) - def currentPath(self): + def current_path(self): return os.path.dirname(self.filePath) if self.filePath else '.' - def chooseColor1(self): + def choose_color1(self): color = self.colorDialog.getColor(self.lineColor, u'Choose line color', default=DEFAULT_LINE_COLOR) if color: @@ -1463,43 +1463,43 @@ def chooseColor1(self): Shape.line_color = color self.canvas.setDrawingColor(color) self.canvas.update() - self.setDirty() + self.set_dirty() - def deleteSelectedShape(self): - self.remLabel(self.canvas.deleteSelected()) - self.setDirty() - if self.noShapes(): + def delete_selected_shape(self): + self.remove_label(self.canvas.deleteSelected()) + self.set_dirty() + if self.no_shapes(): for action in self.actions.onShapesPresent: action.setEnabled(False) - def chshapeLineColor(self): + def choose_shape_line_color(self): color = self.colorDialog.getColor(self.lineColor, u'Choose line color', default=DEFAULT_LINE_COLOR) if color: self.canvas.selectedShape.line_color = color self.canvas.update() - self.setDirty() + self.set_dirty() - def chshapeFillColor(self): + def choose_shape_fill_color(self): color = self.colorDialog.getColor(self.fillColor, u'Choose fill color', default=DEFAULT_FILL_COLOR) if color: self.canvas.selectedShape.fill_color = color self.canvas.update() - self.setDirty() + self.set_dirty() - def copyShape(self): + def copy_shape(self): self.canvas.endMove(copy=True) - self.addLabel(self.canvas.selectedShape) - self.setDirty() + self.add_label(self.canvas.selectedShape) + self.set_dirty() - def moveShape(self): + def move_shape(self): self.canvas.endMove(copy=False) - self.setDirty() + self.set_dirty() - def loadPredefinedClasses(self, predefClassesFile): - if os.path.exists(predefClassesFile) is True: - with codecs.open(predefClassesFile, 'r', 'utf8') as f: + def load_predefined_classes(self, predef_classes_file): + if os.path.exists(predef_classes_file) is True: + with codecs.open(predef_classes_file, 'r', 'utf8') as f: for line in f: line = line.strip() if self.labelHist is None: @@ -1507,57 +1507,57 @@ def loadPredefinedClasses(self, predefClassesFile): else: self.labelHist.append(line) - def loadPascalXMLByFilename(self, xmlPath): + def load_pascal_xml_by_filename(self, xml_path): if self.filePath is None: return - if os.path.isfile(xmlPath) is False: + if os.path.isfile(xml_path) is False: return self.set_format(FORMAT_PASCALVOC) - t_voc_parse_reader = PascalVocReader(xmlPath) + t_voc_parse_reader = PascalVocReader(xml_path) shapes = t_voc_parse_reader.getShapes() - self.loadLabels(shapes) + self.load_labels(shapes) self.canvas.verified = t_voc_parse_reader.verified - def loadYOLOTXTByFilename(self, txtPath): + def load_yolo_txt_by_filename(self, txt_path): if self.filePath is None: return - if os.path.isfile(txtPath) is False: + if os.path.isfile(txt_path) is False: return self.set_format(FORMAT_YOLO) - t_yolo_parse_reader = YoloReader(txtPath, self.image) + t_yolo_parse_reader = YoloReader(txt_path, self.image) shapes = t_yolo_parse_reader.getShapes() - print (shapes) - self.loadLabels(shapes) + print(shapes) + self.load_labels(shapes) self.canvas.verified = t_yolo_parse_reader.verified - def loadCreateMLJSONByFilename(self, jsonPath, filePath): + def load_create_ml_json_by_filename(self, json_path, file_path): if self.filePath is None: return - if os.path.isfile(jsonPath) is False: + if os.path.isfile(json_path) is False: return self.set_format(FORMAT_CREATEML) - crml_parse_reader = CreateMLReader(jsonPath, filePath) - shapes = crml_parse_reader.get_shapes() - self.loadLabels(shapes) - self.canvas.verified = crml_parse_reader.verified + create_ml_parse_reader = CreateMLReader(json_path, file_path) + shapes = create_ml_parse_reader.get_shapes() + self.load_labels(shapes) + self.canvas.verified = create_ml_parse_reader.verified - def copyPreviousBoundingBoxes(self): + def copy_previous_bounding_boxes(self): current_index = self.mImgList.index(self.filePath) if current_index - 1 >= 0: prev_file_path = self.mImgList[current_index - 1] - self.showBoundingBoxFromAnnotationFile(prev_file_path) - self.saveFile() + self.show_bounding_box_from_annotation_file(prev_file_path) + self.save_file() - def togglePaintLabelsOption(self): + def toggle_paint_labels_option(self): for shape in self.canvas.shapes: shape.paintLabel = self.displayLabelOption.isChecked() - def toogleDrawSquare(self): + def toggle_draw_square(self): self.canvas.setDrawingShapeToSquare(self.drawSquaresOption.isChecked()) def inverted(color): diff --git a/libs/combobox.py b/libs/combobox.py index 298bfa06a..8743b648e 100644 --- a/libs/combobox.py +++ b/libs/combobox.py @@ -21,7 +21,7 @@ def __init__(self, parent=None, items=[]): self.items = items self.cb.addItems(self.items) - self.cb.currentIndexChanged.connect(parent.comboSelectionChanged) + self.cb.currentIndexChanged.connect(parent.combo_selection_changed) layout.addWidget(self.cb) self.setLayout(layout) From 9582b53d792163fbf722f5536aa263db0d9a1523 Mon Sep 17 00:00:00 2001 From: Cerno_b Date: Mon, 8 Mar 2021 02:15:59 +0100 Subject: [PATCH 04/13] Rename functions and variables in canvas.py --- labelImg.py | 50 ++++---- libs/canvas.py | 314 ++++++++++++++++++++++++------------------------- 2 files changed, 182 insertions(+), 182 deletions(-) diff --git a/labelImg.py b/labelImg.py index c54834d94..651a59a21 100755 --- a/labelImg.py +++ b/labelImg.py @@ -177,7 +177,7 @@ def __init__(self, default_filename=None, default_prefdef_class_file=None, defau self.canvas = Canvas(parent=self) self.canvas.zoomRequest.connect(self.zoom_request) - self.canvas.setDrawingShapeToSquare(settings.get(SETTING_DRAW_SQUARE, False)) + self.canvas.set_drawing_shape_to_square(settings.get(SETTING_DRAW_SQUARE, False)) scroll = QScrollArea() scroll.setWidget(self.canvas) @@ -470,7 +470,7 @@ def get_format_meta(format): 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.canvas.set_drawing_color(self.lineColor) # Add chris Shape.difficult = self.difficult @@ -507,12 +507,12 @@ def xbool(x): def keyReleaseEvent(self, event): if event.key() == Qt.Key_Control: - self.canvas.setDrawingShapeToSquare(False) + self.canvas.set_drawing_shape_to_square(False) def keyPressEvent(self, event): if event.key() == Qt.Key_Control: # Draw rectangle if Ctrl is pressed - self.canvas.setDrawingShapeToSquare(True) + self.canvas.set_drawing_shape_to_square(True) # Support Functions # def set_format(self, save_format): @@ -550,7 +550,7 @@ def no_shapes(self): def toggle_advanced_mode(self, value=True): self._beginner = not value - self.canvas.setEditing(True) + self.canvas.set_editing(True) self.populate_mode_actions() self.editButton.setVisible(not value) if value: @@ -611,7 +611,7 @@ def reset_state(self): self.filePath = None self.imageData = None self.labelFile = None - self.canvas.resetState() + self.canvas.reset_state() self.labelCoordinates.clear() self.comboBox.cb.clear() @@ -655,7 +655,7 @@ def show_info_dialog(self): def create_shape(self): assert self.beginner() - self.canvas.setEditing(False) + self.canvas.set_editing(False) self.actions.create.setEnabled(False) def toggle_drawing_sensitive(self, drawing=True): @@ -664,12 +664,12 @@ def toggle_drawing_sensitive(self, drawing=True): if not drawing and self.beginner(): # Cancel creation. print('Cancel creation.') - self.canvas.setEditing(True) - self.canvas.restoreCursor() + self.canvas.set_editing(True) + self.canvas.restore_cursor() self.actions.create.setEnabled(True) def toggle_draw_mode(self, edit=True): - self.canvas.setEditing(edit) + self.canvas.set_editing(edit) self.actions.createMode.setEnabled(edit) self.actions.editMode.setEnabled(not edit) @@ -745,7 +745,7 @@ def button_state(self, item=None): shape.difficult = difficult self.set_dirty() else: # User probably changed item visibility - self.canvas.setShapeVisible(shape, item.checkState() == Qt.Checked) + self.canvas.set_shape_visible(shape, item.checkState() == Qt.Checked) except: pass @@ -795,7 +795,7 @@ def load_labels(self, shapes): for x, y in points: # Ensure the labels are within the bounds of the image. If not, fix them. - x, y, snapped = self.canvas.snapPointToCanvas(x, y) + x, y, snapped = self.canvas.snap_point_to_canvas(x, y) if snapped: self.set_dirty() @@ -816,7 +816,7 @@ def load_labels(self, shapes): self.add_label(shape) self.update_combo_box() - self.canvas.loadShapes(s) + self.canvas.load_shapes(s) def update_combo_box(self): # Get the unique labels and add them to the Combobox. @@ -871,7 +871,7 @@ def format_shape(s): return False def copy_selected_shape(self): - self.add_label(self.canvas.copySelectedShape()) + self.add_label(self.canvas.copy_selected_shape()) # fix copy and delete self.shape_selection_changed(True) @@ -889,7 +889,7 @@ def label_selection_changed(self): item = self.current_item() if item and self.canvas.editing(): self._noSelectionSlot = True - self.canvas.selectShape(self.itemsToShapes[item]) + self.canvas.select_shape(self.itemsToShapes[item]) shape = self.itemsToShapes[item] # Add Chris self.diffcButton.setChecked(shape.difficult) @@ -902,7 +902,7 @@ def label_item_changed(self, item): shape.line_color = generateColorByText(shape.label) self.set_dirty() else: # User probably changed item visibility - self.canvas.setShapeVisible(shape, item.checkState() == Qt.Checked) + self.canvas.set_shape_visible(shape, item.checkState() == Qt.Checked) # Callback functions: def new_shape(self): @@ -929,10 +929,10 @@ def new_shape(self): if text is not None: self.prevLabelText = text generate_color = generateColorByText(text) - shape = self.canvas.setLastLabel(text, generate_color, generate_color) + shape = self.canvas.set_last_label(text, generate_color, generate_color) self.add_label(shape) if self.beginner(): # Switch to edit mode. - self.canvas.setEditing(True) + self.canvas.set_editing(True) self.actions.create.setEnabled(True) else: self.actions.editMode.setEnabled(True) @@ -942,7 +942,7 @@ def new_shape(self): self.labelHist.append(text) else: # self.canvas.undoLastLine() - self.canvas.resetAllLines() + self.canvas.reset_all_lines() def scroll_request(self, delta, orientation): units = - delta / (8 * 15) @@ -1084,7 +1084,7 @@ def load_file(self, file_path=None): self.status("Loaded %s" % os.path.basename(unicode_file_path)) self.image = image self.filePath = unicode_file_path - self.canvas.loadPixmap(QPixmap.fromImage(image)) + self.canvas.load_pixmap(QPixmap.fromImage(image)) if self.labelFile: self.load_labels(self.labelFile.shapes) self.set_clean() @@ -1461,12 +1461,12 @@ def choose_color1(self): if color: self.lineColor = color Shape.line_color = color - self.canvas.setDrawingColor(color) + self.canvas.set_drawing_color(color) self.canvas.update() self.set_dirty() def delete_selected_shape(self): - self.remove_label(self.canvas.deleteSelected()) + self.remove_label(self.canvas.delete_selected()) self.set_dirty() if self.no_shapes(): for action in self.actions.onShapesPresent: @@ -1489,12 +1489,12 @@ def choose_shape_fill_color(self): self.set_dirty() def copy_shape(self): - self.canvas.endMove(copy=True) + self.canvas.end_move(copy=True) self.add_label(self.canvas.selectedShape) self.set_dirty() def move_shape(self): - self.canvas.endMove(copy=False) + self.canvas.end_move(copy=False) self.set_dirty() def load_predefined_classes(self, predef_classes_file): @@ -1558,7 +1558,7 @@ def toggle_paint_labels_option(self): shape.paintLabel = self.displayLabelOption.isChecked() def toggle_draw_square(self): - self.canvas.setDrawingShapeToSquare(self.drawSquaresOption.isChecked()) + self.canvas.set_drawing_shape_to_square(self.drawSquaresOption.isChecked()) def inverted(color): return QColor(*[255 - v for v in color.getRgb()]) diff --git a/libs/canvas.py b/libs/canvas.py index 23c5b823d..20e33cc7e 100644 --- a/libs/canvas.py +++ b/libs/canvas.py @@ -7,7 +7,7 @@ from PyQt4.QtGui import * from PyQt4.QtCore import * -#from PyQt4.QtOpenGL import * +# from PyQt4.QtOpenGL import * from libs.shape import Shape from libs.utils import distance @@ -64,21 +64,21 @@ def __init__(self, *args, **kwargs): self.verified = False self.drawSquare = False - #initialisation for panning + # initialisation for panning self.pan_initial_pos = QPoint() - def setDrawingColor(self, qColor): - self.drawingLineColor = qColor - self.drawingRectColor = qColor + def set_drawing_color(self, qcolor): + self.drawingLineColor = qcolor + self.drawingRectColor = qcolor def enterEvent(self, ev): - self.overrideCursor(self._cursor) + self.override_cursor(self._cursor) def leaveEvent(self, ev): - self.restoreCursor() + self.restore_cursor() def focusOutEvent(self, ev): - self.restoreCursor() + self.restore_cursor() def isVisible(self, shape): return self.visible.get(shape, True) @@ -89,25 +89,25 @@ def drawing(self): def editing(self): return self.mode == self.EDIT - def setEditing(self, value=True): + def set_editing(self, value=True): self.mode = self.EDIT if value else self.CREATE if not value: # Create - self.unHighlight() - self.deSelectShape() + self.un_highlight() + self.de_select_shape() self.prevPoint = QPointF() self.repaint() - def unHighlight(self): + def un_highlight(self): if self.hShape: self.hShape.highlightClear() self.hVertex = self.hShape = None - def selectedVertex(self): + def selected_vertex(self): return self.hVertex is not None def mouseMoveEvent(self, ev): """Update line with last point and current coordinates.""" - pos = self.transformPos(ev.pos()) + pos = self.transform_pos(ev.pos()) # Update coordinates in status bar if image is opened window = self.parent().window() @@ -117,16 +117,16 @@ def mouseMoveEvent(self, ev): # Polygon drawing. if self.drawing(): - self.overrideCursor(CURSOR_DRAW) + self.override_cursor(CURSOR_DRAW) if self.current: # Display annotation width and height while drawing - currentWidth = abs(self.current[0].x() - pos.x()) - currentHeight = abs(self.current[0].y() - pos.y()) + current_width = abs(self.current[0].x() - pos.x()) + current_height = abs(self.current[0].y() - pos.y()) self.parent().window().labelCoordinates.setText( - 'Width: %d, Height: %d / X: %d; Y: %d' % (currentWidth, currentHeight, pos.x(), pos.y())) + 'Width: %d, Height: %d / X: %d; Y: %d' % (current_width, current_height, pos.x(), pos.y())) color = self.drawingLineColor - if self.outOfPixmap(pos): + if self.out_of_pixmap(pos): # Don't allow the user to draw outside the pixmap. # Clip the coordinates to 0 or max, # if they are outside the range [0, max] @@ -134,22 +134,22 @@ def mouseMoveEvent(self, ev): clipped_x = min(max(0, pos.x()), size.width()) clipped_y = min(max(0, pos.y()), size.height()) pos = QPointF(clipped_x, clipped_y) - elif len(self.current) > 1 and self.closeEnough(pos, self.current[0]): + elif len(self.current) > 1 and self.close_enough(pos, self.current[0]): # Attract line to starting point and colorise to alert the # user: pos = self.current[0] color = self.current.line_color - self.overrideCursor(CURSOR_POINT) + self.override_cursor(CURSOR_POINT) self.current.highlightVertex(0, Shape.NEAR_VERTEX) if self.drawSquare: - initPos = self.current[0] - minX = initPos.x() - minY = initPos.y() - min_size = min(abs(pos.x() - minX), abs(pos.y() - minY)) - directionX = -1 if pos.x() - minX < 0 else 1 - directionY = -1 if pos.y() - minY < 0 else 1 - self.line[1] = QPointF(minX + directionX * min_size, minY + directionY * min_size) + init_pos = self.current[0] + min_x = init_pos.x() + min_y = init_pos.y() + min_size = min(abs(pos.x() - min_x), abs(pos.y() - min_y)) + direction_x = -1 if pos.x() - min_x < 0 else 1 + direction_y = -1 if pos.y() - min_y < 0 else 1 + self.line[1] = QPointF(min_x + direction_x * min_size, min_y + direction_y * min_size) else: self.line[1] = pos @@ -164,8 +164,8 @@ def mouseMoveEvent(self, ev): # Polygon copy moving. if Qt.RightButton & ev.buttons(): if self.selectedShapeCopy and self.prevPoint: - self.overrideCursor(CURSOR_MOVE) - self.boundedMoveShape(self.selectedShapeCopy, pos) + self.override_cursor(CURSOR_MOVE) + self.bounded_move_shape(self.selectedShapeCopy, pos) self.repaint() elif self.selectedShape: self.selectedShapeCopy = self.selectedShape.copy() @@ -174,17 +174,17 @@ def mouseMoveEvent(self, ev): # Polygon/Vertex moving. if Qt.LeftButton & ev.buttons(): - if self.selectedVertex(): - self.boundedMoveVertex(pos) + if self.selected_vertex(): + self.bounded_move_vertex(pos) self.shapeMoved.emit() self.repaint() elif self.selectedShape and self.prevPoint: - self.overrideCursor(CURSOR_MOVE) - self.boundedMoveShape(self.selectedShape, pos) + self.override_cursor(CURSOR_MOVE) + self.bounded_move_shape(self.selectedShape, pos) self.shapeMoved.emit() self.repaint() else: - #pan + # pan delta_x = pos.x() - self.pan_initial_pos.x() delta_y = pos.y() - self.pan_initial_pos.y() self.scrollRequest.emit(delta_x, Qt.Horizontal) @@ -192,7 +192,7 @@ def mouseMoveEvent(self, ev): self.update() return - # Just hovering over the canvas, 2 posibilities: + # Just hovering over the canvas, 2 possibilities: # - Highlight shapes # - Highlight vertex # Update shape/vertex fill and tooltip value accordingly. @@ -202,23 +202,23 @@ def mouseMoveEvent(self, ev): # check if we happen to be inside a shape. index = shape.nearestVertex(pos, self.epsilon) if index is not None: - if self.selectedVertex(): + if self.selected_vertex(): self.hShape.highlightClear() self.hVertex, self.hShape = index, shape shape.highlightVertex(index, shape.MOVE_VERTEX) - self.overrideCursor(CURSOR_POINT) + self.override_cursor(CURSOR_POINT) self.setToolTip("Click & drag to move point") self.setStatusTip(self.toolTip()) self.update() break elif shape.containsPoint(pos): - if self.selectedVertex(): + if self.selected_vertex(): self.hShape.highlightClear() self.hVertex, self.hShape = None, shape self.setToolTip( "Click & drag to move shape '%s'" % shape.label) self.setStatusTip(self.toolTip()) - self.overrideCursor(CURSOR_GRAB) + self.override_cursor(CURSOR_GRAB) self.update() break else: # Nothing found, clear highlights, reset state. @@ -226,55 +226,55 @@ def mouseMoveEvent(self, ev): self.hShape.highlightClear() self.update() self.hVertex, self.hShape = None, None - self.overrideCursor(CURSOR_DEFAULT) + self.override_cursor(CURSOR_DEFAULT) def mousePressEvent(self, ev): - pos = self.transformPos(ev.pos()) + pos = self.transform_pos(ev.pos()) if ev.button() == Qt.LeftButton: if self.drawing(): - self.handleDrawing(pos) + self.handle_drawing(pos) else: - selection = self.selectShapePoint(pos) + selection = self.select_shape_point(pos) self.prevPoint = pos if selection is None: - #pan + # pan QApplication.setOverrideCursor(QCursor(Qt.OpenHandCursor)) self.pan_initial_pos = pos elif ev.button() == Qt.RightButton and self.editing(): - self.selectShapePoint(pos) + self.select_shape_point(pos) self.prevPoint = pos self.update() def mouseReleaseEvent(self, ev): if ev.button() == Qt.RightButton: menu = self.menus[bool(self.selectedShapeCopy)] - self.restoreCursor() + self.restore_cursor() if not menu.exec_(self.mapToGlobal(ev.pos()))\ and self.selectedShapeCopy: # Cancel the move by deleting the shadow copy. self.selectedShapeCopy = None self.repaint() elif ev.button() == Qt.LeftButton and self.selectedShape: - if self.selectedVertex(): - self.overrideCursor(CURSOR_POINT) + if self.selected_vertex(): + self.override_cursor(CURSOR_POINT) else: - self.overrideCursor(CURSOR_GRAB) + self.override_cursor(CURSOR_GRAB) elif ev.button() == Qt.LeftButton: - pos = self.transformPos(ev.pos()) + pos = self.transform_pos(ev.pos()) if self.drawing(): - self.handleDrawing(pos) + self.handle_drawing(pos) else: - #pan + # pan QApplication.restoreOverrideCursor() - def endMove(self, copy=False): + def end_move(self, copy=False): assert self.selectedShape and self.selectedShapeCopy shape = self.selectedShapeCopy - #del shape.fill_color - #del shape.line_color + # del shape.fill_color + # del shape.line_color if copy: self.shapes.append(shape) self.selectedShape.selected = False @@ -284,71 +284,71 @@ def endMove(self, copy=False): self.selectedShape.points = [p for p in shape.points] self.selectedShapeCopy = None - def hideBackroundShapes(self, value): + def hide_background_shapes(self, value): self.hideBackround = value if self.selectedShape: # Only hide other shapes if there is a current selection. # Otherwise the user will not be able to select a shape. - self.setHiding(True) + self.set_hiding(True) self.repaint() - def handleDrawing(self, pos): + def handle_drawing(self, pos): if self.current and self.current.reachMaxPoints() is False: - initPos = self.current[0] - minX = initPos.x() - minY = initPos.y() - targetPos = self.line[1] - maxX = targetPos.x() - maxY = targetPos.y() - self.current.addPoint(QPointF(maxX, minY)) - self.current.addPoint(targetPos) - self.current.addPoint(QPointF(minX, maxY)) + init_pos = self.current[0] + min_x = init_pos.x() + min_y = init_pos.y() + target_pos = self.line[1] + max_x = target_pos.x() + max_y = target_pos.y() + self.current.addPoint(QPointF(max_x, min_y)) + self.current.addPoint(target_pos) + self.current.addPoint(QPointF(min_x, max_y)) self.finalise() - elif not self.outOfPixmap(pos): + elif not self.out_of_pixmap(pos): self.current = Shape() self.current.addPoint(pos) self.line.points = [pos, pos] - self.setHiding() + self.set_hiding() self.drawingPolygon.emit(True) self.update() - def setHiding(self, enable=True): + def set_hiding(self, enable=True): self._hideBackround = self.hideBackround if enable else False - def canCloseShape(self): + def can_close_shape(self): return self.drawing() and self.current and len(self.current) > 2 def mouseDoubleClickEvent(self, ev): # We need at least 4 points here, since the mousePress handler # adds an extra one before this handler is called. - if self.canCloseShape() and len(self.current) > 3: + if self.can_close_shape() and len(self.current) > 3: self.current.popPoint() self.finalise() - def selectShape(self, shape): - self.deSelectShape() + def select_shape(self, shape): + self.de_select_shape() shape.selected = True self.selectedShape = shape - self.setHiding() + self.set_hiding() self.selectionChanged.emit(True) self.update() - def selectShapePoint(self, point): + def select_shape_point(self, point): """Select the first shape created which contains this point.""" - self.deSelectShape() - if self.selectedVertex(): # A vertex is marked for selection. + self.de_select_shape() + if self.selected_vertex(): # A vertex is marked for selection. index, shape = self.hVertex, self.hShape shape.highlightVertex(index, shape.MOVE_VERTEX) - self.selectShape(shape) + self.select_shape(shape) return self.hVertex for shape in reversed(self.shapes): if self.isVisible(shape) and shape.containsPoint(point): - self.selectShape(shape) - self.calculateOffsets(shape, point) + self.select_shape(shape) + self.calculate_offsets(shape, point) return self.selectedShape return None - def calculateOffsets(self, shape, point): + def calculate_offsets(self, shape, point): rect = shape.boundingRect() x1 = rect.x() - point.x() y1 = rect.y() - point.y() @@ -356,7 +356,7 @@ def calculateOffsets(self, shape, point): y2 = (rect.y() + rect.height()) - point.y() self.offsets = QPointF(x1, y1), QPointF(x2, y2) - def snapPointToCanvas(self, x, y): + def snap_point_to_canvas(self, x, y): """ Moves a point x,y to within the boundaries of the canvas. :return: (x,y,snapped) where snapped is True if x or y were changed, False if not. @@ -370,10 +370,10 @@ def snapPointToCanvas(self, x, y): return x, y, False - def boundedMoveVertex(self, pos): + def bounded_move_vertex(self, pos): index, shape = self.hVertex, self.hShape point = shape[index] - if self.outOfPixmap(pos): + if self.out_of_pixmap(pos): size = self.pixmap.size() clipped_x = min(max(0, pos.x()), size.width()) clipped_y = min(max(0, pos.y()), size.height()) @@ -384,43 +384,43 @@ def boundedMoveVertex(self, pos): opposite_point = shape[opposite_point_index] min_size = min(abs(pos.x() - opposite_point.x()), abs(pos.y() - opposite_point.y())) - directionX = -1 if pos.x() - opposite_point.x() < 0 else 1 - directionY = -1 if pos.y() - opposite_point.y() < 0 else 1 - shiftPos = QPointF(opposite_point.x() + directionX * min_size - point.x(), - opposite_point.y() + directionY * min_size - point.y()) + direction_x = -1 if pos.x() - opposite_point.x() < 0 else 1 + direction_y = -1 if pos.y() - opposite_point.y() < 0 else 1 + shift_pos = QPointF(opposite_point.x() + direction_x * min_size - point.x(), + opposite_point.y() + direction_y * min_size - point.y()) else: - shiftPos = pos - point + shift_pos = pos - point - shape.moveVertexBy(index, shiftPos) + shape.moveVertexBy(index, shift_pos) - lindex = (index + 1) % 4 - rindex = (index + 3) % 4 - lshift = None - rshift = None + left_index = (index + 1) % 4 + right_index = (index + 3) % 4 + left_shift = None + right_shift = None if index % 2 == 0: - rshift = QPointF(shiftPos.x(), 0) - lshift = QPointF(0, shiftPos.y()) + right_shift = QPointF(shift_pos.x(), 0) + left_shift = QPointF(0, shift_pos.y()) else: - lshift = QPointF(shiftPos.x(), 0) - rshift = QPointF(0, shiftPos.y()) - shape.moveVertexBy(rindex, rshift) - shape.moveVertexBy(lindex, lshift) + left_shift = QPointF(shift_pos.x(), 0) + right_shift = QPointF(0, shift_pos.y()) + shape.moveVertexBy(right_index, right_shift) + shape.moveVertexBy(left_index, left_shift) - def boundedMoveShape(self, shape, pos): - if self.outOfPixmap(pos): + def bounded_move_shape(self, shape, pos): + if self.out_of_pixmap(pos): return False # No need to move o1 = pos + self.offsets[0] - if self.outOfPixmap(o1): + if self.out_of_pixmap(o1): pos -= QPointF(min(0, o1.x()), min(0, o1.y())) o2 = pos + self.offsets[1] - if self.outOfPixmap(o2): + if self.out_of_pixmap(o2): pos += QPointF(min(0, self.pixmap.width() - o2.x()), min(0, self.pixmap.height() - o2.y())) # The next line tracks the new position of the cursor # relative to the shape, but also results in making it # a bit "shaky" when nearing the border and allows it to # go outside of the shape's area for some reason. XXX - #self.calculateOffsets(self.selectedShape, pos) + # self.calculateOffsets(self.selectedShape, pos) dp = pos - self.prevPoint if dp: shape.moveBy(dp) @@ -428,15 +428,15 @@ def boundedMoveShape(self, shape, pos): return True return False - def deSelectShape(self): + def de_select_shape(self): if self.selectedShape: self.selectedShape.selected = False self.selectedShape = None - self.setHiding(False) + self.set_hiding(False) self.selectionChanged.emit(False) self.update() - def deleteSelected(self): + def delete_selected(self): if self.selectedShape: shape = self.selectedShape self.shapes.remove(self.selectedShape) @@ -444,25 +444,25 @@ def deleteSelected(self): self.update() return shape - def copySelectedShape(self): + def copy_selected_shape(self): if self.selectedShape: shape = self.selectedShape.copy() - self.deSelectShape() + self.de_select_shape() self.shapes.append(shape) shape.selected = True self.selectedShape = shape - self.boundedShiftShape(shape) + self.bounded_shift_shape(shape) return shape - def boundedShiftShape(self, shape): + def bounded_shift_shape(self, shape): # Try to move in one direction, and if it fails in another. # Give up if both fail. point = shape[0] offset = QPointF(2.0, 2.0) - self.calculateOffsets(shape, point) + self.calculate_offsets(shape, point) self.prevPoint = point - if not self.boundedMoveShape(shape, point - offset): - self.boundedMoveShape(shape, point + offset) + if not self.bounded_move_shape(shape, point - offset): + self.bounded_move_shape(shape, point + offset) def paintEvent(self, event): if not self.pixmap: @@ -475,7 +475,7 @@ def paintEvent(self, event): p.setRenderHint(QPainter.SmoothPixmapTransform) p.scale(self.scale, self.scale) - p.translate(self.offsetToCenter()) + p.translate(self.offset_to_center()) p.drawPixmap(0, 0, self.pixmap) Shape.scale = self.scale @@ -492,16 +492,16 @@ def paintEvent(self, event): # Paint rect if self.current is not None and len(self.line) == 2: - leftTop = self.line[0] - rightBottom = self.line[1] - rectWidth = rightBottom.x() - leftTop.x() - rectHeight = rightBottom.y() - leftTop.y() + left_top = self.line[0] + right_bottom = self.line[1] + rect_width = right_bottom.x() - left_top.x() + rect_height = right_bottom.y() - left_top.y() p.setPen(self.drawingRectColor) brush = QBrush(Qt.BDiagPattern) p.setBrush(brush) - p.drawRect(leftTop.x(), leftTop.y(), rectWidth, rectHeight) + p.drawRect(left_top.x(), left_top.y(), rect_width, rect_height) - if self.drawing() and not self.prevPoint.isNull() and not self.outOfPixmap(self.prevPoint): + if self.drawing() and not self.prevPoint.isNull() and not self.out_of_pixmap(self.prevPoint): p.setPen(QColor(0, 0, 0)) p.drawLine(self.prevPoint.x(), 0, self.prevPoint.x(), self.pixmap.height()) p.drawLine(0, self.prevPoint.y(), self.pixmap.width(), self.prevPoint.y()) @@ -518,11 +518,11 @@ def paintEvent(self, event): p.end() - def transformPos(self, point): + def transform_pos(self, point): """Convert from widget-logical coordinates to painter-logical coordinates.""" - return point / self.scale - self.offsetToCenter() + return point / self.scale - self.offset_to_center() - def offsetToCenter(self): + def offset_to_center(self): s = self.scale area = super(Canvas, self).size() w, h = self.pixmap.width() * s, self.pixmap.height() * s @@ -531,7 +531,7 @@ def offsetToCenter(self): y = (ah - h) / (2 * s) if ah > h else 0 return QPointF(x, y) - def outOfPixmap(self, p): + def out_of_pixmap(self, p): w, h = self.pixmap.width(), self.pixmap.height() return not (0 <= p.x() <= w and 0 <= p.y() <= h) @@ -546,13 +546,13 @@ def finalise(self): self.current.close() self.shapes.append(self.current) self.current = None - self.setHiding(False) + self.set_hiding(False) self.newShape.emit() self.update() - def closeEnough(self, p1, p2): - #d = distance(p1 - p2) - #m = (p1-p2).manhattanLength() + def close_enough(self, p1, p2): + # d = distance(p1 - p2) + # m = (p1-p2).manhattanLength() # print "d %.2f, m %d, %.2f" % (d, m, d - m) return distance(p1 - p2) < self.epsilon @@ -595,38 +595,38 @@ def keyPressEvent(self, ev): self.current = None self.drawingPolygon.emit(False) self.update() - elif key == Qt.Key_Return and self.canCloseShape(): + elif key == Qt.Key_Return and self.can_close_shape(): self.finalise() elif key == Qt.Key_Left and self.selectedShape: - self.moveOnePixel('Left') + self.move_one_pixel('Left') elif key == Qt.Key_Right and self.selectedShape: - self.moveOnePixel('Right') + self.move_one_pixel('Right') elif key == Qt.Key_Up and self.selectedShape: - self.moveOnePixel('Up') + self.move_one_pixel('Up') elif key == Qt.Key_Down and self.selectedShape: - self.moveOnePixel('Down') + self.move_one_pixel('Down') - def moveOnePixel(self, direction): + def move_one_pixel(self, direction): # print(self.selectedShape.points) - if direction == 'Left' and not self.moveOutOfBound(QPointF(-1.0, 0)): + if direction == 'Left' and not self.move_out_of_bound(QPointF(-1.0, 0)): # print("move Left one pixel") self.selectedShape.points[0] += QPointF(-1.0, 0) self.selectedShape.points[1] += QPointF(-1.0, 0) self.selectedShape.points[2] += QPointF(-1.0, 0) self.selectedShape.points[3] += QPointF(-1.0, 0) - elif direction == 'Right' and not self.moveOutOfBound(QPointF(1.0, 0)): + elif direction == 'Right' and not self.move_out_of_bound(QPointF(1.0, 0)): # print("move Right one pixel") self.selectedShape.points[0] += QPointF(1.0, 0) self.selectedShape.points[1] += QPointF(1.0, 0) self.selectedShape.points[2] += QPointF(1.0, 0) self.selectedShape.points[3] += QPointF(1.0, 0) - elif direction == 'Up' and not self.moveOutOfBound(QPointF(0, -1.0)): + elif direction == 'Up' and not self.move_out_of_bound(QPointF(0, -1.0)): # print("move Up one pixel") self.selectedShape.points[0] += QPointF(0, -1.0) self.selectedShape.points[1] += QPointF(0, -1.0) self.selectedShape.points[2] += QPointF(0, -1.0) self.selectedShape.points[3] += QPointF(0, -1.0) - elif direction == 'Down' and not self.moveOutOfBound(QPointF(0, 1.0)): + elif direction == 'Down' and not self.move_out_of_bound(QPointF(0, 1.0)): # print("move Down one pixel") self.selectedShape.points[0] += QPointF(0, 1.0) self.selectedShape.points[1] += QPointF(0, 1.0) @@ -635,11 +635,11 @@ def moveOnePixel(self, direction): self.shapeMoved.emit() self.repaint() - def moveOutOfBound(self, step): + def move_out_of_bound(self, step): points = [p1+p2 for p1, p2 in zip(self.selectedShape.points, [step]*4)] - return True in map(self.outOfPixmap, points) + return True in map(self.out_of_pixmap, points) - def setLastLabel(self, text, line_color = None, fill_color = None): + def set_last_label(self, text, line_color=None, fill_color=None): assert text self.shapes[-1].label = text if line_color: @@ -650,14 +650,14 @@ def setLastLabel(self, text, line_color = None, fill_color = None): return self.shapes[-1] - def undoLastLine(self): + def undo_last_line(self): assert self.shapes self.current = self.shapes.pop() self.current.setOpen() self.line.points = [self.current[-1], self.current[0]] self.drawingPolygon.emit(True) - def resetAllLines(self): + def reset_all_lines(self): assert self.shapes self.current = self.shapes.pop() self.current.setOpen() @@ -667,40 +667,40 @@ def resetAllLines(self): self.drawingPolygon.emit(False) self.update() - def loadPixmap(self, pixmap): + def load_pixmap(self, pixmap): self.pixmap = pixmap self.shapes = [] self.repaint() - def loadShapes(self, shapes): + def load_shapes(self, shapes): self.shapes = list(shapes) self.current = None self.repaint() - def setShapeVisible(self, shape, value): + def set_shape_visible(self, shape, value): self.visible[shape] = value self.repaint() - def currentCursor(self): + def current_cursor(self): cursor = QApplication.overrideCursor() if cursor is not None: cursor = cursor.shape() return cursor - def overrideCursor(self, cursor): + def override_cursor(self, cursor): self._cursor = cursor - if self.currentCursor() is None: + if self.current_cursor() is None: QApplication.setOverrideCursor(cursor) else: QApplication.changeOverrideCursor(cursor) - def restoreCursor(self): + def restore_cursor(self): QApplication.restoreOverrideCursor() - def resetState(self): - self.restoreCursor() + def reset_state(self): + self.restore_cursor() self.pixmap = None self.update() - def setDrawingShapeToSquare(self, status): + def set_drawing_shape_to_square(self, status): self.drawSquare = status From a8beb890e7658e51a73c9239bcbebd0b51a5a610 Mon Sep 17 00:00:00 2001 From: Cerno_b Date: Mon, 8 Mar 2021 02:54:17 +0100 Subject: [PATCH 05/13] Rename functions and locals for remaining files --- labelImg.py | 96 +++++++++++++------------- libs/canvas.py | 48 ++++++------- libs/colorDialog.py | 4 +- libs/create_ml_io.py | 80 ++++++++++----------- libs/labelDialog.py | 42 +++++------ libs/labelFile.py | 124 ++++++++++++++++----------------- libs/pascal_voc_io.py | 112 +++++++++++++++--------------- libs/shape.py | 58 ++++++++-------- libs/stringBundle.py | 42 +++++------ libs/ustr.py | 6 +- libs/utils.py | 32 ++++----- libs/yolo_io.py | 138 ++++++++++++++++++------------------- tests/test_io.py | 38 +++++----- tests/test_stringBundle.py | 12 ++-- tests/test_utils.py | 10 +-- 15 files changed, 421 insertions(+), 421 deletions(-) diff --git a/labelImg.py b/labelImg.py index 651a59a21..d4890dcc8 100755 --- a/labelImg.py +++ b/labelImg.py @@ -57,7 +57,7 @@ class WindowMixin(object): def menu(self, title, actions=None): menu = self.menuBar().addMenu(title) if actions: - addActions(menu, actions) + add_actions(menu, actions) return menu def toolbar(self, title, actions=None): @@ -66,7 +66,7 @@ def toolbar(self, title, actions=None): # toolbar.setOrientation(Qt.Vertical) toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) if actions: - addActions(toolbar, actions) + add_actions(toolbar, actions) self.addToolBar(Qt.LeftToolBarArea, toolbar) return toolbar @@ -84,8 +84,8 @@ def __init__(self, default_filename=None, default_prefdef_class_file=None, defau settings = self.settings # Load string bundle for i18n - self.stringBundle = StringBundle.getBundle() - get_str = lambda str_id: self.stringBundle.getString(str_id) + self.stringBundle = StringBundle.get_bundle() + get_str = lambda str_id: self.stringBundle.get_string(str_id) # Save as Pascal voc xml self.defaultSaveDir = default_save_dir @@ -109,7 +109,7 @@ def __init__(self, default_filename=None, default_prefdef_class_file=None, defau self.load_predefined_classes(default_prefdef_class_file) # Main widgets and related state. - self.labelDialog = LabelDialog(parent=self, listItem=self.labelHist) + self.labelDialog = LabelDialog(parent=self, list_item=self.labelHist) self.itemsToShapes = {} self.shapesToItems = {} @@ -203,7 +203,7 @@ def __init__(self, default_filename=None, default_prefdef_class_file=None, defau self.dock.setFeatures(self.dock.features() ^ self.dockFeatures) # Actions - action = partial(newAction, self) + action = partial(new_action, self) quit = action(get_str('quit'), self.close, 'Ctrl+Q', 'quit', get_str('quitApp')) @@ -293,8 +293,8 @@ def get_format_meta(format): 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"))) + " %s and %s from the canvas." % (format_shortcut("Ctrl+[-+]"), + format_shortcut("Ctrl+Wheel"))) self.zoomWidget.setEnabled(False) zoom_in = action(get_str('zoomin'), partial(self.add_zoom, 10), @@ -338,7 +338,7 @@ def get_format_meta(format): # Label list context menu. label_menu = QMenu() - addActions(label_menu, (edit, delete)) + add_actions(label_menu, (edit, delete)) self.labelList.setContextMenuPolicy(Qt.CustomContextMenu) self.labelList.customContextMenuRequested.connect( self.pop_label_list_menu) @@ -351,7 +351,7 @@ def get_format_meta(format): self.drawSquaresOption.triggered.connect(self.toggle_draw_square) # Store actions for further handling. - self.actions = struct(save=save, save_format=save_format, saveAs=save_as, open=open, close=close, resetAll=reset_all, deleteImg=delete_image, + self.actions = Struct(save=save, save_format=save_format, saveAs=save_as, open=open, close=close, resetAll=reset_all, deleteImg=delete_image, lineColor=color1, create=create, delete=delete, edit=edit, copy=copy, createMode=create_mode, editMode=edit_mode, advancedMode=advanced_mode, shapeLineColor=shape_line_color, shapeFillColor=shape_fill_color, @@ -370,7 +370,7 @@ def get_format_meta(format): close, create, create_mode, edit_mode), onShapesPresent=(save_as, hide_all, show_all)) - self.menus = struct( + self.menus = Struct( file=self.menu(get_str('menu_file')), edit=self.menu(get_str('menu_edit')), view=self.menu(get_str('menu_view')), @@ -395,10 +395,10 @@ def get_format_meta(format): self.displayLabelOption.setChecked(settings.get(SETTING_PAINT_LABEL, False)) self.displayLabelOption.triggered.connect(self.toggle_paint_labels_option) - addActions(self.menus.file, - (open, open_dir, copy_prev_bounding, change_save_dir, open_annotation, self.menus.recentFiles, save, save_format, save_as, close, reset_all, delete_image, quit)) - addActions(self.menus.help, (help, show_info)) - addActions(self.menus.view, ( + add_actions(self.menus.file, + (open, open_dir, copy_prev_bounding, change_save_dir, open_annotation, self.menus.recentFiles, save, save_format, save_as, close, reset_all, delete_image, quit)) + add_actions(self.menus.help, (help, show_info)) + add_actions(self.menus.view, ( self.autoSaving, self.singleClassMode, self.displayLabelOption, @@ -410,8 +410,8 @@ def get_format_meta(format): self.menus.file.aboutToShow.connect(self.update_file_menu) # Custom context menu for the canvas widget: - addActions(self.canvas.menus[0], self.actions.beginnerContext) - addActions(self.canvas.menus[1], ( + add_actions(self.canvas.menus[0], self.actions.beginnerContext) + add_actions(self.canvas.menus[1], ( action('&Copy here', self.copy_shape), action('&Move here', self.move_shape))) @@ -518,19 +518,19 @@ def keyPressEvent(self, event): def set_format(self, save_format): if save_format == FORMAT_PASCALVOC: self.actions.save_format.setText(FORMAT_PASCALVOC) - self.actions.save_format.setIcon(newIcon("format_voc")) + self.actions.save_format.setIcon(new_icon("format_voc")) self.labelFileFormat = LabelFileFormat.PASCAL_VOC LabelFile.suffix = XML_EXT elif save_format == FORMAT_YOLO: self.actions.save_format.setText(FORMAT_YOLO) - self.actions.save_format.setIcon(newIcon("format_yolo")) + self.actions.save_format.setIcon(new_icon("format_yolo")) self.labelFileFormat = LabelFileFormat.YOLO LabelFile.suffix = TXT_EXT elif save_format == FORMAT_CREATEML: self.actions.save_format.setText(FORMAT_CREATEML) - self.actions.save_format.setIcon(newIcon("format_createml")) + self.actions.save_format.setIcon(new_icon("format_createml")) self.labelFileFormat = LabelFileFormat.CREATE_ML LabelFile.suffix = JSON_EXT @@ -566,21 +566,21 @@ def populate_mode_actions(self): else: tool, menu = self.actions.advanced, self.actions.advancedContext self.tools.clear() - addActions(self.tools, tool) + add_actions(self.tools, tool) self.canvas.menus[0].clear() - addActions(self.canvas.menus[0], menu) + add_actions(self.canvas.menus[0], menu) self.menus.edit.clear() actions = (self.actions.create,) if self.beginner()\ else (self.actions.createMode, self.actions.editMode) - addActions(self.menus.edit, actions + self.actions.editMenu) + add_actions(self.menus.edit, actions + self.actions.editMenu) def set_beginner(self): self.tools.clear() - addActions(self.tools, self.actions.beginner) + add_actions(self.tools, self.actions.beginner) def set_advanced(self): self.tools.clear() - addActions(self.tools, self.actions.advanced) + add_actions(self.tools, self.actions.advanced) def set_dirty(self): self.dirty = True @@ -692,7 +692,7 @@ def exists(filename): files = [f for f in self.recentFiles if f != curr_file_path and exists(f)] for i, f in enumerate(files): - icon = newIcon('labels') + icon = new_icon('labels') action = QAction( icon, '&%d %s' % (i + 1, QFileInfo(f).fileName()), self) action.triggered.connect(partial(self.load_recent, f)) @@ -707,10 +707,10 @@ def edit_label(self): item = self.current_item() if not item: return - text = self.labelDialog.popUp(item.text()) + text = self.labelDialog.pop_up(item.text()) if text is not None: item.setText(text) - item.setBackground(generateColorByText(text)) + item.setBackground(generate_color_by_text(text)) self.set_dirty() self.update_combo_box() @@ -770,7 +770,7 @@ def add_label(self, shape): item = HashableQListWidgetItem(shape.label) item.setFlags(item.flags() | Qt.ItemIsUserCheckable) item.setCheckState(Qt.Checked) - item.setBackground(generateColorByText(shape.label)) + item.setBackground(generate_color_by_text(shape.label)) self.itemsToShapes[item] = shape self.shapesToItems[shape] = item self.labelList.addItem(item) @@ -799,7 +799,7 @@ def load_labels(self, shapes): if snapped: self.set_dirty() - shape.addPoint(QPointF(x, y)) + shape.add_point(QPointF(x, y)) shape.difficult = difficult shape.close() s.append(shape) @@ -807,12 +807,12 @@ def load_labels(self, shapes): if line_color: shape.line_color = QColor(*line_color) else: - shape.line_color = generateColorByText(label) + shape.line_color = generate_color_by_text(label) if fill_color: shape.fill_color = QColor(*fill_color) else: - shape.fill_color = generateColorByText(label) + shape.fill_color = generate_color_by_text(label) self.add_label(shape) self.update_combo_box() @@ -849,18 +849,18 @@ def format_shape(s): if self.labelFileFormat == LabelFileFormat.PASCAL_VOC: if annotation_file_path[-4:].lower() != ".xml": annotation_file_path += XML_EXT - self.labelFile.savePascalVocFormat(annotation_file_path, shapes, self.filePath, self.imageData, - self.lineColor.getRgb(), self.fillColor.getRgb()) + self.labelFile.save_pascal_voc_format(annotation_file_path, shapes, self.filePath, self.imageData, + self.lineColor.getRgb(), self.fillColor.getRgb()) elif self.labelFileFormat == LabelFileFormat.YOLO: if annotation_file_path[-4:].lower() != ".txt": annotation_file_path += TXT_EXT - self.labelFile.saveYoloFormat(annotation_file_path, shapes, self.filePath, self.imageData, self.labelHist, - self.lineColor.getRgb(), self.fillColor.getRgb()) + self.labelFile.save_yolo_format(annotation_file_path, shapes, self.filePath, self.imageData, self.labelHist, + self.lineColor.getRgb(), self.fillColor.getRgb()) elif self.labelFileFormat == LabelFileFormat.CREATE_ML: if annotation_file_path[-5:].lower() != ".json": annotation_file_path += JSON_EXT - self.labelFile.saveCreateMLFormat(annotation_file_path, shapes, self.filePath, self.imageData, - self.labelHist, self.lineColor.getRgb(), self.fillColor.getRgb()) + self.labelFile.save_create_ml_format(annotation_file_path, shapes, self.filePath, self.imageData, + self.labelHist, self.lineColor.getRgb(), self.fillColor.getRgb()) else: self.labelFile.save(annotation_file_path, shapes, self.filePath, self.imageData, self.lineColor.getRgb(), self.fillColor.getRgb()) @@ -899,7 +899,7 @@ def label_item_changed(self, item): label = item.text() if label != shape.label: shape.label = item.text() - shape.line_color = generateColorByText(shape.label) + shape.line_color = generate_color_by_text(shape.label) self.set_dirty() else: # User probably changed item visibility self.canvas.set_shape_visible(shape, item.checkState() == Qt.Checked) @@ -913,13 +913,13 @@ def new_shape(self): if not self.useDefaultLabelCheckbox.isChecked() or not self.defaultLabelTextLine.text(): if len(self.labelHist) > 0: self.labelDialog = LabelDialog( - parent=self, listItem=self.labelHist) + parent=self, list_item=self.labelHist) # Sync single class mode from PR#106 if self.singleClassMode.isChecked() and self.lastLabel: text = self.lastLabel else: - text = self.labelDialog.popUp(text=self.prevLabelText) + text = self.labelDialog.pop_up(text=self.prevLabelText) self.lastLabel = text else: text = self.defaultLabelTextLine.text() @@ -928,7 +928,7 @@ def new_shape(self): self.diffcButton.setChecked(False) if text is not None: self.prevLabelText = text - generate_color = generateColorByText(text) + generate_color = generate_color_by_text(text) shape = self.canvas.set_last_label(text, generate_color, generate_color) self.add_label(shape) if self.beginner(): # Switch to edit mode. @@ -1051,7 +1051,7 @@ def load_file(self, file_path=None): self.mImgList.clear() if unicode_file_path and os.path.exists(unicode_file_path): - if LabelFile.isLabelFile(unicode_file_path): + if LabelFile.is_label_file(unicode_file_path): try: self.labelFile = LabelFile(unicode_file_path) except LabelFileError as e: @@ -1286,13 +1286,13 @@ def verify_image(self, _value=False): # Proceeding next image without dialog if having any label if self.filePath is not None: try: - self.labelFile.toggleVerify() + self.labelFile.toggle_verify() except AttributeError: # If the labelling file does not exist yet, create if and # re-save it with the verified attribute. self.save_file() if self.labelFile is not None: - self.labelFile.toggleVerify() + self.labelFile.toggle_verify() else: return @@ -1516,7 +1516,7 @@ def load_pascal_xml_by_filename(self, xml_path): self.set_format(FORMAT_PASCALVOC) t_voc_parse_reader = PascalVocReader(xml_path) - shapes = t_voc_parse_reader.getShapes() + shapes = t_voc_parse_reader.get_shapes() self.load_labels(shapes) self.canvas.verified = t_voc_parse_reader.verified @@ -1528,7 +1528,7 @@ def load_yolo_txt_by_filename(self, txt_path): self.set_format(FORMAT_YOLO) t_yolo_parse_reader = YoloReader(txt_path, self.image) - shapes = t_yolo_parse_reader.getShapes() + shapes = t_yolo_parse_reader.get_shapes() print(shapes) self.load_labels(shapes) self.canvas.verified = t_yolo_parse_reader.verified @@ -1580,7 +1580,7 @@ def get_main_app(argv=[]): """ app = QApplication(argv) app.setApplicationName(__appname__) - app.setWindowIcon(newIcon("app")) + app.setWindowIcon(new_icon("app")) # Tzutalin 201705+: Accept extra agruments to change predefined class file argparser = argparse.ArgumentParser() argparser.add_argument("image_dir", nargs="?") diff --git a/libs/canvas.py b/libs/canvas.py index 20e33cc7e..e89192978 100644 --- a/libs/canvas.py +++ b/libs/canvas.py @@ -99,7 +99,7 @@ def set_editing(self, value=True): def un_highlight(self): if self.hShape: - self.hShape.highlightClear() + self.hShape.highlight_clear() self.hVertex = self.hShape = None def selected_vertex(self): @@ -140,7 +140,7 @@ def mouseMoveEvent(self, ev): pos = self.current[0] color = self.current.line_color self.override_cursor(CURSOR_POINT) - self.current.highlightVertex(0, Shape.NEAR_VERTEX) + self.current.highlight_vertex(0, Shape.NEAR_VERTEX) if self.drawSquare: init_pos = self.current[0] @@ -155,7 +155,7 @@ def mouseMoveEvent(self, ev): self.line.line_color = color self.prevPoint = QPointF() - self.current.highlightClear() + self.current.highlight_clear() else: self.prevPoint = pos self.repaint() @@ -200,20 +200,20 @@ def mouseMoveEvent(self, ev): for shape in reversed([s for s in self.shapes if self.isVisible(s)]): # Look for a nearby vertex to highlight. If that fails, # check if we happen to be inside a shape. - index = shape.nearestVertex(pos, self.epsilon) + index = shape.nearest_vertex(pos, self.epsilon) if index is not None: if self.selected_vertex(): - self.hShape.highlightClear() + self.hShape.highlight_clear() self.hVertex, self.hShape = index, shape - shape.highlightVertex(index, shape.MOVE_VERTEX) + shape.highlight_vertex(index, shape.MOVE_VERTEX) self.override_cursor(CURSOR_POINT) self.setToolTip("Click & drag to move point") self.setStatusTip(self.toolTip()) self.update() break - elif shape.containsPoint(pos): + elif shape.contains_point(pos): if self.selected_vertex(): - self.hShape.highlightClear() + self.hShape.highlight_clear() self.hVertex, self.hShape = None, shape self.setToolTip( "Click & drag to move shape '%s'" % shape.label) @@ -223,7 +223,7 @@ def mouseMoveEvent(self, ev): break else: # Nothing found, clear highlights, reset state. if self.hShape: - self.hShape.highlightClear() + self.hShape.highlight_clear() self.update() self.hVertex, self.hShape = None, None self.override_cursor(CURSOR_DEFAULT) @@ -293,20 +293,20 @@ def hide_background_shapes(self, value): self.repaint() def handle_drawing(self, pos): - if self.current and self.current.reachMaxPoints() is False: + if self.current and self.current.reach_max_points() is False: init_pos = self.current[0] min_x = init_pos.x() min_y = init_pos.y() target_pos = self.line[1] max_x = target_pos.x() max_y = target_pos.y() - self.current.addPoint(QPointF(max_x, min_y)) - self.current.addPoint(target_pos) - self.current.addPoint(QPointF(min_x, max_y)) + self.current.add_point(QPointF(max_x, min_y)) + self.current.add_point(target_pos) + self.current.add_point(QPointF(min_x, max_y)) self.finalise() elif not self.out_of_pixmap(pos): self.current = Shape() - self.current.addPoint(pos) + self.current.add_point(pos) self.line.points = [pos, pos] self.set_hiding() self.drawingPolygon.emit(True) @@ -322,7 +322,7 @@ def mouseDoubleClickEvent(self, ev): # We need at least 4 points here, since the mousePress handler # adds an extra one before this handler is called. if self.can_close_shape() and len(self.current) > 3: - self.current.popPoint() + self.current.pop_point() self.finalise() def select_shape(self, shape): @@ -338,18 +338,18 @@ def select_shape_point(self, point): self.de_select_shape() if self.selected_vertex(): # A vertex is marked for selection. index, shape = self.hVertex, self.hShape - shape.highlightVertex(index, shape.MOVE_VERTEX) + shape.highlight_vertex(index, shape.MOVE_VERTEX) self.select_shape(shape) return self.hVertex for shape in reversed(self.shapes): - if self.isVisible(shape) and shape.containsPoint(point): + if self.isVisible(shape) and shape.contains_point(point): self.select_shape(shape) self.calculate_offsets(shape, point) return self.selectedShape return None def calculate_offsets(self, shape, point): - rect = shape.boundingRect() + rect = shape.bounding_rect() x1 = rect.x() - point.x() y1 = rect.y() - point.y() x2 = (rect.x() + rect.width()) - point.x() @@ -391,7 +391,7 @@ def bounded_move_vertex(self, pos): else: shift_pos = pos - point - shape.moveVertexBy(index, shift_pos) + shape.move_vertex_by(index, shift_pos) left_index = (index + 1) % 4 right_index = (index + 3) % 4 @@ -403,8 +403,8 @@ def bounded_move_vertex(self, pos): else: left_shift = QPointF(shift_pos.x(), 0) right_shift = QPointF(0, shift_pos.y()) - shape.moveVertexBy(right_index, right_shift) - shape.moveVertexBy(left_index, left_shift) + shape.move_vertex_by(right_index, right_shift) + shape.move_vertex_by(left_index, left_shift) def bounded_move_shape(self, shape, pos): if self.out_of_pixmap(pos): @@ -423,7 +423,7 @@ def bounded_move_shape(self, shape, pos): # self.calculateOffsets(self.selectedShape, pos) dp = pos - self.prevPoint if dp: - shape.moveBy(dp) + shape.move_by(dp) self.prevPoint = pos return True return False @@ -653,14 +653,14 @@ def set_last_label(self, text, line_color=None, fill_color=None): def undo_last_line(self): assert self.shapes self.current = self.shapes.pop() - self.current.setOpen() + self.current.set_open() self.line.points = [self.current[-1], self.current[0]] self.drawingPolygon.emit(True) def reset_all_lines(self): assert self.shapes self.current = self.shapes.pop() - self.current.setOpen() + self.current.set_open() self.line.points = [self.current[-1], self.current[0]] self.drawingPolygon.emit(True) self.current = None diff --git a/libs/colorDialog.py b/libs/colorDialog.py index d5d947591..5cd28025c 100644 --- a/libs/colorDialog.py +++ b/libs/colorDialog.py @@ -22,7 +22,7 @@ def __init__(self, parent=None): self.default = None self.bb = self.layout().itemAt(1).widget() self.bb.addButton(BB.RestoreDefaults) - self.bb.clicked.connect(self.checkRestore) + self.bb.clicked.connect(self.check_restore) def getColor(self, value=None, title=None, default=None): self.default = default @@ -32,6 +32,6 @@ def getColor(self, value=None, title=None, default=None): self.setCurrentColor(value) return self.currentColor() if self.exec_() else None - def checkRestore(self, button): + def check_restore(self, button): if self.bb.buttonRole(button) & BB.ResetRole and self.default: self.setCurrentColor(self.default) diff --git a/libs/create_ml_io.py b/libs/create_ml_io.py index 0d0781464..3c05a1692 100644 --- a/libs/create_ml_io.py +++ b/libs/create_ml_io.py @@ -11,26 +11,26 @@ class CreateMLWriter: - def __init__(self, foldername, filename, imgsize, shapes, outputfile, databasesrc='Unknown', localimgpath=None): - self.foldername = foldername + def __init__(self, folder_name, filename, img_size, shapes, output_file, database_src='Unknown', local_img_path=None): + self.foldername = folder_name self.filename = filename - self.databasesrc = databasesrc - self.imgsize = imgsize + self.databasesrc = database_src + self.imgsize = img_size self.boxlist = [] - self.localimgpath = localimgpath + self.localimgpath = local_img_path self.verified = False self.shapes = shapes - self.outputfile = outputfile + self.outputfile = output_file def write(self): if os.path.isfile(self.outputfile): with open(self.outputfile, "r") as file: input_data = file.read() - outputdict = json.loads(input_data) + output_dict = json.loads(input_data) else: - outputdict = [] + output_dict = [] - outputimagedict = { + output_image_dict = { "image": self.filename, "annotations": [] } @@ -45,7 +45,7 @@ def write(self): height, width, x, y = self.calculate_coordinates(x1, x2, y1, y2) - shapedict = { + shape_dict = { "label": shape["label"], "coordinates": { "x": x, @@ -54,50 +54,50 @@ def write(self): "height": height } } - outputimagedict["annotations"].append(shapedict) + output_image_dict["annotations"].append(shape_dict) # check if image already in output exists = False - for i in range(0, len(outputdict)): - if outputdict[i]["image"] == outputimagedict["image"]: + for i in range(0, len(output_dict)): + if output_dict[i]["image"] == output_image_dict["image"]: exists = True - outputdict[i] = outputimagedict + output_dict[i] = output_image_dict break if not exists: - outputdict.append(outputimagedict) + output_dict.append(output_image_dict) - Path(self.outputfile).write_text(json.dumps(outputdict), ENCODE_METHOD) + Path(self.outputfile).write_text(json.dumps(output_dict), ENCODE_METHOD) def calculate_coordinates(self, x1, x2, y1, y2): if x1 < x2: - xmin = x1 - xmax = x2 + x_min = x1 + x_max = x2 else: - xmin = x2 - xmax = x1 + x_min = x2 + x_max = x1 if y1 < y2: - ymin = y1 - ymax = y2 + y_min = y1 + y_max = y2 else: - ymin = y2 - ymax = y1 - width = xmax - xmin + y_min = y2 + y_max = y1 + width = x_max - x_min if width < 0: width = width * -1 - height = ymax - ymin + height = y_max - y_min # x and y from center of rect - x = xmin + width / 2 - y = ymin + height / 2 + x = x_min + width / 2 + y = y_min + height / 2 return height, width, x, y class CreateMLReader: - def __init__(self, jsonpath, filepath): - self.jsonpath = jsonpath + def __init__(self, json_path, file_path): + self.jsonpath = json_path self.shapes = [] self.verified = False - self.filename = filepath.split("/")[-1:][0] + self.filename = file_path.split("/")[-1:][0] try: self.parse_json() except ValueError: @@ -105,26 +105,26 @@ def __init__(self, jsonpath, filepath): def parse_json(self): with open(self.jsonpath, "r") as file: - inputdata = file.read() + input_data = file.read() - outputdict = json.loads(inputdata) + output_dict = json.loads(input_data) self.verified = True if len(self.shapes) > 0: self.shapes = [] - for image in outputdict: + for image in output_dict: if image["image"] == self.filename: for shape in image["annotations"]: self.add_shape(shape["label"], shape["coordinates"]) - def add_shape(self, label, bndbox): - xmin = bndbox["x"] - (bndbox["width"] / 2) - ymin = bndbox["y"] - (bndbox["height"] / 2) + def add_shape(self, label, bnd_box): + x_min = bnd_box["x"] - (bnd_box["width"] / 2) + y_min = bnd_box["y"] - (bnd_box["height"] / 2) - xmax = bndbox["x"] + (bndbox["width"] / 2) - ymax = bndbox["y"] + (bndbox["height"] / 2) + x_max = bnd_box["x"] + (bnd_box["width"] / 2) + y_max = bnd_box["y"] + (bnd_box["height"] / 2) - points = [(xmin, ymin), (xmax, ymin), (xmax, ymax), (xmin, ymax)] + points = [(x_min, y_min), (x_max, y_min), (x_max, y_max), (x_min, y_max)] self.shapes.append((label, points, None, None, True)) def get_shapes(self): diff --git a/libs/labelDialog.py b/libs/labelDialog.py index 924a4a8d3..865a7f307 100644 --- a/libs/labelDialog.py +++ b/libs/labelDialog.py @@ -6,23 +6,23 @@ from PyQt4.QtGui import * from PyQt4.QtCore import * -from libs.utils import newIcon, labelValidator +from libs.utils import new_icon, label_validator BB = QDialogButtonBox class LabelDialog(QDialog): - def __init__(self, text="Enter object label", parent=None, listItem=None): + def __init__(self, text="Enter object label", parent=None, list_item=None): super(LabelDialog, self).__init__(parent) self.edit = QLineEdit() self.edit.setText(text) - self.edit.setValidator(labelValidator()) - self.edit.editingFinished.connect(self.postProcess) + self.edit.setValidator(label_validator()) + self.edit.editingFinished.connect(self.post_process) model = QStringListModel() - model.setStringList(listItem) + model.setStringList(list_item) completer = QCompleter() completer.setModel(model) self.edit.setCompleter(completer) @@ -30,18 +30,18 @@ def __init__(self, text="Enter object label", parent=None, listItem=None): layout = QVBoxLayout() layout.addWidget(self.edit) self.buttonBox = bb = BB(BB.Ok | BB.Cancel, Qt.Horizontal, self) - bb.button(BB.Ok).setIcon(newIcon('done')) - bb.button(BB.Cancel).setIcon(newIcon('undo')) + bb.button(BB.Ok).setIcon(new_icon('done')) + bb.button(BB.Cancel).setIcon(new_icon('undo')) bb.accepted.connect(self.validate) bb.rejected.connect(self.reject) layout.addWidget(bb) - if listItem is not None and len(listItem) > 0: + if list_item is not None and len(list_item) > 0: self.listWidget = QListWidget(self) - for item in listItem: + for item in list_item: self.listWidget.addItem(item) - self.listWidget.itemClicked.connect(self.listItemClick) - self.listWidget.itemDoubleClicked.connect(self.listItemDoubleClick) + self.listWidget.itemClicked.connect(self.list_item_click) + self.listWidget.itemDoubleClicked.connect(self.list_item_double_click) layout.addWidget(self.listWidget) self.setLayout(layout) @@ -55,22 +55,22 @@ def validate(self): if self.edit.text().strip(): self.accept() - def postProcess(self): + def post_process(self): try: self.edit.setText(self.edit.text().trimmed()) except AttributeError: # PyQt5: AttributeError: 'str' object has no attribute 'trimmed' self.edit.setText(self.edit.text()) - def popUp(self, text='', move=True): + def pop_up(self, text='', move=True): self.edit.setText(text) self.edit.setSelection(0, len(text)) self.edit.setFocus(Qt.PopupFocusReason) if move: cursor_pos = QCursor.pos() - parent_bottomRight = self.parentWidget().geometry() - max_x = parent_bottomRight.x() + parent_bottomRight.width() - self.sizeHint().width() - max_y = parent_bottomRight.y() + parent_bottomRight.height() - self.sizeHint().height() + parent_bottom_right = self.parentWidget().geometry() + max_x = parent_bottom_right.x() + parent_bottom_right.width() - self.sizeHint().width() + max_y = parent_bottom_right.y() + parent_bottom_right.height() - self.sizeHint().height() max_global = self.parentWidget().mapToGlobal(QPoint(max_x, max_y)) if cursor_pos.x() > max_global.x(): cursor_pos.setX(max_global.x()) @@ -79,14 +79,14 @@ def popUp(self, text='', move=True): self.move(cursor_pos) return self.edit.text() if self.exec_() else None - def listItemClick(self, tQListWidgetItem): + def list_item_click(self, t_qlist_widget_item): try: - text = tQListWidgetItem.text().trimmed() + text = t_qlist_widget_item.text().trimmed() except AttributeError: # PyQt5: AttributeError: 'str' object has no attribute 'trimmed' - text = tQListWidgetItem.text().strip() + text = t_qlist_widget_item.text().strip() self.edit.setText(text) - def listItemDoubleClick(self, tQListWidgetItem): - self.listItemClick(tQListWidgetItem) + def list_item_double_click(self, t_qlist_widget_item): + self.list_item_click(t_qlist_widget_item) self.validate() diff --git a/libs/labelFile.py b/libs/labelFile.py index b366d45e5..c57106c91 100644 --- a/libs/labelFile.py +++ b/libs/labelFile.py @@ -18,7 +18,7 @@ class LabelFileFormat(Enum): - PASCAL_VOC= 1 + PASCAL_VOC = 1 YOLO = 2 CREATE_ML = 3 @@ -38,40 +38,40 @@ def __init__(self, filename=None): self.imageData = None self.verified = False - def saveCreateMLFormat(self, filename, shapes, imagePath, imageData, classList, lineColor=None, fillColor=None, databaseSrc=None): - imgFolderPath = os.path.dirname(imagePath) - imgFolderName = os.path.split(imgFolderPath)[-1] - imgFileName = os.path.basename(imagePath) - outputFilePath = "/".join(filename.split("/")[:-1]) - outputFile = outputFilePath + "/" + imgFolderName + JSON_EXT + def save_create_ml_format(self, filename, shapes, image_path, image_data, class_list, line_color=None, fill_color=None, database_src=None): + img_folder_path = os.path.dirname(image_path) + img_folder_name = os.path.split(img_folder_path)[-1] + img_file_name = os.path.basename(image_path) + output_file_path = "/".join(filename.split("/")[:-1]) + output_file = output_file_path + "/" + img_folder_name + JSON_EXT image = QImage() - image.load(imagePath) - imageShape = [image.height(), image.width(), - 1 if image.isGrayscale() else 3] - writer = CreateMLWriter(imgFolderName, imgFileName, - imageShape, shapes, outputFile, localimgpath=imagePath) + image.load(image_path) + image_shape = [image.height(), image.width(), + 1 if image.isGrayscale() else 3] + writer = CreateMLWriter(img_folder_name, img_file_name, + image_shape, shapes, output_file, local_img_path=image_path) writer.verified = self.verified writer.write() - def savePascalVocFormat(self, filename, shapes, imagePath, imageData, - lineColor=None, fillColor=None, databaseSrc=None): - imgFolderPath = os.path.dirname(imagePath) - imgFolderName = os.path.split(imgFolderPath)[-1] - imgFileName = os.path.basename(imagePath) - #imgFileNameWithoutExt = os.path.splitext(imgFileName)[0] + def save_pascal_voc_format(self, filename, shapes, image_path, image_data, + line_color=None, fill_color=None, database_src=None): + img_folder_path = os.path.dirname(image_path) + img_folder_name = os.path.split(img_folder_path)[-1] + img_file_name = os.path.basename(image_path) + # imgFileNameWithoutExt = os.path.splitext(img_file_name)[0] # Read from file path because self.imageData might be empty if saving to # Pascal format - if isinstance(imageData, QImage): - image = imageData + if isinstance(image_data, QImage): + image = image_data else: image = QImage() - image.load(imagePath) - imageShape = [image.height(), image.width(), - 1 if image.isGrayscale() else 3] - writer = PascalVocWriter(imgFolderName, imgFileName, - imageShape, localImgPath=imagePath) + image.load(image_path) + image_shape = [image.height(), image.width(), + 1 if image.isGrayscale() else 3] + writer = PascalVocWriter(img_folder_name, img_file_name, + image_shape, local_img_path=image_path) writer.verified = self.verified for shape in shapes: @@ -79,29 +79,29 @@ def savePascalVocFormat(self, filename, shapes, imagePath, imageData, label = shape['label'] # Add Chris difficult = int(shape['difficult']) - bndbox = LabelFile.convertPoints2BndBox(points) - writer.addBndBox(bndbox[0], bndbox[1], bndbox[2], bndbox[3], label, difficult) + bnd_box = LabelFile.convert_points_to_bnd_box(points) + writer.add_bnd_box(bnd_box[0], bnd_box[1], bnd_box[2], bnd_box[3], label, difficult) - writer.save(targetFile=filename) + writer.save(target_file=filename) return - def saveYoloFormat(self, filename, shapes, imagePath, imageData, classList, - lineColor=None, fillColor=None, databaseSrc=None): - imgFolderPath = os.path.dirname(imagePath) - imgFolderName = os.path.split(imgFolderPath)[-1] - imgFileName = os.path.basename(imagePath) - #imgFileNameWithoutExt = os.path.splitext(imgFileName)[0] + def save_yolo_format(self, filename, shapes, image_path, image_data, class_list, + line_color=None, fill_color=None, database_src=None): + img_folder_path = os.path.dirname(image_path) + img_folder_name = os.path.split(img_folder_path)[-1] + img_file_name = os.path.basename(image_path) + # imgFileNameWithoutExt = os.path.splitext(img_file_name)[0] # Read from file path because self.imageData might be empty if saving to # Pascal format - if isinstance(imageData, QImage): - image = imageData + if isinstance(image_data, QImage): + image = image_data else: image = QImage() - image.load(imagePath) - imageShape = [image.height(), image.width(), - 1 if image.isGrayscale() else 3] - writer = YOLOWriter(imgFolderName, imgFileName, - imageShape, localImgPath=imagePath) + image.load(image_path) + image_shape = [image.height(), image.width(), + 1 if image.isGrayscale() else 3] + writer = YOLOWriter(img_folder_name, img_file_name, + image_shape, local_img_path=image_path) writer.verified = self.verified for shape in shapes: @@ -109,13 +109,13 @@ def saveYoloFormat(self, filename, shapes, imagePath, imageData, classList, label = shape['label'] # Add Chris difficult = int(shape['difficult']) - bndbox = LabelFile.convertPoints2BndBox(points) - writer.addBndBox(bndbox[0], bndbox[1], bndbox[2], bndbox[3], label, difficult) + bnd_box = LabelFile.convert_points_to_bnd_box(points) + writer.add_bnd_box(bnd_box[0], bnd_box[1], bnd_box[2], bnd_box[3], label, difficult) - writer.save(targetFile=filename, classList=classList) + writer.save(target_file=filename, class_list=class_list) return - def toggleVerify(self): + def toggle_verify(self): self.verified = not self.verified ''' ttf is disable @@ -148,31 +148,31 @@ def save(self, filename, shapes, imagePath, imageData, lineColor=None, fillColor ''' @staticmethod - def isLabelFile(filename): - fileSuffix = os.path.splitext(filename)[1].lower() - return fileSuffix == LabelFile.suffix + def is_label_file(filename): + file_suffix = os.path.splitext(filename)[1].lower() + return file_suffix == LabelFile.suffix @staticmethod - def convertPoints2BndBox(points): - xmin = float('inf') - ymin = float('inf') - xmax = float('-inf') - ymax = float('-inf') + def convert_points_to_bnd_box(points): + x_min = float('inf') + y_min = float('inf') + x_max = float('-inf') + y_max = float('-inf') for p in points: x = p[0] y = p[1] - xmin = min(x, xmin) - ymin = min(y, ymin) - xmax = max(x, xmax) - ymax = max(y, ymax) + x_min = min(x, x_min) + y_min = min(y, y_min) + x_max = max(x, x_max) + y_max = max(y, y_max) # Martin Kersner, 2015/11/12 # 0-valued coordinates of BB caused an error while # training faster-rcnn object detector. - if xmin < 1: - xmin = 1 + if x_min < 1: + x_min = 1 - if ymin < 1: - ymin = 1 + if y_min < 1: + y_min = 1 - return (int(xmin), int(ymin), int(xmax), int(ymax)) + return int(x_min), int(y_min), int(x_max), int(y_max) diff --git a/libs/pascal_voc_io.py b/libs/pascal_voc_io.py index 627e315b4..370fcbc0e 100644 --- a/libs/pascal_voc_io.py +++ b/libs/pascal_voc_io.py @@ -14,13 +14,13 @@ class PascalVocWriter: - def __init__(self, foldername, filename, imgSize,databaseSrc='Unknown', localImgPath=None): - self.foldername = foldername + def __init__(self, folder_name, filename, img_size, database_src='Unknown', local_img_path=None): + self.foldername = folder_name self.filename = filename - self.databaseSrc = databaseSrc - self.imgSize = imgSize + self.databaseSrc = database_src + self.imgSize = img_size self.boxlist = [] - self.localImgPath = localImgPath + self.localImgPath = local_img_path self.verified = False def prettify(self, elem): @@ -31,10 +31,10 @@ def prettify(self, elem): root = etree.fromstring(rough_string) return etree.tostring(root, pretty_print=True, encoding=ENCODE_METHOD).replace(" ".encode(), "\t".encode()) # minidom does not support UTF-8 - '''reparsed = minidom.parseString(rough_string) - return reparsed.toprettyxml(indent="\t", encoding=ENCODE_METHOD)''' + # reparsed = minidom.parseString(rough_string) + # return reparsed.toprettyxml(indent="\t", encoding=ENCODE_METHOD) - def genXML(self): + def gen_xml(self): """ Return XML root """ @@ -55,8 +55,8 @@ def genXML(self): filename.text = self.filename if self.localImgPath is not None: - localImgPath = SubElement(top, 'path') - localImgPath.text = self.localImgPath + local_img_path = SubElement(top, 'path') + local_img_path.text = self.localImgPath source = SubElement(top, 'source') database = SubElement(source, 'database') @@ -77,13 +77,13 @@ def genXML(self): segmented.text = '0' return top - def addBndBox(self, xmin, ymin, xmax, ymax, name, difficult): - bndbox = {'xmin': xmin, 'ymin': ymin, 'xmax': xmax, 'ymax': ymax} - bndbox['name'] = name - bndbox['difficult'] = difficult - self.boxlist.append(bndbox) + def add_bnd_box(self, x_min, y_min, x_max, y_max, name, difficult): + bnd_box = {'xmin': x_min, 'ymin': y_min, 'xmax': x_max, 'ymax': y_max} + bnd_box['name'] = name + bnd_box['difficult'] = difficult + self.boxlist.append(bnd_box) - def appendObjects(self, top): + def append_objects(self, top): for each_object in self.boxlist: object_item = SubElement(top, 'object') name = SubElement(object_item, 'name') @@ -91,81 +91,81 @@ def appendObjects(self, top): pose = SubElement(object_item, 'pose') pose.text = "Unspecified" truncated = SubElement(object_item, 'truncated') - if int(float(each_object['ymax'])) == int(float(self.imgSize[0])) or (int(float(each_object['ymin']))== 1): - truncated.text = "1" # max == height or min - elif (int(float(each_object['xmax']))==int(float(self.imgSize[1]))) or (int(float(each_object['xmin']))== 1): - truncated.text = "1" # max == width or min + if int(float(each_object['ymax'])) == int(float(self.imgSize[0])) or (int(float(each_object['ymin'])) == 1): + truncated.text = "1" # max == height or min + elif (int(float(each_object['xmax'])) == int(float(self.imgSize[1]))) or (int(float(each_object['xmin'])) == 1): + truncated.text = "1" # max == width or min else: truncated.text = "0" difficult = SubElement(object_item, 'difficult') - difficult.text = str( bool(each_object['difficult']) & 1 ) - bndbox = SubElement(object_item, 'bndbox') - xmin = SubElement(bndbox, 'xmin') - xmin.text = str(each_object['xmin']) - ymin = SubElement(bndbox, 'ymin') - ymin.text = str(each_object['ymin']) - xmax = SubElement(bndbox, 'xmax') - xmax.text = str(each_object['xmax']) - ymax = SubElement(bndbox, 'ymax') - ymax.text = str(each_object['ymax']) - - def save(self, targetFile=None): - root = self.genXML() - self.appendObjects(root) + difficult.text = str(bool(each_object['difficult']) & 1) + bnd_box = SubElement(object_item, 'bndbox') + x_min = SubElement(bnd_box, 'xmin') + x_min.text = str(each_object['xmin']) + y_min = SubElement(bnd_box, 'ymin') + y_min.text = str(each_object['ymin']) + x_max = SubElement(bnd_box, 'xmax') + x_max.text = str(each_object['xmax']) + y_max = SubElement(bnd_box, 'ymax') + y_max.text = str(each_object['ymax']) + + def save(self, target_file=None): + root = self.gen_xml() + self.append_objects(root) out_file = None - if targetFile is None: + if target_file is None: out_file = codecs.open( self.filename + XML_EXT, 'w', encoding=ENCODE_METHOD) else: - out_file = codecs.open(targetFile, 'w', encoding=ENCODE_METHOD) + out_file = codecs.open(target_file, 'w', encoding=ENCODE_METHOD) - prettifyResult = self.prettify(root) - out_file.write(prettifyResult.decode('utf8')) + prettify_result = self.prettify(root) + out_file.write(prettify_result.decode('utf8')) out_file.close() class PascalVocReader: - def __init__(self, filepath): + def __init__(self, file_path): # shapes type: # [labbel, [(x1,y1), (x2,y2), (x3,y3), (x4,y4)], color, color, difficult] self.shapes = [] - self.filepath = filepath + self.filepath = file_path self.verified = False try: - self.parseXML() + self.parse_xml() except: pass - def getShapes(self): + def get_shapes(self): return self.shapes - def addShape(self, label, bndbox, difficult): - xmin = int(float(bndbox.find('xmin').text)) - ymin = int(float(bndbox.find('ymin').text)) - xmax = int(float(bndbox.find('xmax').text)) - ymax = int(float(bndbox.find('ymax').text)) - points = [(xmin, ymin), (xmax, ymin), (xmax, ymax), (xmin, ymax)] + def add_shape(self, label, bnd_box, difficult): + x_min = int(float(bnd_box.find('xmin').text)) + y_min = int(float(bnd_box.find('ymin').text)) + x_max = int(float(bnd_box.find('xmax').text)) + y_max = int(float(bnd_box.find('ymax').text)) + points = [(x_min, y_min), (x_max, y_min), (x_max, y_max), (x_min, y_max)] self.shapes.append((label, points, None, None, difficult)) - def parseXML(self): - assert self.filepath.endswith(XML_EXT), "Unsupport file format" + def parse_xml(self): + assert self.filepath.endswith(XML_EXT), "Unsupported file format" parser = etree.XMLParser(encoding=ENCODE_METHOD) - xmltree = ElementTree.parse(self.filepath, parser=parser).getroot() - filename = xmltree.find('filename').text + xml_tree = ElementTree.parse(self.filepath, parser=parser).getroot() + filename = xml_tree.find('filename').text try: - verified = xmltree.attrib['verified'] + verified = xml_tree.attrib['verified'] if verified == 'yes': self.verified = True except KeyError: self.verified = False - for object_iter in xmltree.findall('object'): - bndbox = object_iter.find("bndbox") + for object_iter in xml_tree.findall('object'): + bnd_box = object_iter.find("bndbox") label = object_iter.find('name').text # Add chris difficult = False if object_iter.find('difficult') is not None: difficult = bool(int(object_iter.find('difficult').text)) - self.addShape(label, bndbox, difficult) + self.add_shape(label, bnd_box, difficult) return True diff --git a/libs/shape.py b/libs/shape.py index 466e046dc..2df7f4653 100644 --- a/libs/shape.py +++ b/libs/shape.py @@ -32,19 +32,19 @@ class Shape(object): select_line_color = DEFAULT_SELECT_LINE_COLOR select_fill_color = DEFAULT_SELECT_FILL_COLOR vertex_fill_color = DEFAULT_VERTEX_FILL_COLOR - hvertex_fill_color = DEFAULT_HVERTEX_FILL_COLOR + h_vertex_fill_color = DEFAULT_HVERTEX_FILL_COLOR point_type = P_ROUND point_size = 8 scale = 1.0 labelFontSize = 8 - def __init__(self, label=None, line_color=None, difficult=False, paintLabel=False): + def __init__(self, label=None, line_color=None, difficult=False, paint_label=False): self.label = label self.points = [] self.fill = False self.selected = False self.difficult = difficult - self.paintLabel = paintLabel + self.paintLabel = paint_label self._highlightIndex = None self._highlightMode = self.NEAR_VERTEX @@ -64,24 +64,24 @@ def __init__(self, label=None, line_color=None, difficult=False, paintLabel=Fals def close(self): self._closed = True - def reachMaxPoints(self): + def reach_max_points(self): if len(self.points) >= 4: return True return False - def addPoint(self, point): - if not self.reachMaxPoints(): + def add_point(self, point): + if not self.reach_max_points(): self.points.append(point) - def popPoint(self): + def pop_point(self): if self.points: return self.points.pop() return None - def isClosed(self): + def is_closed(self): return self._closed - def setOpen(self): + def set_open(self): self._closed = False def paint(self, painter): @@ -93,23 +93,23 @@ def paint(self, painter): painter.setPen(pen) line_path = QPainterPath() - vrtx_path = QPainterPath() + vertex_path = QPainterPath() line_path.moveTo(self.points[0]) # Uncommenting the following line will draw 2 paths # for the 1st vertex, and make it non-filled, which # may be desirable. - #self.drawVertex(vrtx_path, 0) + # self.drawVertex(vertex_path, 0) for i, p in enumerate(self.points): line_path.lineTo(p) - self.drawVertex(vrtx_path, i) - if self.isClosed(): + self.draw_vertex(vertex_path, i) + if self.is_closed(): line_path.lineTo(self.points[0]) painter.drawPath(line_path) - painter.drawPath(vrtx_path) - painter.fillPath(vrtx_path, self.vertex_fill_color) + painter.drawPath(vertex_path) + painter.fillPath(vertex_path, self.vertex_fill_color) # Draw text at the top-left if self.paintLabel: @@ -124,9 +124,9 @@ def paint(self, painter): font.setPointSize(self.labelFontSize) font.setBold(True) painter.setFont(font) - if(self.label == None): + if self.label is None: self.label = "" - if(min_y < min_y_label): + if min_y < min_y_label: min_y += min_y_label painter.drawText(min_x, min_y, self.label) @@ -134,7 +134,7 @@ def paint(self, painter): color = self.select_fill_color if self.selected else self.fill_color painter.fillPath(line_path, color) - def drawVertex(self, path, i): + def draw_vertex(self, path, i): d = self.point_size / self.scale shape = self.point_type point = self.points[i] @@ -142,7 +142,7 @@ def drawVertex(self, path, i): size, shape = self._highlightSettings[self._highlightMode] d *= size if self._highlightIndex is not None: - self.vertex_fill_color = self.hvertex_fill_color + self.vertex_fill_color = self.h_vertex_fill_color else: self.vertex_fill_color = Shape.vertex_fill_color if shape == self.P_SQUARE: @@ -152,35 +152,35 @@ def drawVertex(self, path, i): else: assert False, "unsupported vertex shape" - def nearestVertex(self, point, epsilon): + def nearest_vertex(self, point, epsilon): for i, p in enumerate(self.points): if distance(p - point) <= epsilon: return i return None - def containsPoint(self, point): - return self.makePath().contains(point) + def contains_point(self, point): + return self.make_path().contains(point) - def makePath(self): + def make_path(self): path = QPainterPath(self.points[0]) for p in self.points[1:]: path.lineTo(p) return path - def boundingRect(self): - return self.makePath().boundingRect() + def bounding_rect(self): + return self.make_path().boundingRect() - def moveBy(self, offset): + def move_by(self, offset): self.points = [p + offset for p in self.points] - def moveVertexBy(self, i, offset): + def move_vertex_by(self, i, offset): self.points[i] = self.points[i] + offset - def highlightVertex(self, i, action): + def highlight_vertex(self, i, action): self._highlightIndex = i self._highlightMode = action - def highlightClear(self): + def highlight_clear(self): self._highlightIndex = None def copy(self): diff --git a/libs/stringBundle.py b/libs/stringBundle.py index a84f169bc..f3e6ee641 100644 --- a/libs/stringBundle.py +++ b/libs/stringBundle.py @@ -19,43 +19,43 @@ class StringBundle: __create_key = object() - def __init__(self, create_key, localeStr): + def __init__(self, create_key, locale_str): assert(create_key == StringBundle.__create_key), "StringBundle must be created using StringBundle.getBundle" self.idToMessage = {} - paths = self.__createLookupFallbackList(localeStr) + paths = self.__create_lookup_fallback_list(locale_str) for path in paths: - self.__loadBundle(path) + self.__load_bundle(path) @classmethod - def getBundle(cls, localeStr=None): - if localeStr is None: + def get_bundle(cls, locale_str=None): + if locale_str is None: try: - localeStr = locale.getlocale()[0] if locale.getlocale() and len( + locale_str = locale.getlocale()[0] if locale.getlocale() and len( locale.getlocale()) > 0 else os.getenv('LANG') except: print('Invalid locale') - localeStr = 'en' + locale_str = 'en' - return StringBundle(cls.__create_key, localeStr) + return StringBundle(cls.__create_key, locale_str) - def getString(self, stringId): - assert(stringId in self.idToMessage), "Missing string id : " + stringId - return self.idToMessage[stringId] + def get_string(self, string_id): + assert(string_id in self.idToMessage), "Missing string id : " + string_id + return self.idToMessage[string_id] - def __createLookupFallbackList(self, localeStr): - resultPaths = [] - basePath = ":/strings" - resultPaths.append(basePath) - if localeStr is not None: + def __create_lookup_fallback_list(self, locale_str): + result_paths = [] + base_path = ":/strings" + result_paths.append(base_path) + if locale_str is not None: # Don't follow standard BCP47. Simple fallback - tags = re.split('[^a-zA-Z]', localeStr) + tags = re.split('[^a-zA-Z]', locale_str) for tag in tags: - lastPath = resultPaths[-1] - resultPaths.append(lastPath + '-' + tag) + last_path = result_paths[-1] + result_paths.append(last_path + '-' + tag) - return resultPaths + return result_paths - def __loadBundle(self, path): + def __load_bundle(self, path): PROP_SEPERATOR = '=' f = QFile(path) if f.exists(): diff --git a/libs/ustr.py b/libs/ustr.py index 511e68b5e..bfcaff5d7 100644 --- a/libs/ustr.py +++ b/libs/ustr.py @@ -2,15 +2,15 @@ from libs.constants import DEFAULT_ENCODING def ustr(x): - '''py2/py3 unicode helper''' + """py2/py3 unicode helper""" if sys.version_info < (3, 0, 0): from PyQt4.QtCore import QString if type(x) == str: return x.decode(DEFAULT_ENCODING) if type(x) == QString: - #https://blog.csdn.net/friendan/article/details/51088476 - #https://blog.csdn.net/xxm524/article/details/74937308 + # https://blog.csdn.net/friendan/article/details/51088476 + # https://blog.csdn.net/xxm524/article/details/74937308 return unicode(x.toUtf8(), DEFAULT_ENCODING, 'ignore') return x else: diff --git a/libs/utils.py b/libs/utils.py index dacf682a1..d440a14d4 100644 --- a/libs/utils.py +++ b/libs/utils.py @@ -13,25 +13,25 @@ from PyQt4.QtCore import * -def newIcon(icon): +def new_icon(icon): return QIcon(':/' + icon) -def newButton(text, icon=None, slot=None): +def new_button(text, icon=None, slot=None): b = QPushButton(text) if icon is not None: - b.setIcon(newIcon(icon)) + b.setIcon(new_icon(icon)) if slot is not None: b.clicked.connect(slot) return b -def newAction(parent, text, slot=None, shortcut=None, icon=None, - tip=None, checkable=False, enabled=True): +def new_action(parent, text, slot=None, shortcut=None, icon=None, + tip=None, checkable=False, enabled=True): """Create a new action and assign callbacks, shortcuts, etc.""" a = QAction(text, parent) if icon is not None: - a.setIcon(newIcon(icon)) + a.setIcon(new_icon(icon)) if shortcut is not None: if isinstance(shortcut, (list, tuple)): a.setShortcuts(shortcut) @@ -48,7 +48,7 @@ def newAction(parent, text, slot=None, shortcut=None, icon=None, return a -def addActions(widget, actions): +def add_actions(widget, actions): for action in actions: if action is None: widget.addSeparator() @@ -58,11 +58,11 @@ def addActions(widget, actions): widget.addAction(action) -def labelValidator(): +def label_validator(): return QRegExpValidator(QRegExp(r'^[^ \t].+'), None) -class struct(object): +class Struct(object): def __init__(self, **kwargs): self.__dict__.update(kwargs) @@ -72,21 +72,21 @@ def distance(p): return sqrt(p.x() * p.x() + p.y() * p.y()) -def fmtShortcut(text): +def format_shortcut(text): mod, key = text.split('+', 1) return '%s+%s' % (mod, key) -def generateColorByText(text): +def generate_color_by_text(text): s = ustr(text) - hashCode = int(hashlib.sha256(s.encode('utf-8')).hexdigest(), 16) - r = int((hashCode / 255) % 255) - g = int((hashCode / 65025) % 255) - b = int((hashCode / 16581375) % 255) + hash_code = int(hashlib.sha256(s.encode('utf-8')).hexdigest(), 16) + r = int((hash_code / 255) % 255) + g = int((hash_code / 65025) % 255) + b = int((hash_code / 16581375) % 255) return QColor(r, g, b, 100) def have_qstring(): - '''p3/qt5 get rid of QString wrapper as py3 has native unicode str type''' + """p3/qt5 get rid of QString wrapper as py3 has native unicode str type""" return not (sys.version_info.major >= 3 or QT_VERSION_STR.startswith('5.')) def util_qt_strlistclass(): diff --git a/libs/yolo_io.py b/libs/yolo_io.py index 216fba388..7948d80bf 100644 --- a/libs/yolo_io.py +++ b/libs/yolo_io.py @@ -13,67 +13,67 @@ class YOLOWriter: - def __init__(self, foldername, filename, imgSize, databaseSrc='Unknown', localImgPath=None): - self.foldername = foldername + def __init__(self, folder_name, filename, img_size, database_src='Unknown', local_img_path=None): + self.foldername = folder_name self.filename = filename - self.databaseSrc = databaseSrc - self.imgSize = imgSize + self.databaseSrc = database_src + self.imgSize = img_size self.boxlist = [] - self.localImgPath = localImgPath + self.localImgPath = local_img_path self.verified = False - def addBndBox(self, xmin, ymin, xmax, ymax, name, difficult): - bndbox = {'xmin': xmin, 'ymin': ymin, 'xmax': xmax, 'ymax': ymax} - bndbox['name'] = name - bndbox['difficult'] = difficult - self.boxlist.append(bndbox) + def add_bnd_box(self, x_min, y_min, x_max, y_max, name, difficult): + bnd_box = {'xmin': x_min, 'ymin': y_min, 'xmax': x_max, 'ymax': y_max} + bnd_box['name'] = name + bnd_box['difficult'] = difficult + self.boxlist.append(bnd_box) - def BndBox2YoloLine(self, box, classList=[]): - xmin = box['xmin'] - xmax = box['xmax'] - ymin = box['ymin'] - ymax = box['ymax'] + def bnd_box_to_yolo_line(self, box, class_list=[]): + x_min = box['xmin'] + x_max = box['xmax'] + y_min = box['ymin'] + y_max = box['ymax'] - xcen = float((xmin + xmax)) / 2 / self.imgSize[1] - ycen = float((ymin + ymax)) / 2 / self.imgSize[0] + x_center = float((x_min + x_max)) / 2 / self.imgSize[1] + y_center = float((y_min + y_max)) / 2 / self.imgSize[0] - w = float((xmax - xmin)) / self.imgSize[1] - h = float((ymax - ymin)) / self.imgSize[0] + w = float((x_max - x_min)) / self.imgSize[1] + h = float((y_max - y_min)) / self.imgSize[0] # PR387 - boxName = box['name'] - if boxName not in classList: - classList.append(boxName) + box_name = box['name'] + if box_name not in class_list: + class_list.append(box_name) - classIndex = classList.index(boxName) + class_index = class_list.index(box_name) - return classIndex, xcen, ycen, w, h + return class_index, x_center, y_center, w, h - def save(self, classList=[], targetFile=None): + def save(self, class_list=[], target_file=None): - out_file = None #Update yolo .txt - out_class_file = None #Update class list .txt + out_file = None # Update yolo .txt + out_class_file = None # Update class list .txt - if targetFile is None: + if target_file is None: out_file = open( self.filename + TXT_EXT, 'w', encoding=ENCODE_METHOD) - classesFile = os.path.join(os.path.dirname(os.path.abspath(self.filename)), "classes.txt") - out_class_file = open(classesFile, 'w') + classes_file = os.path.join(os.path.dirname(os.path.abspath(self.filename)), "classes.txt") + out_class_file = open(classes_file, 'w') else: - out_file = codecs.open(targetFile, 'w', encoding=ENCODE_METHOD) - classesFile = os.path.join(os.path.dirname(os.path.abspath(targetFile)), "classes.txt") - out_class_file = open(classesFile, 'w') + out_file = codecs.open(target_file, 'w', encoding=ENCODE_METHOD) + classes_file = os.path.join(os.path.dirname(os.path.abspath(target_file)), "classes.txt") + out_class_file = open(classes_file, 'w') for box in self.boxlist: - classIndex, xcen, ycen, w, h = self.BndBox2YoloLine(box, classList) - # print (classIndex, xcen, ycen, w, h) - out_file.write("%d %.6f %.6f %.6f %.6f\n" % (classIndex, xcen, ycen, w, h)) + class_index, x_center, y_center, w, h = self.bnd_box_to_yolo_line(box, class_list) + # print (classIndex, x_center, y_center, w, h) + out_file.write("%d %.6f %.6f %.6f %.6f\n" % (class_index, x_center, y_center, w, h)) # print (classList) # print (out_class_file) - for c in classList: + for c in class_list: out_class_file.write(c+'\n') out_class_file.close() @@ -83,64 +83,64 @@ def save(self, classList=[], targetFile=None): class YoloReader: - def __init__(self, filepath, image, classListPath=None): + def __init__(self, file_path, image, class_list_path=None): # shapes type: # [labbel, [(x1,y1), (x2,y2), (x3,y3), (x4,y4)], color, color, difficult] self.shapes = [] - self.filepath = filepath + self.filepath = file_path - if classListPath is None: + if class_list_path is None: dir_path = os.path.dirname(os.path.realpath(self.filepath)) self.classListPath = os.path.join(dir_path, "classes.txt") else: - self.classListPath = classListPath + self.classListPath = class_list_path - # print (filepath, self.classListPath) + # print (file_path, self.classListPath) - classesFile = open(self.classListPath, 'r') - self.classes = classesFile.read().strip('\n').split('\n') + classes_file = open(self.classListPath, 'r') + self.classes = classes_file.read().strip('\n').split('\n') # print (self.classes) - imgSize = [image.height(), image.width(), - 1 if image.isGrayscale() else 3] + img_size = [image.height(), image.width(), + 1 if image.isGrayscale() else 3] - self.imgSize = imgSize + self.imgSize = img_size self.verified = False # try: - self.parseYoloFormat() + self.parse_yolo_format() # except: - # pass + # pass - def getShapes(self): + def get_shapes(self): return self.shapes - def addShape(self, label, xmin, ymin, xmax, ymax, difficult): + def add_shape(self, label, x_min, y_min, x_max, y_max, difficult): - points = [(xmin, ymin), (xmax, ymin), (xmax, ymax), (xmin, ymax)] + points = [(x_min, y_min), (x_max, y_min), (x_max, y_max), (x_min, y_max)] self.shapes.append((label, points, None, None, difficult)) - def yoloLine2Shape(self, classIndex, xcen, ycen, w, h): - label = self.classes[int(classIndex)] + def yolo_line_to_shape(self, class_index, x_center, y_center, w, h): + label = self.classes[int(class_index)] - xmin = max(float(xcen) - float(w) / 2, 0) - xmax = min(float(xcen) + float(w) / 2, 1) - ymin = max(float(ycen) - float(h) / 2, 0) - ymax = min(float(ycen) + float(h) / 2, 1) + x_min = max(float(x_center) - float(w) / 2, 0) + x_max = min(float(x_center) + float(w) / 2, 1) + y_min = max(float(y_center) - float(h) / 2, 0) + y_max = min(float(y_center) + float(h) / 2, 1) - xmin = int(self.imgSize[1] * xmin) - xmax = int(self.imgSize[1] * xmax) - ymin = int(self.imgSize[0] * ymin) - ymax = int(self.imgSize[0] * ymax) + x_min = int(self.imgSize[1] * x_min) + x_max = int(self.imgSize[1] * x_max) + y_min = int(self.imgSize[0] * y_min) + y_max = int(self.imgSize[0] * y_max) - return label, xmin, ymin, xmax, ymax + return label, x_min, y_min, x_max, y_max - def parseYoloFormat(self): - bndBoxFile = open(self.filepath, 'r') - for bndBox in bndBoxFile: - classIndex, xcen, ycen, w, h = bndBox.strip().split(' ') - label, xmin, ymin, xmax, ymax = self.yoloLine2Shape(classIndex, xcen, ycen, w, h) + def parse_yolo_format(self): + bnd_box_file = open(self.filepath, 'r') + for bndBox in bnd_box_file: + class_index, x_center, y_center, w, h = bndBox.strip().split(' ') + label, x_min, y_min, x_max, y_max = self.yolo_line_to_shape(class_index, x_center, y_center, w, h) # Caveat: difficult flag is discarded when saved as yolo format. - self.addShape(label, xmin, ymin, xmax, ymax, False) + self.add_shape(label, x_min, y_min, x_max, y_max, False) diff --git a/tests/test_io.py b/tests/test_io.py index 7a6d022e1..ce733a492 100644 --- a/tests/test_io.py +++ b/tests/test_io.py @@ -14,17 +14,17 @@ def test_upper(self): # Test Write/Read writer = PascalVocWriter('tests', 'test', (512, 512, 1), localImgPath='tests/test.512.512.bmp') difficult = 1 - writer.addBndBox(60, 40, 430, 504, 'person', difficult) - writer.addBndBox(113, 40, 450, 403, 'face', difficult) + writer.add_bnd_box(60, 40, 430, 504, 'person', difficult) + writer.add_bnd_box(113, 40, 450, 403, 'face', difficult) writer.save('tests/test.xml') reader = PascalVocReader('tests/test.xml') - shapes = reader.getShapes() + shapes = reader.get_shapes() - personBndBox = shapes[0] + person_bnd_box = shapes[0] face = shapes[1] - self.assertEqual(personBndBox[0], 'person') - self.assertEqual(personBndBox[1], [(60, 40), (430, 40), (430, 504), (60, 504)]) + self.assertEqual(person_bnd_box[0], 'person') + self.assertEqual(person_bnd_box[1], [(60, 40), (430, 40), (430, 504), (60, 504)]) self.assertEqual(face[0], 'face') self.assertEqual(face[1], [(113, 40), (450, 40), (450, 403), (113, 403)]) @@ -54,15 +54,15 @@ def test_a_write(self): # check written json with open(output_file, "r") as file: - inputdata = file.read() + input_data = file.read() import json - data_dict = json.loads(inputdata)[0] + data_dict = json.loads(input_data)[0] self.assertEqual('test.512.512.bmp', data_dict['image'], 'filename not correct in .json') - self.assertEqual(2, len(data_dict['annotations']), 'outputfile contains to less annotations') + self.assertEqual(2, len(data_dict['annotations']), 'output file contains to less annotations') face = data_dict['annotations'][1] - self.assertEqual('face', face['label'], 'labelname is wrong') + self.assertEqual('face', face['label'], 'label name is wrong') face_coords = face['coordinates'] self.assertEqual(expected_width, face_coords['width'], 'calculated width is wrong') self.assertEqual(expected_height, face_coords['height'], 'calculated height is wrong') @@ -84,15 +84,15 @@ def test_b_read(self): self.assertEqual('face', face[0], 'label is wrong') face_coords = face[1] - xmin = face_coords[0][0] - xmax = face_coords[1][0] - ymin = face_coords[0][1] - ymax = face_coords[2][1] - - self.assertEqual(245, xmin, 'xmin is wrong') - self.assertEqual(350, xmax, 'xmax is wrong') - self.assertEqual(250, ymin, 'ymin is wrong') - self.assertEqual(365, ymax, 'ymax is wrong') + x_min = face_coords[0][0] + x_max = face_coords[1][0] + y_min = face_coords[0][1] + y_max = face_coords[2][1] + + self.assertEqual(245, x_min, 'xmin is wrong') + self.assertEqual(350, x_max, 'xmax is wrong') + self.assertEqual(250, y_min, 'ymin is wrong') + self.assertEqual(365, y_max, 'ymax is wrong') if __name__ == '__main__': diff --git a/tests/test_stringBundle.py b/tests/test_stringBundle.py index d4eb7f262..0dea1044a 100644 --- a/tests/test_stringBundle.py +++ b/tests/test_stringBundle.py @@ -7,20 +7,20 @@ class TestStringBundle(unittest.TestCase): def test_loadDefaultBundle_withoutError(self): - strBundle = StringBundle.getBundle('en') - self.assertEqual(strBundle.getString("openDir"), 'Open Dir', 'Fail to load the default bundle') + str_bundle = StringBundle.get_bundle('en') + self.assertEqual(str_bundle.get_string("openDir"), 'Open Dir', 'Fail to load the default bundle') def test_fallback_withoutError(self): - strBundle = StringBundle.getBundle('zh-TW') - self.assertEqual(strBundle.getString("openDir"), u'\u958B\u555F\u76EE\u9304', 'Fail to load the zh-TW bundle') + str_bundle = StringBundle.get_bundle('zh-TW') + self.assertEqual(str_bundle.get_string("openDir"), u'\u958B\u555F\u76EE\u9304', 'Fail to load the zh-TW bundle') def test_setInvaleLocaleToEnv_printErrorMsg(self): prev_lc = os.environ['LC_ALL'] prev_lang = os.environ['LANG'] os.environ['LC_ALL'] = 'UTF-8' os.environ['LANG'] = 'UTF-8' - strBundle = StringBundle.getBundle() - self.assertEqual(strBundle.getString("openDir"), 'Open Dir', 'Fail to load the default bundle') + str_bundle = StringBundle.get_bundle() + self.assertEqual(str_bundle.get_string("openDir"), 'Open Dir', 'Fail to load the default bundle') os.environ['LC_ALL'] = prev_lc os.environ['LANG'] = prev_lang diff --git a/tests/test_utils.py b/tests/test_utils.py index 1b0a6c45e..a1971efcd 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,22 +1,22 @@ import os import sys import unittest -from libs.utils import struct, newAction, newIcon, addActions, fmtShortcut, generateColorByText, natural_sort +from libs.utils import Struct, new_action, new_icon, add_actions, format_shortcut, generate_color_by_text, natural_sort class TestUtils(unittest.TestCase): def test_generateColorByGivingUniceText_noError(self): - res = generateColorByText(u'\u958B\u555F\u76EE\u9304') + res = generate_color_by_text(u'\u958B\u555F\u76EE\u9304') self.assertTrue(res.green() >= 0) self.assertTrue(res.red() >= 0) self.assertTrue(res.blue() >= 0) def test_nautalSort_noError(self): - l1 = ['f1', 'f11', 'f3' ] - exptected_l1 = ['f1', 'f3', 'f11'] + l1 = ['f1', 'f11', 'f3'] + expected_l1 = ['f1', 'f3', 'f11'] natural_sort(l1) for idx, val in enumerate(l1): - self.assertTrue(val == exptected_l1[idx]) + self.assertTrue(val == expected_l1[idx]) if __name__ == '__main__': unittest.main() From 39b71f818b4ceb1b14050c2b659532232a810a6b Mon Sep 17 00:00:00 2001 From: Cerno_b Date: Mon, 8 Mar 2021 03:08:47 +0100 Subject: [PATCH 06/13] Rename non-Qt derived class' members --- labelImg.py | 2 +- libs/canvas.py | 2 +- libs/create_ml_io.py | 22 ++++++++++----------- libs/labelFile.py | 4 ++-- libs/pascal_voc_io.py | 44 ++++++++++++++++++++--------------------- libs/shape.py | 28 +++++++++++++------------- libs/stringBundle.py | 8 ++++---- libs/yolo_io.py | 46 +++++++++++++++++++++---------------------- 8 files changed, 78 insertions(+), 78 deletions(-) diff --git a/labelImg.py b/labelImg.py index d4890dcc8..3f30dcbfa 100755 --- a/labelImg.py +++ b/labelImg.py @@ -1061,7 +1061,7 @@ def load_file(self, file_path=None): % (e, unicode_file_path)) self.status("Error reading %s" % unicode_file_path) return False - self.imageData = self.labelFile.imageData + self.imageData = self.labelFile.image_data self.lineColor = QColor(*self.labelFile.lineColor) self.fillColor = QColor(*self.labelFile.fillColor) self.canvas.verified = self.labelFile.verified diff --git a/libs/canvas.py b/libs/canvas.py index e89192978..959c9e9dd 100644 --- a/libs/canvas.py +++ b/libs/canvas.py @@ -479,7 +479,7 @@ def paintEvent(self, event): p.drawPixmap(0, 0, self.pixmap) Shape.scale = self.scale - Shape.labelFontSize = self.labelFontSize + Shape.label_font_size = self.labelFontSize for shape in self.shapes: if (shape.selected or not self._hideBackround) and self.isVisible(shape): shape.fill = shape.selected or shape == self.hShape diff --git a/libs/create_ml_io.py b/libs/create_ml_io.py index 3c05a1692..922ae1f63 100644 --- a/libs/create_ml_io.py +++ b/libs/create_ml_io.py @@ -12,19 +12,19 @@ class CreateMLWriter: def __init__(self, folder_name, filename, img_size, shapes, output_file, database_src='Unknown', local_img_path=None): - self.foldername = folder_name + self.folder_name = folder_name self.filename = filename - self.databasesrc = database_src - self.imgsize = img_size - self.boxlist = [] - self.localimgpath = local_img_path + self.database_src = database_src + self.img_size = img_size + self.box_list = [] + self.local_img_path = local_img_path self.verified = False self.shapes = shapes - self.outputfile = output_file + self.output_file = output_file def write(self): - if os.path.isfile(self.outputfile): - with open(self.outputfile, "r") as file: + if os.path.isfile(self.output_file): + with open(self.output_file, "r") as file: input_data = file.read() output_dict = json.loads(input_data) else: @@ -67,7 +67,7 @@ def write(self): if not exists: output_dict.append(output_image_dict) - Path(self.outputfile).write_text(json.dumps(output_dict), ENCODE_METHOD) + Path(self.output_file).write_text(json.dumps(output_dict), ENCODE_METHOD) def calculate_coordinates(self, x1, x2, y1, y2): if x1 < x2: @@ -94,7 +94,7 @@ def calculate_coordinates(self, x1, x2, y1, y2): class CreateMLReader: def __init__(self, json_path, file_path): - self.jsonpath = json_path + self.json_path = json_path self.shapes = [] self.verified = False self.filename = file_path.split("/")[-1:][0] @@ -104,7 +104,7 @@ def __init__(self, json_path, file_path): print("JSON decoding failed") def parse_json(self): - with open(self.jsonpath, "r") as file: + with open(self.json_path, "r") as file: input_data = file.read() output_dict = json.loads(input_data) diff --git a/libs/labelFile.py b/libs/labelFile.py index c57106c91..378576771 100644 --- a/libs/labelFile.py +++ b/libs/labelFile.py @@ -34,8 +34,8 @@ class LabelFile(object): def __init__(self, filename=None): self.shapes = () - self.imagePath = None - self.imageData = None + self.image_path = None + self.image_data = None self.verified = False def save_create_ml_format(self, filename, shapes, image_path, image_data, class_list, line_color=None, fill_color=None, database_src=None): diff --git a/libs/pascal_voc_io.py b/libs/pascal_voc_io.py index 370fcbc0e..d8f7d690b 100644 --- a/libs/pascal_voc_io.py +++ b/libs/pascal_voc_io.py @@ -15,12 +15,12 @@ class PascalVocWriter: def __init__(self, folder_name, filename, img_size, database_src='Unknown', local_img_path=None): - self.foldername = folder_name + self.folder_name = folder_name self.filename = filename - self.databaseSrc = database_src - self.imgSize = img_size - self.boxlist = [] - self.localImgPath = local_img_path + self.database_src = database_src + self.img_size = img_size + self.box_list = [] + self.local_img_path = local_img_path self.verified = False def prettify(self, elem): @@ -40,8 +40,8 @@ def gen_xml(self): """ # Check conditions if self.filename is None or \ - self.foldername is None or \ - self.imgSize is None: + self.folder_name is None or \ + self.img_size is None: return None top = Element('annotation') @@ -49,27 +49,27 @@ def gen_xml(self): top.set('verified', 'yes') folder = SubElement(top, 'folder') - folder.text = self.foldername + folder.text = self.folder_name filename = SubElement(top, 'filename') filename.text = self.filename - if self.localImgPath is not None: + if self.local_img_path is not None: local_img_path = SubElement(top, 'path') - local_img_path.text = self.localImgPath + local_img_path.text = self.local_img_path source = SubElement(top, 'source') database = SubElement(source, 'database') - database.text = self.databaseSrc + database.text = self.database_src size_part = SubElement(top, 'size') width = SubElement(size_part, 'width') height = SubElement(size_part, 'height') depth = SubElement(size_part, 'depth') - width.text = str(self.imgSize[1]) - height.text = str(self.imgSize[0]) - if len(self.imgSize) == 3: - depth.text = str(self.imgSize[2]) + width.text = str(self.img_size[1]) + height.text = str(self.img_size[0]) + if len(self.img_size) == 3: + depth.text = str(self.img_size[2]) else: depth.text = '1' @@ -81,19 +81,19 @@ def add_bnd_box(self, x_min, y_min, x_max, y_max, name, difficult): bnd_box = {'xmin': x_min, 'ymin': y_min, 'xmax': x_max, 'ymax': y_max} bnd_box['name'] = name bnd_box['difficult'] = difficult - self.boxlist.append(bnd_box) + self.box_list.append(bnd_box) def append_objects(self, top): - for each_object in self.boxlist: + for each_object in self.box_list: object_item = SubElement(top, 'object') name = SubElement(object_item, 'name') name.text = ustr(each_object['name']) pose = SubElement(object_item, 'pose') pose.text = "Unspecified" truncated = SubElement(object_item, 'truncated') - if int(float(each_object['ymax'])) == int(float(self.imgSize[0])) or (int(float(each_object['ymin'])) == 1): + if int(float(each_object['ymax'])) == int(float(self.img_size[0])) or (int(float(each_object['ymin'])) == 1): truncated.text = "1" # max == height or min - elif (int(float(each_object['xmax'])) == int(float(self.imgSize[1]))) or (int(float(each_object['xmin'])) == 1): + elif (int(float(each_object['xmax'])) == int(float(self.img_size[1]))) or (int(float(each_object['xmin'])) == 1): truncated.text = "1" # max == width or min else: truncated.text = "0" @@ -130,7 +130,7 @@ def __init__(self, file_path): # shapes type: # [labbel, [(x1,y1), (x2,y2), (x3,y3), (x4,y4)], color, color, difficult] self.shapes = [] - self.filepath = file_path + self.file_path = file_path self.verified = False try: self.parse_xml() @@ -149,9 +149,9 @@ def add_shape(self, label, bnd_box, difficult): self.shapes.append((label, points, None, None, difficult)) def parse_xml(self): - assert self.filepath.endswith(XML_EXT), "Unsupported file format" + assert self.file_path.endswith(XML_EXT), "Unsupported file format" parser = etree.XMLParser(encoding=ENCODE_METHOD) - xml_tree = ElementTree.parse(self.filepath, parser=parser).getroot() + xml_tree = ElementTree.parse(self.file_path, parser=parser).getroot() filename = xml_tree.find('filename').text try: verified = xml_tree.attrib['verified'] diff --git a/libs/shape.py b/libs/shape.py index 2df7f4653..04cf1f96f 100644 --- a/libs/shape.py +++ b/libs/shape.py @@ -36,7 +36,7 @@ class Shape(object): point_type = P_ROUND point_size = 8 scale = 1.0 - labelFontSize = 8 + label_font_size = 8 def __init__(self, label=None, line_color=None, difficult=False, paint_label=False): self.label = label @@ -44,11 +44,11 @@ def __init__(self, label=None, line_color=None, difficult=False, paint_label=Fal self.fill = False self.selected = False self.difficult = difficult - self.paintLabel = paint_label + self.paint_label = paint_label - self._highlightIndex = None - self._highlightMode = self.NEAR_VERTEX - self._highlightSettings = { + self._highlight_index = None + self._highlight_mode = self.NEAR_VERTEX + self._highlight_settings = { self.NEAR_VERTEX: (4, self.P_ROUND), self.MOVE_VERTEX: (1.5, self.P_SQUARE), } @@ -112,16 +112,16 @@ def paint(self, painter): painter.fillPath(vertex_path, self.vertex_fill_color) # Draw text at the top-left - if self.paintLabel: + if self.paint_label: min_x = sys.maxsize min_y = sys.maxsize - min_y_label = int(1.25 * self.labelFontSize) + min_y_label = int(1.25 * self.label_font_size) for point in self.points: min_x = min(min_x, point.x()) min_y = min(min_y, point.y()) if min_x != sys.maxsize and min_y != sys.maxsize: font = QFont() - font.setPointSize(self.labelFontSize) + font.setPointSize(self.label_font_size) font.setBold(True) painter.setFont(font) if self.label is None: @@ -138,10 +138,10 @@ def draw_vertex(self, path, i): d = self.point_size / self.scale shape = self.point_type point = self.points[i] - if i == self._highlightIndex: - size, shape = self._highlightSettings[self._highlightMode] + if i == self._highlight_index: + size, shape = self._highlight_settings[self._highlight_mode] d *= size - if self._highlightIndex is not None: + if self._highlight_index is not None: self.vertex_fill_color = self.h_vertex_fill_color else: self.vertex_fill_color = Shape.vertex_fill_color @@ -177,11 +177,11 @@ def move_vertex_by(self, i, offset): self.points[i] = self.points[i] + offset def highlight_vertex(self, i, action): - self._highlightIndex = i - self._highlightMode = action + self._highlight_index = i + self._highlight_mode = action def highlight_clear(self): - self._highlightIndex = None + self._highlight_index = None def copy(self): shape = Shape("%s" % self.label) diff --git a/libs/stringBundle.py b/libs/stringBundle.py index f3e6ee641..dfd785908 100644 --- a/libs/stringBundle.py +++ b/libs/stringBundle.py @@ -21,7 +21,7 @@ class StringBundle: def __init__(self, create_key, locale_str): assert(create_key == StringBundle.__create_key), "StringBundle must be created using StringBundle.getBundle" - self.idToMessage = {} + self.id_to_message = {} paths = self.__create_lookup_fallback_list(locale_str) for path in paths: self.__load_bundle(path) @@ -39,8 +39,8 @@ def get_bundle(cls, locale_str=None): return StringBundle(cls.__create_key, locale_str) def get_string(self, string_id): - assert(string_id in self.idToMessage), "Missing string id : " + string_id - return self.idToMessage[string_id] + assert(string_id in self.id_to_message), "Missing string id : " + string_id + return self.id_to_message[string_id] def __create_lookup_fallback_list(self, locale_str): result_paths = [] @@ -68,6 +68,6 @@ def __load_bundle(self, path): key_value = line.split(PROP_SEPERATOR) key = key_value[0].strip() value = PROP_SEPERATOR.join(key_value[1:]).strip().strip('"') - self.idToMessage[key] = value + self.id_to_message[key] = value f.close() diff --git a/libs/yolo_io.py b/libs/yolo_io.py index 7948d80bf..039acdb6d 100644 --- a/libs/yolo_io.py +++ b/libs/yolo_io.py @@ -14,19 +14,19 @@ class YOLOWriter: def __init__(self, folder_name, filename, img_size, database_src='Unknown', local_img_path=None): - self.foldername = folder_name + self.folder_name = folder_name self.filename = filename - self.databaseSrc = database_src - self.imgSize = img_size - self.boxlist = [] - self.localImgPath = local_img_path + self.database_src = database_src + self.img_size = img_size + self.box_list = [] + self.local_img_path = local_img_path self.verified = False def add_bnd_box(self, x_min, y_min, x_max, y_max, name, difficult): bnd_box = {'xmin': x_min, 'ymin': y_min, 'xmax': x_max, 'ymax': y_max} bnd_box['name'] = name bnd_box['difficult'] = difficult - self.boxlist.append(bnd_box) + self.box_list.append(bnd_box) def bnd_box_to_yolo_line(self, box, class_list=[]): x_min = box['xmin'] @@ -34,11 +34,11 @@ def bnd_box_to_yolo_line(self, box, class_list=[]): y_min = box['ymin'] y_max = box['ymax'] - x_center = float((x_min + x_max)) / 2 / self.imgSize[1] - y_center = float((y_min + y_max)) / 2 / self.imgSize[0] + x_center = float((x_min + x_max)) / 2 / self.img_size[1] + y_center = float((y_min + y_max)) / 2 / self.img_size[0] - w = float((x_max - x_min)) / self.imgSize[1] - h = float((y_max - y_min)) / self.imgSize[0] + w = float((x_max - x_min)) / self.img_size[1] + h = float((y_max - y_min)) / self.img_size[0] # PR387 box_name = box['name'] @@ -66,7 +66,7 @@ def save(self, class_list=[], target_file=None): out_class_file = open(classes_file, 'w') - for box in self.boxlist: + for box in self.box_list: class_index, x_center, y_center, w, h = self.bnd_box_to_yolo_line(box, class_list) # print (classIndex, x_center, y_center, w, h) out_file.write("%d %.6f %.6f %.6f %.6f\n" % (class_index, x_center, y_center, w, h)) @@ -87,17 +87,17 @@ def __init__(self, file_path, image, class_list_path=None): # shapes type: # [labbel, [(x1,y1), (x2,y2), (x3,y3), (x4,y4)], color, color, difficult] self.shapes = [] - self.filepath = file_path + self.file_path = file_path if class_list_path is None: - dir_path = os.path.dirname(os.path.realpath(self.filepath)) - self.classListPath = os.path.join(dir_path, "classes.txt") + dir_path = os.path.dirname(os.path.realpath(self.file_path)) + self.class_list_path = os.path.join(dir_path, "classes.txt") else: - self.classListPath = class_list_path + self.class_list_path = class_list_path - # print (file_path, self.classListPath) + # print (file_path, self.class_list_path) - classes_file = open(self.classListPath, 'r') + classes_file = open(self.class_list_path, 'r') self.classes = classes_file.read().strip('\n').split('\n') # print (self.classes) @@ -105,7 +105,7 @@ def __init__(self, file_path, image, class_list_path=None): img_size = [image.height(), image.width(), 1 if image.isGrayscale() else 3] - self.imgSize = img_size + self.img_size = img_size self.verified = False # try: @@ -129,15 +129,15 @@ def yolo_line_to_shape(self, class_index, x_center, y_center, w, h): y_min = max(float(y_center) - float(h) / 2, 0) y_max = min(float(y_center) + float(h) / 2, 1) - x_min = int(self.imgSize[1] * x_min) - x_max = int(self.imgSize[1] * x_max) - y_min = int(self.imgSize[0] * y_min) - y_max = int(self.imgSize[0] * y_max) + x_min = int(self.img_size[1] * x_min) + x_max = int(self.img_size[1] * x_max) + y_min = int(self.img_size[0] * y_min) + y_max = int(self.img_size[0] * y_max) return label, x_min, y_min, x_max, y_max def parse_yolo_format(self): - bnd_box_file = open(self.filepath, 'r') + bnd_box_file = open(self.file_path, 'r') for bndBox in bnd_box_file: class_index, x_center, y_center, w, h = bndBox.strip().split(' ') label, x_min, y_min, x_max, y_max = self.yolo_line_to_shape(class_index, x_center, y_center, w, h) From ba2792cd1523919a9630c00d4ddcbc1b72e41b82 Mon Sep 17 00:00:00 2001 From: Cerno_b Date: Mon, 8 Mar 2021 03:31:38 +0100 Subject: [PATCH 07/13] Rename members of Qt-derived classes --- labelImg.py | 638 ++++++++++++++++++++++---------------------- libs/canvas.py | 208 +++++++-------- libs/labelDialog.py | 12 +- 3 files changed, 429 insertions(+), 429 deletions(-) diff --git a/labelImg.py b/labelImg.py index 3f30dcbfa..1fd419b0b 100755 --- a/labelImg.py +++ b/labelImg.py @@ -84,76 +84,76 @@ def __init__(self, default_filename=None, default_prefdef_class_file=None, defau settings = self.settings # Load string bundle for i18n - self.stringBundle = StringBundle.get_bundle() - get_str = lambda str_id: self.stringBundle.get_string(str_id) + self.string_bundle = StringBundle.get_bundle() + get_str = lambda str_id: self.string_bundle.get_string(str_id) # Save as Pascal voc xml - self.defaultSaveDir = default_save_dir - self.labelFileFormat = settings.get(SETTING_LABEL_FILE_FORMAT, LabelFileFormat.PASCAL_VOC) + self.default_save_dir = default_save_dir + self.label_file_format = 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 + self.m_img_list = [] + self.dir_name = None + self.label_hist = [] + self.last_open_dir = None # Whether we need to save or not. self.dirty = False - self._noSelectionSlot = False + self._no_selection_slot = False self._beginner = True - self.screencastViewer = self.get_available_screencast_viewer() + self.screencast_viewer = self.get_available_screencast_viewer() self.screencast = "https://youtu.be/p0nR2YsCY_U" # Load predefined classes to the list self.load_predefined_classes(default_prefdef_class_file) # Main widgets and related state. - self.labelDialog = LabelDialog(parent=self, list_item=self.labelHist) + self.label_dialog = LabelDialog(parent=self, list_item=self.label_hist) - self.itemsToShapes = {} - self.shapesToItems = {} - self.prevLabelText = '' + self.items_to_shapes = {} + self.shapes_to_items = {} + self.prev_label_text = '' list_layout = QVBoxLayout() list_layout.setContentsMargins(0, 0, 0, 0) # Create a widget for using default label - self.useDefaultLabelCheckbox = QCheckBox(get_str('useDefaultLabel')) - self.useDefaultLabelCheckbox.setChecked(False) - self.defaultLabelTextLine = QLineEdit() + self.use_default_label_checkbox = QCheckBox(get_str('useDefaultLabel')) + self.use_default_label_checkbox.setChecked(False) + self.default_label_text_line = QLineEdit() use_default_label_qhbox_layout = QHBoxLayout() - use_default_label_qhbox_layout.addWidget(self.useDefaultLabelCheckbox) - use_default_label_qhbox_layout.addWidget(self.defaultLabelTextLine) + use_default_label_qhbox_layout.addWidget(self.use_default_label_checkbox) + use_default_label_qhbox_layout.addWidget(self.default_label_text_line) use_default_label_container = QWidget() use_default_label_container.setLayout(use_default_label_qhbox_layout) # Create a widget for edit and diffc button - self.diffcButton = QCheckBox(get_str('useDifficult')) - self.diffcButton.setChecked(False) - self.diffcButton.stateChanged.connect(self.button_state) - self.editButton = QToolButton() - self.editButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) + self.diffc_button = QCheckBox(get_str('useDifficult')) + self.diffc_button.setChecked(False) + self.diffc_button.stateChanged.connect(self.button_state) + self.edit_button = QToolButton() + self.edit_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) # Add some of widgets to list_layout - list_layout.addWidget(self.editButton) - list_layout.addWidget(self.diffcButton) + list_layout.addWidget(self.edit_button) + list_layout.addWidget(self.diffc_button) list_layout.addWidget(use_default_label_container) # Create and add combobox for showing unique labels in group - self.comboBox = ComboBox(self) - list_layout.addWidget(self.comboBox) + self.combo_box = ComboBox(self) + list_layout.addWidget(self.combo_box) # Create and add a widget for showing current label items - self.labelList = QListWidget() + self.label_list = QListWidget() label_list_container = QWidget() label_list_container.setLayout(list_layout) - self.labelList.itemActivated.connect(self.label_selection_changed) - self.labelList.itemSelectionChanged.connect(self.label_selection_changed) - self.labelList.itemDoubleClicked.connect(self.edit_label) + self.label_list.itemActivated.connect(self.label_selection_changed) + self.label_list.itemSelectionChanged.connect(self.label_selection_changed) + self.label_list.itemDoubleClicked.connect(self.edit_label) # Connect to itemChanged to detect checkbox changes. - self.labelList.itemChanged.connect(self.label_item_changed) - list_layout.addWidget(self.labelList) + self.label_list.itemChanged.connect(self.label_item_changed) + list_layout.addWidget(self.label_list) @@ -161,19 +161,19 @@ def __init__(self, default_filename=None, default_prefdef_class_file=None, defau self.dock.setObjectName(get_str('labels')) self.dock.setWidget(label_list_container) - self.fileListWidget = QListWidget() - self.fileListWidget.itemDoubleClicked.connect(self.file_item_double_clicked) + self.file_list_widget = QListWidget() + self.file_list_widget.itemDoubleClicked.connect(self.file_item_double_clicked) file_list_layout = QVBoxLayout() file_list_layout.setContentsMargins(0, 0, 0, 0) - file_list_layout.addWidget(self.fileListWidget) + file_list_layout.addWidget(self.file_list_widget) file_list_container = QWidget() file_list_container.setLayout(file_list_layout) - self.filedock = QDockWidget(get_str('fileList'), self) - self.filedock.setObjectName(get_str('files')) - self.filedock.setWidget(file_list_container) + self.file_dock = QDockWidget(get_str('fileList'), self) + self.file_dock.setObjectName(get_str('files')) + self.file_dock.setWidget(file_list_container) - self.zoomWidget = ZoomWidget() - self.colorDialog = ColorDialog(parent=self) + self.zoom_widget = ZoomWidget() + self.color_dialog = ColorDialog(parent=self) self.canvas = Canvas(parent=self) self.canvas.zoomRequest.connect(self.zoom_request) @@ -182,11 +182,11 @@ def __init__(self, default_filename=None, default_prefdef_class_file=None, defau scroll = QScrollArea() scroll.setWidget(self.canvas) scroll.setWidgetResizable(True) - self.scrollBars = { + self.scroll_bars = { Qt.Vertical: scroll.verticalScrollBar(), Qt.Horizontal: scroll.horizontalScrollBar() } - self.scrollArea = scroll + self.scroll_area = scroll self.canvas.scrollRequest.connect(self.scroll_request) self.canvas.newShape.connect(self.new_shape) @@ -196,11 +196,11 @@ def __init__(self, default_filename=None, default_prefdef_class_file=None, defau self.setCentralWidget(scroll) self.addDockWidget(Qt.RightDockWidgetArea, self.dock) - self.addDockWidget(Qt.RightDockWidgetArea, self.filedock) - self.filedock.setFeatures(QDockWidget.DockWidgetFloatable) + self.addDockWidget(Qt.RightDockWidgetArea, self.file_dock) + self.file_dock.setFeatures(QDockWidget.DockWidgetFloatable) - self.dockFeatures = QDockWidget.DockWidgetClosable | QDockWidget.DockWidgetFloatable - self.dock.setFeatures(self.dock.features() ^ self.dockFeatures) + self.dock_features = QDockWidget.DockWidgetClosable | QDockWidget.DockWidgetFloatable + self.dock.setFeatures(self.dock.features() ^ self.dock_features) # Actions action = partial(new_action, self) @@ -245,9 +245,9 @@ def get_format_meta(format): elif format == LabelFileFormat.CREATE_ML: return '&CreateML', 'format_createml' - save_format = action(get_format_meta(self.labelFileFormat)[0], + save_format = action(get_format_meta(self.label_file_format)[0], self.change_format, 'Ctrl+', - get_format_meta(self.labelFileFormat)[1], + get_format_meta(self.label_file_format)[1], get_str('changeSaveFormat'), enabled=True) save_as = action(get_str('saveAs'), self.save_file_as, @@ -290,12 +290,12 @@ def get_format_meta(format): show_info = action(get_str('info'), self.show_info_dialog, None, 'help', get_str('info')) zoom = QWidgetAction(self) - zoom.setDefaultWidget(self.zoomWidget) - self.zoomWidget.setWhatsThis( + zoom.setDefaultWidget(self.zoom_widget) + self.zoom_widget.setWhatsThis( u"Zoom in or out of the image. Also accessible with" " %s and %s from the canvas." % (format_shortcut("Ctrl+[-+]"), format_shortcut("Ctrl+Wheel"))) - self.zoomWidget.setEnabled(False) + self.zoom_widget.setEnabled(False) zoom_in = action(get_str('zoomin'), partial(self.add_zoom, 10), 'Ctrl++', 'zoom-in', get_str('zoominDetail'), enabled=False) @@ -310,9 +310,9 @@ def get_format_meta(format): 'Ctrl+Shift+F', 'fit-width', get_str('fitWidthDetail'), checkable=True, enabled=False) # Group zoom controls into a list for easier toggling. - zoom_actions = (self.zoomWidget, zoom_in, zoom_out, + zoom_actions = (self.zoom_widget, zoom_in, zoom_out, zoom_org, fit_window, fit_width) - self.zoomMode = self.MANUAL_ZOOM + self.zoom_mode = self.MANUAL_ZOOM self.scalers = { self.FIT_WINDOW: self.scale_fit_window, self.FIT_WIDTH: self.scale_fit_width, @@ -323,7 +323,7 @@ def get_format_meta(format): edit = action(get_str('editLabel'), self.edit_label, 'Ctrl+E', 'edit', get_str('editLabelDetail'), enabled=False) - self.editButton.setDefaultAction(edit) + self.edit_button.setDefaultAction(edit) shape_line_color = action(get_str('shapeLineColor'), self.choose_shape_line_color, icon='color_line', tip=get_str('shapeLineColorDetail'), @@ -339,16 +339,16 @@ def get_format_meta(format): # Label list context menu. label_menu = QMenu() add_actions(label_menu, (edit, delete)) - self.labelList.setContextMenuPolicy(Qt.CustomContextMenu) - self.labelList.customContextMenuRequested.connect( + self.label_list.setContextMenuPolicy(Qt.CustomContextMenu) + self.label_list.customContextMenuRequested.connect( self.pop_label_list_menu) # 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.toggle_draw_square) + self.draw_squares_option = QAction('Draw Squares', self) + self.draw_squares_option.setShortcut('Ctrl+Shift+R') + self.draw_squares_option.setCheckable(True) + self.draw_squares_option.setChecked(settings.get(SETTING_DRAW_SQUARE, False)) + self.draw_squares_option.triggered.connect(self.toggle_draw_square) # Store actions for further handling. self.actions = Struct(save=save, save_format=save_format, saveAs=save_as, open=open, close=close, resetAll=reset_all, deleteImg=delete_image, @@ -362,7 +362,7 @@ def get_format_meta(format): open, open_dir, save, save_as, close, reset_all, quit), beginner=(), advanced=(), editMenu=(edit, copy, delete, - None, color1, self.drawSquaresOption), + None, color1, self.draw_squares_option), beginnerContext=(create, edit, copy, delete), advancedContext=(create_mode, edit_mode, edit, copy, delete, shape_line_color, shape_fill_color), @@ -379,29 +379,29 @@ def get_format_meta(format): labelList=label_menu) # Auto saving : Enable auto saving if pressing next - self.autoSaving = QAction(get_str('autoSaveMode'), self) - self.autoSaving.setCheckable(True) - self.autoSaving.setChecked(settings.get(SETTING_AUTO_SAVE, False)) + self.auto_saving = QAction(get_str('autoSaveMode'), self) + self.auto_saving.setCheckable(True) + self.auto_saving.setChecked(settings.get(SETTING_AUTO_SAVE, False)) # Sync single class mode from PR#106 - self.singleClassMode = QAction(get_str('singleClsMode'), self) - self.singleClassMode.setShortcut("Ctrl+Shift+S") - self.singleClassMode.setCheckable(True) - self.singleClassMode.setChecked(settings.get(SETTING_SINGLE_CLASS, False)) + self.single_class_mode = QAction(get_str('singleClsMode'), self) + self.single_class_mode.setShortcut("Ctrl+Shift+S") + self.single_class_mode.setCheckable(True) + self.single_class_mode.setChecked(settings.get(SETTING_SINGLE_CLASS, False)) self.lastLabel = None # Add option to enable/disable labels being displayed at the top of bounding boxes - self.displayLabelOption = QAction(get_str('displayLabel'), self) - self.displayLabelOption.setShortcut("Ctrl+Shift+P") - self.displayLabelOption.setCheckable(True) - self.displayLabelOption.setChecked(settings.get(SETTING_PAINT_LABEL, False)) - self.displayLabelOption.triggered.connect(self.toggle_paint_labels_option) + self.display_label_option = QAction(get_str('displayLabel'), self) + self.display_label_option.setShortcut("Ctrl+Shift+P") + self.display_label_option.setCheckable(True) + self.display_label_option.setChecked(settings.get(SETTING_PAINT_LABEL, False)) + self.display_label_option.triggered.connect(self.toggle_paint_labels_option) add_actions(self.menus.file, (open, open_dir, copy_prev_bounding, change_save_dir, open_annotation, self.menus.recentFiles, save, save_format, save_as, close, reset_all, delete_image, quit)) add_actions(self.menus.help, (help, show_info)) add_actions(self.menus.view, ( - self.autoSaving, - self.singleClassMode, - self.displayLabelOption, + self.auto_saving, + self.single_class_mode, + self.display_label_option, labels, advanced_mode, None, hide_all, show_all, None, zoom_in, zoom_out, zoom_org, None, @@ -430,12 +430,12 @@ def get_format_meta(format): # Application state. self.image = QImage() - self.filePath = ustr(default_filename) - self.lastOpenDir = None - self.recentFiles = [] - self.maxRecent = 7 - self.lineColor = None - self.fillColor = None + self.file_path = ustr(default_filename) + self.last_open_dir = None + self.recent_files = [] + self.max_recent = 7 + self.line_color = None + self.fill_color = None self.zoom_level = 100 self.fit_window = False # Add Chris @@ -445,9 +445,9 @@ def get_format_meta(format): if settings.get(SETTING_RECENT_FILES): if have_qstring(): recent_file_qstring_list = settings.get(SETTING_RECENT_FILES) - self.recentFiles = [ustr(i) for i in recent_file_qstring_list] + self.recent_files = [ustr(i) for i in recent_file_qstring_list] else: - self.recentFiles = recent_file_qstring_list = settings.get(SETTING_RECENT_FILES) + self.recent_files = recent_file_qstring_list = settings.get(SETTING_RECENT_FILES) size = settings.get(SETTING_WIN_SIZE, QSize(600, 500)) position = QPoint(0, 0) @@ -460,17 +460,17 @@ def get_format_meta(format): self.resize(size) self.move(position) save_dir = ustr(settings.get(SETTING_SAVE_DIR, None)) - self.lastOpenDir = ustr(settings.get(SETTING_LAST_OPEN_DIR, None)) - if self.defaultSaveDir is None and save_dir is not None and os.path.exists(save_dir): - self.defaultSaveDir = save_dir + self.last_open_dir = ustr(settings.get(SETTING_LAST_OPEN_DIR, None)) + if self.default_save_dir is None and save_dir is not None and os.path.exists(save_dir): + self.default_save_dir = save_dir self.statusBar().showMessage('%s started. Annotation will be saved to %s' % - (__appname__, self.defaultSaveDir)) + (__appname__, self.default_save_dir)) 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.set_drawing_color(self.lineColor) + Shape.line_color = self.line_color = QColor(settings.get(SETTING_LINE_COLOR, DEFAULT_LINE_COLOR)) + Shape.fill_color = self.fill_color = QColor(settings.get(SETTING_FILL_COLOR, DEFAULT_FILL_COLOR)) + self.canvas.set_drawing_color(self.line_color) # Add chris Shape.difficult = self.difficult @@ -487,23 +487,23 @@ def xbool(x): self.update_file_menu() # 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.queue_event(partial(self.import_dir_images, self.filePath or "")) - elif self.filePath: - self.queue_event(partial(self.load_file, self.filePath or "")) + if self.file_path and os.path.isdir(self.file_path): + self.queue_event(partial(self.import_dir_images, self.file_path or "")) + elif self.file_path: + self.queue_event(partial(self.load_file, self.file_path or "")) # Callbacks: - self.zoomWidget.valueChanged.connect(self.paint_canvas) + self.zoom_widget.valueChanged.connect(self.paint_canvas) self.populate_mode_actions() # Display cursor coordinates at the right of status bar - self.labelCoordinates = QLabel('') - self.statusBar().addPermanentWidget(self.labelCoordinates) + self.label_coordinates = QLabel('') + self.statusBar().addPermanentWidget(self.label_coordinates) # Open Dir if default file - if self.filePath and os.path.isdir(self.filePath): - self.open_dir_dialog(dir_path=self.filePath, silent=True) + if self.file_path and os.path.isdir(self.file_path): + self.open_dir_dialog(dir_path=self.file_path, silent=True) def keyReleaseEvent(self, event): if event.key() == Qt.Key_Control: @@ -519,46 +519,46 @@ def set_format(self, save_format): if save_format == FORMAT_PASCALVOC: self.actions.save_format.setText(FORMAT_PASCALVOC) self.actions.save_format.setIcon(new_icon("format_voc")) - self.labelFileFormat = LabelFileFormat.PASCAL_VOC + self.label_file_format = LabelFileFormat.PASCAL_VOC LabelFile.suffix = XML_EXT elif save_format == FORMAT_YOLO: self.actions.save_format.setText(FORMAT_YOLO) self.actions.save_format.setIcon(new_icon("format_yolo")) - self.labelFileFormat = LabelFileFormat.YOLO + self.label_file_format = LabelFileFormat.YOLO LabelFile.suffix = TXT_EXT elif save_format == FORMAT_CREATEML: self.actions.save_format.setText(FORMAT_CREATEML) self.actions.save_format.setIcon(new_icon("format_createml")) - self.labelFileFormat = LabelFileFormat.CREATE_ML + self.label_file_format = LabelFileFormat.CREATE_ML LabelFile.suffix = JSON_EXT def change_format(self): - if self.labelFileFormat == LabelFileFormat.PASCAL_VOC: + if self.label_file_format == LabelFileFormat.PASCAL_VOC: self.set_format(FORMAT_YOLO) - elif self.labelFileFormat == LabelFileFormat.YOLO: + elif self.label_file_format == LabelFileFormat.YOLO: self.set_format(FORMAT_CREATEML) - elif self.labelFileFormat == LabelFileFormat.CREATE_ML: + elif self.label_file_format == LabelFileFormat.CREATE_ML: self.set_format(FORMAT_PASCALVOC) else: raise ValueError('Unknown label file format.') self.set_dirty() def no_shapes(self): - return not self.itemsToShapes + return not self.items_to_shapes def toggle_advanced_mode(self, value=True): self._beginner = not value self.canvas.set_editing(True) self.populate_mode_actions() - self.editButton.setVisible(not value) + self.edit_button.setVisible(not value) if value: self.actions.createMode.setEnabled(True) self.actions.editMode.setEnabled(False) - self.dock.setFeatures(self.dock.features() | self.dockFeatures) + self.dock.setFeatures(self.dock.features() | self.dock_features) else: - self.dock.setFeatures(self.dock.features() ^ self.dockFeatures) + self.dock.setFeatures(self.dock.features() ^ self.dock_features) def populate_mode_actions(self): if self.beginner(): @@ -605,28 +605,28 @@ def status(self, message, delay=5000): self.statusBar().showMessage(message, delay) def reset_state(self): - self.itemsToShapes.clear() - self.shapesToItems.clear() - self.labelList.clear() - self.filePath = None - self.imageData = None - self.labelFile = None + self.items_to_shapes.clear() + self.shapes_to_items.clear() + self.label_list.clear() + self.file_path = None + self.image_data = None + self.label_file = None self.canvas.reset_state() - self.labelCoordinates.clear() - self.comboBox.cb.clear() + self.label_coordinates.clear() + self.combo_box.cb.clear() def current_item(self): - items = self.labelList.selectedItems() + items = self.label_list.selectedItems() if items: return items[0] return None def add_recent_file(self, file_path): - if file_path in self.recentFiles: - self.recentFiles.remove(file_path) - elif len(self.recentFiles) >= self.maxRecent: - self.recentFiles.pop() - self.recentFiles.insert(0, file_path) + if file_path in self.recent_files: + self.recent_files.remove(file_path) + elif len(self.recent_files) >= self.max_recent: + self.recent_files.pop() + self.recent_files.insert(0, file_path) def beginner(self): return self._beginner @@ -646,7 +646,7 @@ def get_available_screencast_viewer(self): # Callbacks # def show_tutorial_dialog(self): - subprocess.Popen(self.screencastViewer + [self.screencast]) + subprocess.Popen(self.screencast_viewer + [self.screencast]) def show_info_dialog(self): from libs.__init__ import __version__ @@ -683,13 +683,13 @@ def set_edit_mode(self): self.label_selection_changed() def update_file_menu(self): - curr_file_path = self.filePath + curr_file_path = self.file_path def exists(filename): return os.path.exists(filename) menu = self.menus.recentFiles menu.clear() - files = [f for f in self.recentFiles if f != + files = [f for f in self.recent_files if f != curr_file_path and exists(f)] for i, f in enumerate(files): icon = new_icon('labels') @@ -699,7 +699,7 @@ def exists(filename): menu.addAction(action) def pop_label_list_menu(self, point): - self.menus.labelList.exec_(self.labelList.mapToGlobal(point)) + self.menus.labelList.exec_(self.label_list.mapToGlobal(point)) def edit_label(self): if not self.canvas.editing(): @@ -707,7 +707,7 @@ def edit_label(self): item = self.current_item() if not item: return - text = self.labelDialog.pop_up(item.text()) + text = self.label_dialog.pop_up(item.text()) if text is not None: item.setText(text) item.setBackground(generate_color_by_text(text)) @@ -716,9 +716,9 @@ def edit_label(self): # Tzutalin 20160906 : Add file list and dock to move faster def file_item_double_clicked(self, item=None): - current_index = self.mImgList.index(ustr(item.text())) - if current_index < len(self.mImgList): - filename = self.mImgList[current_index] + current_index = self.m_img_list.index(ustr(item.text())) + if current_index < len(self.m_img_list): + filename = self.m_img_list[current_index] if filename: self.load_file(filename) @@ -731,12 +731,12 @@ def button_state(self, item=None): item = self.current_item() if not item: # If not selected Item, take the first one - item = self.labelList.item(self.labelList.count()-1) + item = self.label_list.item(self.label_list.count() - 1) - difficult = self.diffcButton.isChecked() + difficult = self.diffc_button.isChecked() try: - shape = self.itemsToShapes[item] + shape = self.items_to_shapes[item] except: pass # Checked and Update @@ -751,14 +751,14 @@ def button_state(self, item=None): # React to canvas signals. def shape_selection_changed(self, selected=False): - if self._noSelectionSlot: - self._noSelectionSlot = False + if self._no_selection_slot: + self._no_selection_slot = False else: - shape = self.canvas.selectedShape + shape = self.canvas.selected_shape if shape: - self.shapesToItems[shape].setSelected(True) + self.shapes_to_items[shape].setSelected(True) else: - self.labelList.clearSelection() + self.label_list.clearSelection() self.actions.delete.setEnabled(selected) self.actions.copy.setEnabled(selected) self.actions.edit.setEnabled(selected) @@ -766,14 +766,14 @@ def shape_selection_changed(self, selected=False): self.actions.shapeFillColor.setEnabled(selected) def add_label(self, shape): - shape.paintLabel = self.displayLabelOption.isChecked() + shape.paintLabel = self.display_label_option.isChecked() item = HashableQListWidgetItem(shape.label) item.setFlags(item.flags() | Qt.ItemIsUserCheckable) item.setCheckState(Qt.Checked) item.setBackground(generate_color_by_text(shape.label)) - self.itemsToShapes[item] = shape - self.shapesToItems[shape] = item - self.labelList.addItem(item) + self.items_to_shapes[item] = shape + self.shapes_to_items[shape] = item + self.label_list.addItem(item) for action in self.actions.onShapesPresent: action.setEnabled(True) self.update_combo_box() @@ -782,10 +782,10 @@ def remove_label(self, shape): if shape is None: # print('rm empty label') return - item = self.shapesToItems[shape] - self.labelList.takeItem(self.labelList.row(item)) - del self.shapesToItems[shape] - del self.itemsToShapes[item] + item = self.shapes_to_items[shape] + self.label_list.takeItem(self.label_list.row(item)) + del self.shapes_to_items[shape] + del self.items_to_shapes[item] self.update_combo_box() def load_labels(self, shapes): @@ -820,20 +820,20 @@ def load_labels(self, shapes): def update_combo_box(self): # Get the unique labels and add them to the Combobox. - items_text_list = [str(self.labelList.item(i).text()) for i in range(self.labelList.count())] + items_text_list = [str(self.label_list.item(i).text()) for i in range(self.label_list.count())] unique_text_list = list(set(items_text_list)) # Add a null row for showing all the labels unique_text_list.append("") unique_text_list.sort() - self.comboBox.update_items(unique_text_list) + self.combo_box.update_items(unique_text_list) def save_labels(self, annotation_file_path): annotation_file_path = ustr(annotation_file_path) - if self.labelFile is None: - self.labelFile = LabelFile() - self.labelFile.verified = self.canvas.verified + if self.label_file is None: + self.label_file = LabelFile() + self.label_file.verified = self.canvas.verified def format_shape(s): return dict(label=s.label, @@ -846,25 +846,25 @@ def format_shape(s): shapes = [format_shape(shape) for shape in self.canvas.shapes] # Can add different annotation formats here try: - if self.labelFileFormat == LabelFileFormat.PASCAL_VOC: + if self.label_file_format == LabelFileFormat.PASCAL_VOC: if annotation_file_path[-4:].lower() != ".xml": annotation_file_path += XML_EXT - self.labelFile.save_pascal_voc_format(annotation_file_path, shapes, self.filePath, self.imageData, - self.lineColor.getRgb(), self.fillColor.getRgb()) - elif self.labelFileFormat == LabelFileFormat.YOLO: + self.label_file.save_pascal_voc_format(annotation_file_path, shapes, self.file_path, self.image_data, + self.line_color.getRgb(), self.fill_color.getRgb()) + elif self.label_file_format == LabelFileFormat.YOLO: if annotation_file_path[-4:].lower() != ".txt": annotation_file_path += TXT_EXT - self.labelFile.save_yolo_format(annotation_file_path, shapes, self.filePath, self.imageData, self.labelHist, - self.lineColor.getRgb(), self.fillColor.getRgb()) - elif self.labelFileFormat == LabelFileFormat.CREATE_ML: + self.label_file.save_yolo_format(annotation_file_path, shapes, self.file_path, self.image_data, self.label_hist, + self.line_color.getRgb(), self.fill_color.getRgb()) + elif self.label_file_format == LabelFileFormat.CREATE_ML: if annotation_file_path[-5:].lower() != ".json": annotation_file_path += JSON_EXT - self.labelFile.save_create_ml_format(annotation_file_path, shapes, self.filePath, self.imageData, - self.labelHist, self.lineColor.getRgb(), self.fillColor.getRgb()) + self.label_file.save_create_ml_format(annotation_file_path, shapes, self.file_path, self.image_data, + self.label_hist, self.line_color.getRgb(), self.fill_color.getRgb()) else: - self.labelFile.save(annotation_file_path, shapes, self.filePath, self.imageData, - self.lineColor.getRgb(), self.fillColor.getRgb()) - print('Image:{0} -> Annotation:{1}'.format(self.filePath, annotation_file_path)) + self.label_file.save(annotation_file_path, shapes, self.file_path, self.image_data, + self.line_color.getRgb(), self.fill_color.getRgb()) + print('Image:{0} -> Annotation:{1}'.format(self.file_path, annotation_file_path)) return True except LabelFileError as e: self.error_message(u'Error saving label data', u'%s' % e) @@ -876,26 +876,26 @@ def copy_selected_shape(self): self.shape_selection_changed(True) def combo_selection_changed(self, index): - text = self.comboBox.cb.itemText(index) - for i in range(self.labelList.count()): + text = self.combo_box.cb.itemText(index) + for i in range(self.label_list.count()): if text == "": - self.labelList.item(i).setCheckState(2) - elif text != self.labelList.item(i).text(): - self.labelList.item(i).setCheckState(0) + self.label_list.item(i).setCheckState(2) + elif text != self.label_list.item(i).text(): + self.label_list.item(i).setCheckState(0) else: - self.labelList.item(i).setCheckState(2) + self.label_list.item(i).setCheckState(2) def label_selection_changed(self): item = self.current_item() if item and self.canvas.editing(): - self._noSelectionSlot = True - self.canvas.select_shape(self.itemsToShapes[item]) - shape = self.itemsToShapes[item] + self._no_selection_slot = True + self.canvas.select_shape(self.items_to_shapes[item]) + shape = self.items_to_shapes[item] # Add Chris - self.diffcButton.setChecked(shape.difficult) + self.diffc_button.setChecked(shape.difficult) def label_item_changed(self, item): - shape = self.itemsToShapes[item] + shape = self.items_to_shapes[item] label = item.text() if label != shape.label: shape.label = item.text() @@ -910,24 +910,24 @@ def new_shape(self): position MUST be in global coordinates. """ - if not self.useDefaultLabelCheckbox.isChecked() or not self.defaultLabelTextLine.text(): - if len(self.labelHist) > 0: - self.labelDialog = LabelDialog( - parent=self, list_item=self.labelHist) + if not self.use_default_label_checkbox.isChecked() or not self.default_label_text_line.text(): + if len(self.label_hist) > 0: + self.label_dialog = LabelDialog( + parent=self, list_item=self.label_hist) # Sync single class mode from PR#106 - if self.singleClassMode.isChecked() and self.lastLabel: + if self.single_class_mode.isChecked() and self.lastLabel: text = self.lastLabel else: - text = self.labelDialog.pop_up(text=self.prevLabelText) + text = self.label_dialog.pop_up(text=self.prev_label_text) self.lastLabel = text else: - text = self.defaultLabelTextLine.text() + text = self.default_label_text_line.text() # Add Chris - self.diffcButton.setChecked(False) + self.diffc_button.setChecked(False) if text is not None: - self.prevLabelText = text + self.prev_label_text = text generate_color = generate_color_by_text(text) shape = self.canvas.set_last_label(text, generate_color, generate_color) self.add_label(shape) @@ -938,31 +938,31 @@ def new_shape(self): self.actions.editMode.setEnabled(True) self.set_dirty() - if text not in self.labelHist: - self.labelHist.append(text) + if text not in self.label_hist: + self.label_hist.append(text) else: # self.canvas.undoLastLine() self.canvas.reset_all_lines() def scroll_request(self, delta, orientation): units = - delta / (8 * 15) - bar = self.scrollBars[orientation] + bar = self.scroll_bars[orientation] bar.setValue(bar.value() + bar.singleStep() * units) def set_zoom(self, value): self.actions.fitWidth.setChecked(False) self.actions.fitWindow.setChecked(False) - self.zoomMode = self.MANUAL_ZOOM - self.zoomWidget.setValue(value) + self.zoom_mode = self.MANUAL_ZOOM + self.zoom_widget.setValue(value) def add_zoom(self, increment=10): - self.set_zoom(self.zoomWidget.value() + increment) + self.set_zoom(self.zoom_widget.value() + increment) def zoom_request(self, delta): # get the current scrollbar positions # calculate the percentages ~ coordinates - h_bar = self.scrollBars[Qt.Horizontal] - v_bar = self.scrollBars[Qt.Vertical] + h_bar = self.scroll_bars[Qt.Horizontal] + v_bar = self.scroll_bars[Qt.Vertical] # get the current maximum, to know the difference after zooming h_bar_max = h_bar.maximum() @@ -980,8 +980,8 @@ def zoom_request(self, delta): cursor_x = relative_pos.x() cursor_y = relative_pos.y() - w = self.scrollArea.width() - h = self.scrollArea.height() + w = self.scroll_area.width() + h = self.scroll_area.height() # the scaling from 0 to 1 has some padding # you don't have to hit the very leftmost pixel for a maximum-left movement @@ -1013,17 +1013,17 @@ def zoom_request(self, delta): def set_fit_window(self, value=True): if value: self.actions.fitWidth.setChecked(False) - self.zoomMode = self.FIT_WINDOW if value else self.MANUAL_ZOOM + self.zoom_mode = self.FIT_WINDOW if value else self.MANUAL_ZOOM self.adjust_scale() def set_fit_width(self, value=True): if value: self.actions.fitWindow.setChecked(False) - self.zoomMode = self.FIT_WIDTH if value else self.MANUAL_ZOOM + self.zoom_mode = self.FIT_WIDTH if value else self.MANUAL_ZOOM self.adjust_scale() def toggle_polygons(self, value): - for item, shape in self.itemsToShapes.items(): + for item, shape in self.items_to_shapes.items(): item.setCheckState(Qt.Checked if value else Qt.Unchecked) def load_file(self, file_path=None): @@ -1041,19 +1041,19 @@ def load_file(self, file_path=None): unicode_file_path = os.path.abspath(unicode_file_path) # Tzutalin 20160906 : Add file list and dock to move faster # Highlight the file item - if unicode_file_path and self.fileListWidget.count() > 0: - if unicode_file_path in self.mImgList: - index = self.mImgList.index(unicode_file_path) - file_widget_item = self.fileListWidget.item(index) + if unicode_file_path and self.file_list_widget.count() > 0: + if unicode_file_path in self.m_img_list: + index = self.m_img_list.index(unicode_file_path) + file_widget_item = self.file_list_widget.item(index) file_widget_item.setSelected(True) else: - self.fileListWidget.clear() - self.mImgList.clear() + self.file_list_widget.clear() + self.m_img_list.clear() if unicode_file_path and os.path.exists(unicode_file_path): if LabelFile.is_label_file(unicode_file_path): try: - self.labelFile = LabelFile(unicode_file_path) + self.label_file = LabelFile(unicode_file_path) except LabelFileError as e: self.error_message(u'Error opening file', (u"

%s

" @@ -1061,21 +1061,21 @@ def load_file(self, file_path=None): % (e, unicode_file_path)) self.status("Error reading %s" % unicode_file_path) return False - self.imageData = self.labelFile.image_data - self.lineColor = QColor(*self.labelFile.lineColor) - self.fillColor = QColor(*self.labelFile.fillColor) - self.canvas.verified = self.labelFile.verified + self.image_data = self.label_file.image_data + self.line_color = QColor(*self.label_file.lineColor) + self.fill_color = QColor(*self.label_file.fillColor) + self.canvas.verified = self.label_file.verified else: # Load image: # read data first and store for saving into label file. - self.imageData = read(unicode_file_path, None) - self.labelFile = None + self.image_data = read(unicode_file_path, None) + self.label_file = None self.canvas.verified = False - if isinstance(self.imageData, QImage): - image = self.imageData + if isinstance(self.image_data, QImage): + image = self.image_data else: - image = QImage.fromData(self.imageData) + image = QImage.fromData(self.image_data) if image.isNull(): self.error_message(u'Error opening file', u"

Make sure %s is a valid image file." % unicode_file_path) @@ -1083,36 +1083,36 @@ def load_file(self, file_path=None): return False self.status("Loaded %s" % os.path.basename(unicode_file_path)) self.image = image - self.filePath = unicode_file_path + self.file_path = unicode_file_path self.canvas.load_pixmap(QPixmap.fromImage(image)) - if self.labelFile: - self.load_labels(self.labelFile.shapes) + if self.label_file: + self.load_labels(self.label_file.shapes) self.set_clean() self.canvas.setEnabled(True) self.adjust_scale(initial=True) self.paint_canvas() - self.add_recent_file(self.filePath) + self.add_recent_file(self.file_path) self.toggle_actions(True) self.show_bounding_box_from_annotation_file(file_path) self.setWindowTitle(__appname__ + ' ' + file_path) # Default : select last item if there is at least one item - if self.labelList.count(): - self.labelList.setCurrentItem(self.labelList.item(self.labelList.count()-1)) - self.labelList.item(self.labelList.count()-1).setSelected(True) + if self.label_list.count(): + self.label_list.setCurrentItem(self.label_list.item(self.label_list.count() - 1)) + self.label_list.item(self.label_list.count() - 1).setSelected(True) self.canvas.setFocus(True) return True return False def show_bounding_box_from_annotation_file(self, file_path): - if self.defaultSaveDir is not None: + if self.default_save_dir is not None: basename = os.path.basename(os.path.splitext(file_path)[0]) file_dir = file_path.split(basename)[0].split(os.path.sep)[-2:-1][0] - xml_path = os.path.join(self.defaultSaveDir, basename + XML_EXT) - txt_path = os.path.join(self.defaultSaveDir, basename + TXT_EXT) - json_path = os.path.join(self.defaultSaveDir, file_dir + JSON_EXT) + xml_path = os.path.join(self.default_save_dir, basename + XML_EXT) + txt_path = os.path.join(self.default_save_dir, basename + TXT_EXT) + json_path = os.path.join(self.default_save_dir, file_dir + JSON_EXT) """Annotation file priority: PascalXML > YOLO @@ -1134,20 +1134,20 @@ def show_bounding_box_from_annotation_file(self, file_path): def resizeEvent(self, event): if self.canvas and not self.image.isNull()\ - and self.zoomMode != self.MANUAL_ZOOM: + and self.zoom_mode != self.MANUAL_ZOOM: self.adjust_scale() super(MainWindow, self).resizeEvent(event) def paint_canvas(self): assert not self.image.isNull(), "cannot paint null image" - self.canvas.scale = 0.01 * self.zoomWidget.value() - self.canvas.labelFontSize = int(0.02 * max(self.image.width(), self.image.height())) + self.canvas.scale = 0.01 * self.zoom_widget.value() + self.canvas.label_font_size = int(0.02 * max(self.image.width(), self.image.height())) self.canvas.adjustSize() self.canvas.update() def adjust_scale(self, initial=False): - value = self.scalers[self.FIT_WINDOW if initial else self.zoomMode]() - self.zoomWidget.setValue(int(100 * value)) + value = self.scalers[self.FIT_WINDOW if initial else self.zoom_mode]() + self.zoom_widget.setValue(int(100 * value)) def scale_fit_window(self): """Figure out the size of the pixmap in order to fit the main widget.""" @@ -1171,33 +1171,33 @@ def closeEvent(self, event): event.ignore() settings = self.settings # If it loads images from dir, don't load it at the beginning - if self.dirname is None: - settings[SETTING_FILENAME] = self.filePath if self.filePath else '' + if self.dir_name is None: + settings[SETTING_FILENAME] = self.file_path if self.file_path else '' else: settings[SETTING_FILENAME] = '' settings[SETTING_WIN_SIZE] = self.size() settings[SETTING_WIN_POSE] = self.pos() settings[SETTING_WIN_STATE] = self.saveState() - settings[SETTING_LINE_COLOR] = self.lineColor - settings[SETTING_FILL_COLOR] = self.fillColor - settings[SETTING_RECENT_FILES] = self.recentFiles + settings[SETTING_LINE_COLOR] = self.line_color + settings[SETTING_FILL_COLOR] = self.fill_color + settings[SETTING_RECENT_FILES] = self.recent_files settings[SETTING_ADVANCE_MODE] = not self._beginner - if self.defaultSaveDir and os.path.exists(self.defaultSaveDir): - settings[SETTING_SAVE_DIR] = ustr(self.defaultSaveDir) + if self.default_save_dir and os.path.exists(self.default_save_dir): + settings[SETTING_SAVE_DIR] = ustr(self.default_save_dir) else: settings[SETTING_SAVE_DIR] = '' - if self.lastOpenDir and os.path.exists(self.lastOpenDir): - settings[SETTING_LAST_OPEN_DIR] = self.lastOpenDir + if self.last_open_dir and os.path.exists(self.last_open_dir): + settings[SETTING_LAST_OPEN_DIR] = self.last_open_dir else: settings[SETTING_LAST_OPEN_DIR] = '' - settings[SETTING_AUTO_SAVE] = self.autoSaving.isChecked() - settings[SETTING_SINGLE_CLASS] = self.singleClassMode.isChecked() - settings[SETTING_PAINT_LABEL] = self.displayLabelOption.isChecked() - settings[SETTING_DRAW_SQUARE] = self.drawSquaresOption.isChecked() - settings[SETTING_LABEL_FILE_FORMAT] = self.labelFileFormat + settings[SETTING_AUTO_SAVE] = self.auto_saving.isChecked() + settings[SETTING_SINGLE_CLASS] = self.single_class_mode.isChecked() + settings[SETTING_PAINT_LABEL] = self.display_label_option.isChecked() + settings[SETTING_DRAW_SQUARE] = self.draw_squares_option.isChecked() + settings[SETTING_LABEL_FILE_FORMAT] = self.label_file_format settings.save() def load_recent(self, filename): @@ -1218,8 +1218,8 @@ def scan_all_images(self, folder_path): return images def change_save_dir_dialog(self, _value=False): - if self.defaultSaveDir is not None: - path = ustr(self.defaultSaveDir) + if self.default_save_dir is not None: + path = ustr(self.default_save_dir) else: path = '.' @@ -1228,21 +1228,21 @@ def change_save_dir_dialog(self, _value=False): | QFileDialog.DontResolveSymlinks)) if dir_path is not None and len(dir_path) > 1: - self.defaultSaveDir = dir_path + self.default_save_dir = dir_path self.statusBar().showMessage('%s . Annotation will be saved to %s' % - ('Change saved folder', self.defaultSaveDir)) + ('Change saved folder', self.default_save_dir)) self.statusBar().show() def open_annotation_dialog(self, _value=False): - if self.filePath is None: + if self.file_path is None: self.statusBar().showMessage('Please select image first') self.statusBar().show() return - path = os.path.dirname(ustr(self.filePath))\ - if self.filePath else '.' - if self.labelFileFormat == LabelFileFormat.PASCAL_VOC: + path = os.path.dirname(ustr(self.file_path))\ + if self.file_path else '.' + if self.label_file_format == LabelFileFormat.PASCAL_VOC: filters = "Open Annotation XML file (%s)" % ' '.join(['*.xml']) filename = ustr(QFileDialog.getOpenFileName(self, '%s - Choose a xml file' % __appname__, path, filters)) if filename: @@ -1255,55 +1255,55 @@ def open_dir_dialog(self, _value=False, dir_path=None, silent=False): return default_open_dir_path = dir_path if dir_path else '.' - if self.lastOpenDir and os.path.exists(self.lastOpenDir): - default_open_dir_path = self.lastOpenDir + if self.last_open_dir and os.path.exists(self.last_open_dir): + default_open_dir_path = self.last_open_dir else: - default_open_dir_path = os.path.dirname(self.filePath) if self.filePath else '.' + default_open_dir_path = os.path.dirname(self.file_path) if self.file_path else '.' if silent != True: target_dir_path = ustr(QFileDialog.getExistingDirectory(self, '%s - Open Directory' % __appname__, default_open_dir_path, QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks)) else: target_dir_path = ustr(default_open_dir_path) - self.lastOpenDir = target_dir_path + self.last_open_dir = target_dir_path self.import_dir_images(target_dir_path) def import_dir_images(self, dir_path): if not self.may_continue() or not dir_path: return - self.lastOpenDir = dir_path - self.dirname = dir_path - self.filePath = None - self.fileListWidget.clear() - self.mImgList = self.scan_all_images(dir_path) + self.last_open_dir = dir_path + self.dir_name = dir_path + self.file_path = None + self.file_list_widget.clear() + self.m_img_list = self.scan_all_images(dir_path) self.open_next_image() - for imgPath in self.mImgList: + for imgPath in self.m_img_list: item = QListWidgetItem(imgPath) - self.fileListWidget.addItem(item) + self.file_list_widget.addItem(item) def verify_image(self, _value=False): # Proceeding next image without dialog if having any label - if self.filePath is not None: + if self.file_path is not None: try: - self.labelFile.toggle_verify() + self.label_file.toggle_verify() except AttributeError: # If the labelling file does not exist yet, create if and # re-save it with the verified attribute. self.save_file() - if self.labelFile is not None: - self.labelFile.toggle_verify() + if self.label_file is not None: + self.label_file.toggle_verify() else: return - self.canvas.verified = self.labelFile.verified + self.canvas.verified = self.label_file.verified self.paint_canvas() self.save_file() def open_prev_image(self, _value=False): # Proceeding prev image without dialog if having any label - if self.autoSaving.isChecked(): - if self.defaultSaveDir is not None: + if self.auto_saving.isChecked(): + if self.default_save_dir is not None: if self.dirty is True: self.save_file() else: @@ -1313,22 +1313,22 @@ def open_prev_image(self, _value=False): if not self.may_continue(): return - if len(self.mImgList) <= 0: + if len(self.m_img_list) <= 0: return - if self.filePath is None: + if self.file_path is None: return - current_index = self.mImgList.index(self.filePath) + current_index = self.m_img_list.index(self.file_path) if current_index - 1 >= 0: - filename = self.mImgList[current_index - 1] + filename = self.m_img_list[current_index - 1] if filename: self.load_file(filename) def open_next_image(self, _value=False): # Proceeding prev image without dialog if having any label - if self.autoSaving.isChecked(): - if self.defaultSaveDir is not None: + if self.auto_saving.isChecked(): + if self.default_save_dir is not None: if self.dirty is True: self.save_file() else: @@ -1338,16 +1338,16 @@ def open_next_image(self, _value=False): if not self.may_continue(): return - if len(self.mImgList) <= 0: + if len(self.m_img_list) <= 0: return filename = None - if self.filePath is None: - filename = self.mImgList[0] + if self.file_path is None: + filename = self.m_img_list[0] else: - current_index = self.mImgList.index(self.filePath) - if current_index + 1 < len(self.mImgList): - filename = self.mImgList[current_index + 1] + current_index = self.m_img_list.index(self.file_path) + if current_index + 1 < len(self.m_img_list): + filename = self.m_img_list[current_index + 1] if filename: self.load_file(filename) @@ -1355,7 +1355,7 @@ def open_next_image(self, _value=False): def open_file(self, _value=False): if not self.may_continue(): return - path = os.path.dirname(ustr(self.filePath)) if self.filePath else '.' + path = os.path.dirname(ustr(self.file_path)) if self.file_path else '.' formats = ['*.%s' % fmt.data().decode("ascii").lower() for fmt in QImageReader.supportedImageFormats()] filters = "Image & Label files (%s)" % ' '.join(formats + ['*%s' % LabelFile.suffix]) filename = QFileDialog.getOpenFileName(self, '%s - Choose Image or Label file' % __appname__, path, filters) @@ -1365,18 +1365,18 @@ def open_file(self, _value=False): self.load_file(filename) def save_file(self, _value=False): - if self.defaultSaveDir is not None and len(ustr(self.defaultSaveDir)): - if self.filePath: - image_file_name = os.path.basename(self.filePath) + if self.default_save_dir is not None and len(ustr(self.default_save_dir)): + if self.file_path: + image_file_name = os.path.basename(self.file_path) saved_file_name = os.path.splitext(image_file_name)[0] - saved_path = os.path.join(ustr(self.defaultSaveDir), saved_file_name) + saved_path = os.path.join(ustr(self.default_save_dir), saved_file_name) self._save_file(saved_path) else: - image_file_dir = os.path.dirname(self.filePath) - image_file_name = os.path.basename(self.filePath) + image_file_dir = os.path.dirname(self.file_path) + image_file_name = os.path.basename(self.file_path) saved_file_name = os.path.splitext(image_file_name)[0] saved_path = os.path.join(image_file_dir, saved_file_name) - self._save_file(saved_path if self.labelFile + self._save_file(saved_path if self.label_file else self.save_file_dialog(remove_ext=False)) def save_file_as(self, _value=False): @@ -1390,7 +1390,7 @@ def save_file_dialog(self, remove_ext=True): dlg = QFileDialog(self, caption, open_dialog_path, filters) dlg.setDefaultSuffix(LabelFile.suffix[1:]) dlg.setAcceptMode(QFileDialog.AcceptSave) - filename_without_extension = os.path.splitext(self.filePath)[0] + filename_without_extension = os.path.splitext(self.file_path)[0] dlg.selectFile(filename_without_extension) dlg.setOption(QFileDialog.DontUseNativeDialog, False) if dlg.exec_(): @@ -1417,18 +1417,18 @@ def close_file(self, _value=False): self.actions.saveAs.setEnabled(False) def delete_image(self): - delete_path = self.filePath + delete_path = self.file_path if delete_path is not None: self.open_next_image() if os.path.exists(delete_path): os.remove(delete_path) - self.import_dir_images(self.lastOpenDir) + self.import_dir_images(self.last_open_dir) def reset_all(self): self.settings.reset() self.close() - proc = QProcess() - proc.startDetached(os.path.abspath(__file__)) + process = QProcess() + process.startDetached(os.path.abspath(__file__)) def may_continue(self): if not self.dirty: @@ -1453,13 +1453,13 @@ def error_message(self, title, message): '

%s

%s' % (title, message)) def current_path(self): - return os.path.dirname(self.filePath) if self.filePath else '.' + return os.path.dirname(self.file_path) if self.file_path else '.' def choose_color1(self): - color = self.colorDialog.getColor(self.lineColor, u'Choose line color', - default=DEFAULT_LINE_COLOR) + color = self.color_dialog.getColor(self.line_color, u'Choose line color', + default=DEFAULT_LINE_COLOR) if color: - self.lineColor = color + self.line_color = color Shape.line_color = color self.canvas.set_drawing_color(color) self.canvas.update() @@ -1473,24 +1473,24 @@ def delete_selected_shape(self): action.setEnabled(False) def choose_shape_line_color(self): - color = self.colorDialog.getColor(self.lineColor, u'Choose line color', - default=DEFAULT_LINE_COLOR) + color = self.color_dialog.getColor(self.line_color, u'Choose line color', + default=DEFAULT_LINE_COLOR) if color: - self.canvas.selectedShape.line_color = color + self.canvas.selected_shape.line_color = color self.canvas.update() self.set_dirty() def choose_shape_fill_color(self): - color = self.colorDialog.getColor(self.fillColor, u'Choose fill color', - default=DEFAULT_FILL_COLOR) + color = self.color_dialog.getColor(self.fill_color, u'Choose fill color', + default=DEFAULT_FILL_COLOR) if color: - self.canvas.selectedShape.fill_color = color + self.canvas.selected_shape.fill_color = color self.canvas.update() self.set_dirty() def copy_shape(self): self.canvas.end_move(copy=True) - self.add_label(self.canvas.selectedShape) + self.add_label(self.canvas.selected_shape) self.set_dirty() def move_shape(self): @@ -1502,13 +1502,13 @@ def load_predefined_classes(self, predef_classes_file): with codecs.open(predef_classes_file, 'r', 'utf8') as f: for line in f: line = line.strip() - if self.labelHist is None: - self.labelHist = [line] + if self.label_hist is None: + self.label_hist = [line] else: - self.labelHist.append(line) + self.label_hist.append(line) def load_pascal_xml_by_filename(self, xml_path): - if self.filePath is None: + if self.file_path is None: return if os.path.isfile(xml_path) is False: return @@ -1521,7 +1521,7 @@ def load_pascal_xml_by_filename(self, xml_path): self.canvas.verified = t_voc_parse_reader.verified def load_yolo_txt_by_filename(self, txt_path): - if self.filePath is None: + if self.file_path is None: return if os.path.isfile(txt_path) is False: return @@ -1534,7 +1534,7 @@ def load_yolo_txt_by_filename(self, txt_path): self.canvas.verified = t_yolo_parse_reader.verified def load_create_ml_json_by_filename(self, json_path, file_path): - if self.filePath is None: + if self.file_path is None: return if os.path.isfile(json_path) is False: return @@ -1547,18 +1547,18 @@ def load_create_ml_json_by_filename(self, json_path, file_path): self.canvas.verified = create_ml_parse_reader.verified def copy_previous_bounding_boxes(self): - current_index = self.mImgList.index(self.filePath) + current_index = self.m_img_list.index(self.file_path) if current_index - 1 >= 0: - prev_file_path = self.mImgList[current_index - 1] + prev_file_path = self.m_img_list[current_index - 1] self.show_bounding_box_from_annotation_file(prev_file_path) self.save_file() def toggle_paint_labels_option(self): for shape in self.canvas.shapes: - shape.paintLabel = self.displayLabelOption.isChecked() + shape.paintLabel = self.display_label_option.isChecked() def toggle_draw_square(self): - self.canvas.set_drawing_shape_to_square(self.drawSquaresOption.isChecked()) + self.canvas.set_drawing_shape_to_square(self.draw_squares_option.isChecked()) def inverted(color): return QColor(*[255 - v for v in color.getRgb()]) diff --git a/libs/canvas.py b/libs/canvas.py index 959c9e9dd..77b7867fc 100644 --- a/libs/canvas.py +++ b/libs/canvas.py @@ -39,21 +39,21 @@ def __init__(self, *args, **kwargs): self.mode = self.EDIT self.shapes = [] self.current = None - self.selectedShape = None # save the selected shape here - self.selectedShapeCopy = None - self.drawingLineColor = QColor(0, 0, 255) - self.drawingRectColor = QColor(0, 0, 255) - self.line = Shape(line_color=self.drawingLineColor) - self.prevPoint = QPointF() + self.selected_shape = None # save the selected shape here + self.selected_shape_copy = None + self.drawing_line_color = QColor(0, 0, 255) + self.drawing_rect_color = QColor(0, 0, 255) + self.line = Shape(line_color=self.drawing_line_color) + self.prev_point = QPointF() self.offsets = QPointF(), QPointF() self.scale = 1.0 - self.labelFontSize = 8 + self.label_font_size = 8 self.pixmap = QPixmap() self.visible = {} - self._hideBackround = False - self.hideBackround = False - self.hShape = None - self.hVertex = None + self._hide_background = False + self.hide_background = False + self.h_shape = None + self.h_vertex = None self._painter = QPainter() self._cursor = CURSOR_DEFAULT # Menus: @@ -62,14 +62,14 @@ def __init__(self, *args, **kwargs): self.setMouseTracking(True) self.setFocusPolicy(Qt.WheelFocus) self.verified = False - self.drawSquare = False + self.draw_square = False # initialisation for panning self.pan_initial_pos = QPoint() def set_drawing_color(self, qcolor): - self.drawingLineColor = qcolor - self.drawingRectColor = qcolor + self.drawing_line_color = qcolor + self.drawing_rect_color = qcolor def enterEvent(self, ev): self.override_cursor(self._cursor) @@ -94,16 +94,16 @@ def set_editing(self, value=True): if not value: # Create self.un_highlight() self.de_select_shape() - self.prevPoint = QPointF() + self.prev_point = QPointF() self.repaint() def un_highlight(self): - if self.hShape: - self.hShape.highlight_clear() - self.hVertex = self.hShape = None + if self.h_shape: + self.h_shape.highlight_clear() + self.h_vertex = self.h_shape = None def selected_vertex(self): - return self.hVertex is not None + return self.h_vertex is not None def mouseMoveEvent(self, ev): """Update line with last point and current coordinates.""" @@ -111,8 +111,8 @@ def mouseMoveEvent(self, ev): # Update coordinates in status bar if image is opened window = self.parent().window() - if window.filePath is not None: - self.parent().window().labelCoordinates.setText( + if window.file_path is not None: + self.parent().window().label_coordinates.setText( 'X: %d; Y: %d' % (pos.x(), pos.y())) # Polygon drawing. @@ -122,10 +122,10 @@ def mouseMoveEvent(self, ev): # Display annotation width and height while drawing current_width = abs(self.current[0].x() - pos.x()) current_height = abs(self.current[0].y() - pos.y()) - self.parent().window().labelCoordinates.setText( + self.parent().window().label_coordinates.setText( 'Width: %d, Height: %d / X: %d; Y: %d' % (current_width, current_height, pos.x(), pos.y())) - color = self.drawingLineColor + color = self.drawing_line_color if self.out_of_pixmap(pos): # Don't allow the user to draw outside the pixmap. # Clip the coordinates to 0 or max, @@ -142,7 +142,7 @@ def mouseMoveEvent(self, ev): self.override_cursor(CURSOR_POINT) self.current.highlight_vertex(0, Shape.NEAR_VERTEX) - if self.drawSquare: + if self.draw_square: init_pos = self.current[0] min_x = init_pos.x() min_y = init_pos.y() @@ -154,21 +154,21 @@ def mouseMoveEvent(self, ev): self.line[1] = pos self.line.line_color = color - self.prevPoint = QPointF() + self.prev_point = QPointF() self.current.highlight_clear() else: - self.prevPoint = pos + self.prev_point = pos self.repaint() return # Polygon copy moving. if Qt.RightButton & ev.buttons(): - if self.selectedShapeCopy and self.prevPoint: + if self.selected_shape_copy and self.prev_point: self.override_cursor(CURSOR_MOVE) - self.bounded_move_shape(self.selectedShapeCopy, pos) + self.bounded_move_shape(self.selected_shape_copy, pos) self.repaint() - elif self.selectedShape: - self.selectedShapeCopy = self.selectedShape.copy() + elif self.selected_shape: + self.selected_shape_copy = self.selected_shape.copy() self.repaint() return @@ -178,9 +178,9 @@ def mouseMoveEvent(self, ev): self.bounded_move_vertex(pos) self.shapeMoved.emit() self.repaint() - elif self.selectedShape and self.prevPoint: + elif self.selected_shape and self.prev_point: self.override_cursor(CURSOR_MOVE) - self.bounded_move_shape(self.selectedShape, pos) + self.bounded_move_shape(self.selected_shape, pos) self.shapeMoved.emit() self.repaint() else: @@ -203,8 +203,8 @@ def mouseMoveEvent(self, ev): index = shape.nearest_vertex(pos, self.epsilon) if index is not None: if self.selected_vertex(): - self.hShape.highlight_clear() - self.hVertex, self.hShape = index, shape + self.h_shape.highlight_clear() + self.h_vertex, self.h_shape = index, shape shape.highlight_vertex(index, shape.MOVE_VERTEX) self.override_cursor(CURSOR_POINT) self.setToolTip("Click & drag to move point") @@ -213,8 +213,8 @@ def mouseMoveEvent(self, ev): break elif shape.contains_point(pos): if self.selected_vertex(): - self.hShape.highlight_clear() - self.hVertex, self.hShape = None, shape + self.h_shape.highlight_clear() + self.h_vertex, self.h_shape = None, shape self.setToolTip( "Click & drag to move shape '%s'" % shape.label) self.setStatusTip(self.toolTip()) @@ -222,10 +222,10 @@ def mouseMoveEvent(self, ev): self.update() break else: # Nothing found, clear highlights, reset state. - if self.hShape: - self.hShape.highlight_clear() + if self.h_shape: + self.h_shape.highlight_clear() self.update() - self.hVertex, self.hShape = None, None + self.h_vertex, self.h_shape = None, None self.override_cursor(CURSOR_DEFAULT) def mousePressEvent(self, ev): @@ -236,7 +236,7 @@ def mousePressEvent(self, ev): self.handle_drawing(pos) else: selection = self.select_shape_point(pos) - self.prevPoint = pos + self.prev_point = pos if selection is None: # pan @@ -245,19 +245,19 @@ def mousePressEvent(self, ev): elif ev.button() == Qt.RightButton and self.editing(): self.select_shape_point(pos) - self.prevPoint = pos + self.prev_point = pos self.update() def mouseReleaseEvent(self, ev): if ev.button() == Qt.RightButton: - menu = self.menus[bool(self.selectedShapeCopy)] + menu = self.menus[bool(self.selected_shape_copy)] self.restore_cursor() if not menu.exec_(self.mapToGlobal(ev.pos()))\ - and self.selectedShapeCopy: + and self.selected_shape_copy: # Cancel the move by deleting the shadow copy. - self.selectedShapeCopy = None + self.selected_shape_copy = None self.repaint() - elif ev.button() == Qt.LeftButton and self.selectedShape: + elif ev.button() == Qt.LeftButton and self.selected_shape: if self.selected_vertex(): self.override_cursor(CURSOR_POINT) else: @@ -271,22 +271,22 @@ def mouseReleaseEvent(self, ev): QApplication.restoreOverrideCursor() def end_move(self, copy=False): - assert self.selectedShape and self.selectedShapeCopy - shape = self.selectedShapeCopy + assert self.selected_shape and self.selected_shape_copy + shape = self.selected_shape_copy # del shape.fill_color # del shape.line_color if copy: self.shapes.append(shape) - self.selectedShape.selected = False - self.selectedShape = shape + self.selected_shape.selected = False + self.selected_shape = shape self.repaint() else: - self.selectedShape.points = [p for p in shape.points] - self.selectedShapeCopy = None + self.selected_shape.points = [p for p in shape.points] + self.selected_shape_copy = None def hide_background_shapes(self, value): - self.hideBackround = value - if self.selectedShape: + self.hide_background = value + if self.selected_shape: # Only hide other shapes if there is a current selection. # Otherwise the user will not be able to select a shape. self.set_hiding(True) @@ -313,7 +313,7 @@ def handle_drawing(self, pos): self.update() def set_hiding(self, enable=True): - self._hideBackround = self.hideBackround if enable else False + self._hide_background = self.hide_background if enable else False def can_close_shape(self): return self.drawing() and self.current and len(self.current) > 2 @@ -328,7 +328,7 @@ def mouseDoubleClickEvent(self, ev): def select_shape(self, shape): self.de_select_shape() shape.selected = True - self.selectedShape = shape + self.selected_shape = shape self.set_hiding() self.selectionChanged.emit(True) self.update() @@ -337,15 +337,15 @@ def select_shape_point(self, point): """Select the first shape created which contains this point.""" self.de_select_shape() if self.selected_vertex(): # A vertex is marked for selection. - index, shape = self.hVertex, self.hShape + index, shape = self.h_vertex, self.h_shape shape.highlight_vertex(index, shape.MOVE_VERTEX) self.select_shape(shape) - return self.hVertex + return self.h_vertex for shape in reversed(self.shapes): if self.isVisible(shape) and shape.contains_point(point): self.select_shape(shape) self.calculate_offsets(shape, point) - return self.selectedShape + return self.selected_shape return None def calculate_offsets(self, shape, point): @@ -371,7 +371,7 @@ def snap_point_to_canvas(self, x, y): return x, y, False def bounded_move_vertex(self, pos): - index, shape = self.hVertex, self.hShape + index, shape = self.h_vertex, self.h_shape point = shape[index] if self.out_of_pixmap(pos): size = self.pixmap.size() @@ -379,7 +379,7 @@ def bounded_move_vertex(self, pos): clipped_y = min(max(0, pos.y()), size.height()) pos = QPointF(clipped_x, clipped_y) - if self.drawSquare: + if self.draw_square: opposite_point_index = (index + 2) % 4 opposite_point = shape[opposite_point_index] @@ -421,36 +421,36 @@ def bounded_move_shape(self, shape, pos): # a bit "shaky" when nearing the border and allows it to # go outside of the shape's area for some reason. XXX # self.calculateOffsets(self.selectedShape, pos) - dp = pos - self.prevPoint + dp = pos - self.prev_point if dp: shape.move_by(dp) - self.prevPoint = pos + self.prev_point = pos return True return False def de_select_shape(self): - if self.selectedShape: - self.selectedShape.selected = False - self.selectedShape = None + if self.selected_shape: + self.selected_shape.selected = False + self.selected_shape = None self.set_hiding(False) self.selectionChanged.emit(False) self.update() def delete_selected(self): - if self.selectedShape: - shape = self.selectedShape - self.shapes.remove(self.selectedShape) - self.selectedShape = None + if self.selected_shape: + shape = self.selected_shape + self.shapes.remove(self.selected_shape) + self.selected_shape = None self.update() return shape def copy_selected_shape(self): - if self.selectedShape: - shape = self.selectedShape.copy() + if self.selected_shape: + shape = self.selected_shape.copy() self.de_select_shape() self.shapes.append(shape) shape.selected = True - self.selectedShape = shape + self.selected_shape = shape self.bounded_shift_shape(shape) return shape @@ -460,7 +460,7 @@ def bounded_shift_shape(self, shape): point = shape[0] offset = QPointF(2.0, 2.0) self.calculate_offsets(shape, point) - self.prevPoint = point + self.prev_point = point if not self.bounded_move_shape(shape, point - offset): self.bounded_move_shape(shape, point + offset) @@ -479,16 +479,16 @@ def paintEvent(self, event): p.drawPixmap(0, 0, self.pixmap) Shape.scale = self.scale - Shape.label_font_size = self.labelFontSize + Shape.label_font_size = self.label_font_size for shape in self.shapes: - if (shape.selected or not self._hideBackround) and self.isVisible(shape): - shape.fill = shape.selected or shape == self.hShape + if (shape.selected or not self._hide_background) and self.isVisible(shape): + shape.fill = shape.selected or shape == self.h_shape shape.paint(p) if self.current: self.current.paint(p) self.line.paint(p) - if self.selectedShapeCopy: - self.selectedShapeCopy.paint(p) + if self.selected_shape_copy: + self.selected_shape_copy.paint(p) # Paint rect if self.current is not None and len(self.line) == 2: @@ -496,15 +496,15 @@ def paintEvent(self, event): right_bottom = self.line[1] rect_width = right_bottom.x() - left_top.x() rect_height = right_bottom.y() - left_top.y() - p.setPen(self.drawingRectColor) + p.setPen(self.drawing_rect_color) brush = QBrush(Qt.BDiagPattern) p.setBrush(brush) p.drawRect(left_top.x(), left_top.y(), rect_width, rect_height) - if self.drawing() and not self.prevPoint.isNull() and not self.out_of_pixmap(self.prevPoint): + if self.drawing() and not self.prev_point.isNull() and not self.out_of_pixmap(self.prev_point): p.setPen(QColor(0, 0, 0)) - p.drawLine(self.prevPoint.x(), 0, self.prevPoint.x(), self.pixmap.height()) - p.drawLine(0, self.prevPoint.y(), self.pixmap.width(), self.prevPoint.y()) + p.drawLine(self.prev_point.x(), 0, self.prev_point.x(), self.pixmap.height()) + p.drawLine(0, self.prev_point.y(), self.pixmap.width(), self.prev_point.y()) self.setAutoFillBackground(True) if self.verified: @@ -597,46 +597,46 @@ def keyPressEvent(self, ev): self.update() elif key == Qt.Key_Return and self.can_close_shape(): self.finalise() - elif key == Qt.Key_Left and self.selectedShape: + elif key == Qt.Key_Left and self.selected_shape: self.move_one_pixel('Left') - elif key == Qt.Key_Right and self.selectedShape: + elif key == Qt.Key_Right and self.selected_shape: self.move_one_pixel('Right') - elif key == Qt.Key_Up and self.selectedShape: + elif key == Qt.Key_Up and self.selected_shape: self.move_one_pixel('Up') - elif key == Qt.Key_Down and self.selectedShape: + elif key == Qt.Key_Down and self.selected_shape: self.move_one_pixel('Down') def move_one_pixel(self, direction): # print(self.selectedShape.points) if direction == 'Left' and not self.move_out_of_bound(QPointF(-1.0, 0)): # print("move Left one pixel") - self.selectedShape.points[0] += QPointF(-1.0, 0) - self.selectedShape.points[1] += QPointF(-1.0, 0) - self.selectedShape.points[2] += QPointF(-1.0, 0) - self.selectedShape.points[3] += QPointF(-1.0, 0) + self.selected_shape.points[0] += QPointF(-1.0, 0) + self.selected_shape.points[1] += QPointF(-1.0, 0) + self.selected_shape.points[2] += QPointF(-1.0, 0) + self.selected_shape.points[3] += QPointF(-1.0, 0) elif direction == 'Right' and not self.move_out_of_bound(QPointF(1.0, 0)): # print("move Right one pixel") - self.selectedShape.points[0] += QPointF(1.0, 0) - self.selectedShape.points[1] += QPointF(1.0, 0) - self.selectedShape.points[2] += QPointF(1.0, 0) - self.selectedShape.points[3] += QPointF(1.0, 0) + self.selected_shape.points[0] += QPointF(1.0, 0) + self.selected_shape.points[1] += QPointF(1.0, 0) + self.selected_shape.points[2] += QPointF(1.0, 0) + self.selected_shape.points[3] += QPointF(1.0, 0) elif direction == 'Up' and not self.move_out_of_bound(QPointF(0, -1.0)): # print("move Up one pixel") - self.selectedShape.points[0] += QPointF(0, -1.0) - self.selectedShape.points[1] += QPointF(0, -1.0) - self.selectedShape.points[2] += QPointF(0, -1.0) - self.selectedShape.points[3] += QPointF(0, -1.0) + self.selected_shape.points[0] += QPointF(0, -1.0) + self.selected_shape.points[1] += QPointF(0, -1.0) + self.selected_shape.points[2] += QPointF(0, -1.0) + self.selected_shape.points[3] += QPointF(0, -1.0) elif direction == 'Down' and not self.move_out_of_bound(QPointF(0, 1.0)): # print("move Down one pixel") - self.selectedShape.points[0] += QPointF(0, 1.0) - self.selectedShape.points[1] += QPointF(0, 1.0) - self.selectedShape.points[2] += QPointF(0, 1.0) - self.selectedShape.points[3] += QPointF(0, 1.0) + self.selected_shape.points[0] += QPointF(0, 1.0) + self.selected_shape.points[1] += QPointF(0, 1.0) + self.selected_shape.points[2] += QPointF(0, 1.0) + self.selected_shape.points[3] += QPointF(0, 1.0) self.shapeMoved.emit() self.repaint() def move_out_of_bound(self, step): - points = [p1+p2 for p1, p2 in zip(self.selectedShape.points, [step]*4)] + points = [p1 + p2 for p1, p2 in zip(self.selected_shape.points, [step] * 4)] return True in map(self.out_of_pixmap, points) def set_last_label(self, text, line_color=None, fill_color=None): @@ -703,4 +703,4 @@ def reset_state(self): self.update() def set_drawing_shape_to_square(self, status): - self.drawSquare = status + self.draw_square = status diff --git a/libs/labelDialog.py b/libs/labelDialog.py index 865a7f307..1ee3a1991 100644 --- a/libs/labelDialog.py +++ b/libs/labelDialog.py @@ -29,7 +29,7 @@ def __init__(self, text="Enter object label", parent=None, list_item=None): layout = QVBoxLayout() layout.addWidget(self.edit) - self.buttonBox = bb = BB(BB.Ok | BB.Cancel, Qt.Horizontal, self) + self.button_box = bb = BB(BB.Ok | BB.Cancel, Qt.Horizontal, self) bb.button(BB.Ok).setIcon(new_icon('done')) bb.button(BB.Cancel).setIcon(new_icon('undo')) bb.accepted.connect(self.validate) @@ -37,12 +37,12 @@ def __init__(self, text="Enter object label", parent=None, list_item=None): layout.addWidget(bb) if list_item is not None and len(list_item) > 0: - self.listWidget = QListWidget(self) + self.list_widget = QListWidget(self) for item in list_item: - self.listWidget.addItem(item) - self.listWidget.itemClicked.connect(self.list_item_click) - self.listWidget.itemDoubleClicked.connect(self.list_item_double_click) - layout.addWidget(self.listWidget) + self.list_widget.addItem(item) + self.list_widget.itemClicked.connect(self.list_item_click) + self.list_widget.itemDoubleClicked.connect(self.list_item_double_click) + layout.addWidget(self.list_widget) self.setLayout(layout) From 4812be5644c9043bc172fa54ce2b3b6d75eb3dc5 Mon Sep 17 00:00:00 2001 From: Cerno_b Date: Tue, 9 Mar 2021 08:05:38 +0100 Subject: [PATCH 08/13] Fix paint label issue --- labelImg.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/labelImg.py b/labelImg.py index 1fd419b0b..01a110048 100755 --- a/labelImg.py +++ b/labelImg.py @@ -766,7 +766,7 @@ def shape_selection_changed(self, selected=False): self.actions.shapeFillColor.setEnabled(selected) def add_label(self, shape): - shape.paintLabel = self.display_label_option.isChecked() + shape.paint_label = self.display_label_option.isChecked() item = HashableQListWidgetItem(shape.label) item.setFlags(item.flags() | Qt.ItemIsUserCheckable) item.setCheckState(Qt.Checked) @@ -1555,7 +1555,7 @@ def copy_previous_bounding_boxes(self): def toggle_paint_labels_option(self): for shape in self.canvas.shapes: - shape.paintLabel = self.display_label_option.isChecked() + shape.paint_label = self.display_label_option.isChecked() def toggle_draw_square(self): self.canvas.set_drawing_shape_to_square(self.draw_squares_option.isChecked()) From 9b7c696500231a0cc459302d80275a450a535686 Mon Sep 17 00:00:00 2001 From: Cerno_b Date: Tue, 9 Mar 2021 08:46:48 +0100 Subject: [PATCH 09/13] Fix more warnings --- labelImg.py | 136 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 81 insertions(+), 55 deletions(-) diff --git a/labelImg.py b/labelImg.py index 01a110048..706fae81f 100755 --- a/labelImg.py +++ b/labelImg.py @@ -2,15 +2,12 @@ # -*- coding: utf-8 -*- import argparse import codecs -import distutils.spawn import os.path import platform -import re import sys import subprocess from functools import partial -from collections import defaultdict try: from PyQt5.QtGui import * @@ -85,7 +82,9 @@ def __init__(self, default_filename=None, default_prefdef_class_file=None, defau # Load string bundle for i18n self.string_bundle = StringBundle.get_bundle() - get_str = lambda str_id: self.string_bundle.get_string(str_id) + + def get_str(str_id): + return self.string_bundle.get_string(str_id) # Save as Pascal voc xml self.default_save_dir = default_save_dir @@ -155,8 +154,6 @@ def __init__(self, default_filename=None, default_prefdef_class_file=None, defau self.label_list.itemChanged.connect(self.label_item_changed) list_layout.addWidget(self.label_list) - - self.dock = QDockWidget(get_str('boxLabelText'), self) self.dock.setObjectName(get_str('labels')) self.dock.setWidget(label_list_container) @@ -204,11 +201,11 @@ def __init__(self, default_filename=None, default_prefdef_class_file=None, defau # Actions action = partial(new_action, self) - quit = action(get_str('quit'), self.close, - 'Ctrl+Q', 'quit', get_str('quitApp')) + action_quit = action(get_str('quit'), self.close, + 'Ctrl+Q', 'quit', get_str('quitApp')) - open = action(get_str('openFile'), self.open_file, - 'Ctrl+O', 'open', get_str('openFileDetail')) + action_open = action(get_str('openFile'), self.open_file, + 'Ctrl+O', 'open', get_str('openFileDetail')) open_dir = action(get_str('openDir'), self.open_dir_dialog, 'Ctrl+u', 'open', get_str('openDir')) @@ -234,15 +231,15 @@ def __init__(self, default_filename=None, default_prefdef_class_file=None, defau save = action(get_str('save'), self.save_file, 'Ctrl+S', 'save', get_str('saveDetail'), enabled=False) - def get_format_meta(format): + def get_format_meta(label_format): """ returns a tuple containing (title, icon_name) of the selected format """ - if format == LabelFileFormat.PASCAL_VOC: + if label_format == LabelFileFormat.PASCAL_VOC: return '&PascalVOC', 'format_voc' - elif format == LabelFileFormat.YOLO: + elif label_format == LabelFileFormat.YOLO: return '&YOLO', 'format_yolo' - elif format == LabelFileFormat.CREATE_ML: + elif label_format == LabelFileFormat.CREATE_ML: return '&CreateML', 'format_createml' save_format = action(get_format_meta(self.label_file_format)[0], @@ -265,7 +262,7 @@ def get_format_meta(format): create_mode = action(get_str('crtBox'), self.set_create_mode, 'w', 'new', get_str('crtBoxDetail'), enabled=False) edit_mode = action('&Edit\nRectBox', self.set_edit_mode, - 'Ctrl+J', 'edit', u'Move and edit Boxs', enabled=False) + 'Ctrl+J', 'edit', u'Move and edit Boxes', enabled=False) create = action(get_str('crtBox'), self.create_shape, 'w', 'new', get_str('crtBoxDetail'), enabled=False) @@ -286,7 +283,7 @@ def get_format_meta(format): 'Ctrl+A', 'hide', get_str('showAllBoxDetail'), enabled=False) - help = action(get_str('tutorial'), self.show_tutorial_dialog, None, 'help', get_str('tutorialDetail')) + action_help = action(get_str('tutorial'), self.show_tutorial_dialog, None, 'help', get_str('tutorialDetail')) show_info = action(get_str('info'), self.show_info_dialog, None, 'help', get_str('info')) zoom = QWidgetAction(self) @@ -350,33 +347,57 @@ def get_format_meta(format): self.draw_squares_option.setChecked(settings.get(SETTING_DRAW_SQUARE, False)) self.draw_squares_option.triggered.connect(self.toggle_draw_square) - # Store actions for further handling. - self.actions = Struct(save=save, save_format=save_format, saveAs=save_as, open=open, close=close, resetAll=reset_all, deleteImg=delete_image, - lineColor=color1, create=create, delete=delete, edit=edit, copy=copy, - createMode=create_mode, editMode=edit_mode, advancedMode=advanced_mode, - shapeLineColor=shape_line_color, shapeFillColor=shape_fill_color, - zoom=zoom, zoomIn=zoom_in, zoomOut=zoom_out, zoomOrg=zoom_org, - fitWindow=fit_window, fitWidth=fit_width, - zoomActions=zoom_actions, - fileMenuActions=( - open, open_dir, save, save_as, close, reset_all, quit), - beginner=(), advanced=(), - editMenu=(edit, copy, delete, - None, color1, self.draw_squares_option), - beginnerContext=(create, edit, copy, delete), - advancedContext=(create_mode, edit_mode, edit, copy, - delete, shape_line_color, shape_fill_color), - onLoadActive=( - close, create, create_mode, edit_mode), - onShapesPresent=(save_as, hide_all, show_all)) - - self.menus = Struct( - file=self.menu(get_str('menu_file')), - edit=self.menu(get_str('menu_edit')), - view=self.menu(get_str('menu_view')), - help=self.menu(get_str('menu_help')), - recentFiles=QMenu(get_str('menu_openRecent')), - labelList=label_menu) + draw_squares_option = self.draw_squares_option + + class Actions: + def __init__(self): + self.save = save + self.save_format = save_format + self.saveAs = save_as + self.open = action_open + self.close = close + self.resetAll = reset_all + self.deleteImg = delete_image + self.lineColor = color1 + self.create = create + self.delete = delete + self.edit = edit + self.copy = copy + self.createMode = create_mode + self.editMode = edit_mode + self.advancedMode = advanced_mode + self.shapeLineColor = shape_line_color + self.shapeFillColor = shape_fill_color + self.zoom = zoom + self.zoomIn = zoom_in + self.zoomOut = zoom_out + self.zoomOrg = zoom_org + self.fitWindow = fit_window + self.fitWidth = fit_width + self.zoomActions = zoom_actions + self.fileMenuActions = (action_open, open_dir, save, save_as, close, reset_all, action_quit) + self.beginner = () + self.advanced = () + self.editMenu = (edit, copy, delete, None, color1, draw_squares_option) + self.beginnerContext = (create, edit, copy, delete) + self.advancedContext = (create_mode, edit_mode, edit, copy, delete, shape_line_color, shape_fill_color) + self.onLoadActive = (close, create, create_mode, edit_mode) + self.onShapesPresent = (save_as, hide_all, show_all) + + self.actions = Actions() + + menu = self.menu + + class Menus: + def __init__(self): + self.file = menu(get_str('menu_file')) + self.edit = menu(get_str('menu_edit')) + self.view = menu(get_str('menu_view')) + self.help = menu(get_str('menu_help')) + self.recentFiles = QMenu(get_str('menu_openRecent')) + self.labelList = label_menu + + self.menus = Menus() # Auto saving : Enable auto saving if pressing next self.auto_saving = QAction(get_str('autoSaveMode'), self) @@ -396,8 +417,8 @@ def get_format_meta(format): self.display_label_option.triggered.connect(self.toggle_paint_labels_option) add_actions(self.menus.file, - (open, open_dir, copy_prev_bounding, change_save_dir, open_annotation, self.menus.recentFiles, save, save_format, save_as, close, reset_all, delete_image, quit)) - add_actions(self.menus.help, (help, show_info)) + (action_open, open_dir, copy_prev_bounding, change_save_dir, open_annotation, self.menus.recentFiles, save, save_format, save_as, close, reset_all, delete_image, action_quit)) + add_actions(self.menus.help, (action_help, show_info)) add_actions(self.menus.view, ( self.auto_saving, self.single_class_mode, @@ -417,11 +438,11 @@ def get_format_meta(format): self.tools = self.toolbar('Tools') self.actions.beginner = ( - open, open_dir, change_save_dir, open_next_image, open_prev_image, verify, save, save_format, None, create, copy, delete, None, + action_open, open_dir, change_save_dir, open_next_image, open_prev_image, verify, save, save_format, None, create, copy, delete, None, zoom_in, zoom, zoom_out, fit_window, fit_width) self.actions.advanced = ( - open, open_dir, change_save_dir, open_next_image, open_prev_image, save, save_format, None, + action_open, open_dir, change_save_dir, open_next_image, open_prev_image, save, save_format, None, create_mode, edit_mode, None, hide_all, show_all) @@ -447,7 +468,7 @@ def get_format_meta(format): recent_file_qstring_list = settings.get(SETTING_RECENT_FILES) self.recent_files = [ustr(i) for i in recent_file_qstring_list] else: - self.recent_files = recent_file_qstring_list = settings.get(SETTING_RECENT_FILES) + self.recent_files = settings.get(SETTING_RECENT_FILES) size = settings.get(SETTING_WIN_SIZE, QSize(600, 500)) position = QPoint(0, 0) @@ -570,7 +591,7 @@ def populate_mode_actions(self): self.canvas.menus[0].clear() add_actions(self.canvas.menus[0], menu) self.menus.edit.clear() - actions = (self.actions.create,) if self.beginner()\ + actions = (self.actions.create,) if self.beginner() \ else (self.actions.createMode, self.actions.editMode) add_actions(self.menus.edit, actions + self.actions.editMenu) @@ -598,7 +619,8 @@ def toggle_actions(self, value=True): for action in self.actions.onLoadActive: action.setEnabled(value) - def queue_event(self, function): + @staticmethod + def queue_event(function): QTimer.singleShot(0, function) def status(self, message, delay=5000): @@ -634,7 +656,8 @@ def beginner(self): def advanced(self): return not self.beginner() - def get_available_screencast_viewer(self): + @staticmethod + def get_available_screencast_viewer(): os_name = platform.system() if os_name == 'Windows': @@ -723,7 +746,7 @@ def file_item_double_clicked(self, item=None): self.load_file(filename) # Add chris - def button_state(self, item=None): + def button_state(self): """ Function to handle difficult examples Update on each object """ if not self.canvas.editing(): @@ -1254,12 +1277,11 @@ def open_dir_dialog(self, _value=False, dir_path=None, silent=False): if not self.may_continue(): return - default_open_dir_path = dir_path if dir_path else '.' if self.last_open_dir and os.path.exists(self.last_open_dir): default_open_dir_path = self.last_open_dir else: default_open_dir_path = os.path.dirname(self.file_path) if self.file_path else '.' - if silent != True: + if not silent: target_dir_path = ustr(QFileDialog.getExistingDirectory(self, '%s - Open Directory' % __appname__, default_open_dir_path, QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks)) @@ -1560,6 +1582,7 @@ def toggle_paint_labels_option(self): def toggle_draw_square(self): self.canvas.set_drawing_shape_to_square(self.draw_squares_option.isChecked()) + def inverted(color): return QColor(*[255 - v for v in color.getRgb()]) @@ -1573,11 +1596,13 @@ def read(filename, default=None): return default -def get_main_app(argv=[]): +def get_main_app(argv=None): """ Standard boilerplate Qt application code. Do everything but app.exec_() -- so that we can test the application in one thread """ + if argv is None: + argv = [] app = QApplication(argv) app.setApplicationName(__appname__) app.setWindowIcon(new_icon("app")) @@ -1602,5 +1627,6 @@ def main(): app, _win = get_main_app(sys.argv) return app.exec_() + if __name__ == '__main__': sys.exit(main()) From 0bafad5a1762ca9d3b9c654571a04b42eb9d0cec Mon Sep 17 00:00:00 2001 From: Cerno_b Date: Wed, 10 Mar 2021 16:58:15 +0100 Subject: [PATCH 10/13] Further warning removal and cleanup --- labelImg.py | 153 +++++++++++++++++++++--------------------- libs/canvas.py | 22 +++--- libs/colorDialog.py | 2 +- libs/combobox.py | 5 +- libs/constants.py | 6 +- libs/create_ml_io.py | 3 +- libs/labelFile.py | 13 ++-- libs/pascal_voc_io.py | 23 ++++--- libs/settings.py | 1 - libs/stringBundle.py | 9 +-- libs/ustr.py | 1 + libs/utils.py | 23 +++---- libs/yolo_io.py | 35 +++++----- tools/label_to_csv.py | 2 +- 14 files changed, 149 insertions(+), 149 deletions(-) diff --git a/labelImg.py b/labelImg.py index 706fae81f..9892ac04a 100755 --- a/labelImg.py +++ b/labelImg.py @@ -8,6 +8,7 @@ import subprocess from functools import partial +from enum import Enum try: from PyQt5.QtGui import * @@ -49,15 +50,20 @@ __appname__ = 'labelImg' -class WindowMixin(object): +class MainWindow(QMainWindow): - def menu(self, title, actions=None): + class ScaleMode(Enum): + FIT_WINDOW = 0 + FIT_WIDTH = 1 + MANUAL_ZOOM = 2 + + def add_menu(self, title, actions=None): menu = self.menuBar().addMenu(title) if actions: add_actions(menu, actions) return menu - def toolbar(self, title, actions=None): + def add_toolbar(self, title, actions=None): toolbar = ToolBar(title) toolbar.setObjectName(u'%sToolBar' % title) # toolbar.setOrientation(Qt.Vertical) @@ -67,11 +73,7 @@ def toolbar(self, title, actions=None): self.addToolBar(Qt.LeftToolBarArea, toolbar) return toolbar - -class MainWindow(QMainWindow, WindowMixin): - FIT_WINDOW, FIT_WIDTH, MANUAL_ZOOM = list(range(3)) - - def __init__(self, default_filename=None, default_prefdef_class_file=None, default_save_dir=None): + def __init__(self, default_filename=None, default_pre_def_class_file=None, default_save_dir=None): super(MainWindow, self).__init__() self.setWindowTitle(__appname__) @@ -80,6 +82,9 @@ def __init__(self, default_filename=None, default_prefdef_class_file=None, defau self.settings.load() settings = self.settings + self.image_data = None + self.label_file = None + # Load string bundle for i18n self.string_bundle = StringBundle.get_bundle() @@ -105,7 +110,7 @@ def get_str(str_id): self.screencast = "https://youtu.be/p0nR2YsCY_U" # Load predefined classes to the list - self.load_predefined_classes(default_prefdef_class_file) + self.load_predefined_classes(default_pre_def_class_file) # Main widgets and related state. self.label_dialog = LabelDialog(parent=self, list_item=self.label_hist) @@ -127,16 +132,16 @@ def get_str(str_id): use_default_label_container = QWidget() use_default_label_container.setLayout(use_default_label_qhbox_layout) - # Create a widget for edit and diffc button - self.diffc_button = QCheckBox(get_str('useDifficult')) - self.diffc_button.setChecked(False) - self.diffc_button.stateChanged.connect(self.button_state) + # Create a widget for edit and difficult checkbox + self.difficult_checkbox = QCheckBox(get_str('useDifficult')) + self.difficult_checkbox.setChecked(False) + self.difficult_checkbox.stateChanged.connect(self.button_state) self.edit_button = QToolButton() self.edit_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) # Add some of widgets to list_layout list_layout.addWidget(self.edit_button) - list_layout.addWidget(self.diffc_button) + list_layout.addWidget(self.difficult_checkbox) list_layout.addWidget(use_default_label_container) # Create and add combobox for showing unique labels in group @@ -309,12 +314,12 @@ def get_format_meta(label_format): # Group zoom controls into a list for easier toggling. zoom_actions = (self.zoom_widget, zoom_in, zoom_out, zoom_org, fit_window, fit_width) - self.zoom_mode = self.MANUAL_ZOOM + self.zoom_mode = self.ScaleMode.MANUAL_ZOOM self.scalers = { - self.FIT_WINDOW: self.scale_fit_window, - self.FIT_WIDTH: self.scale_fit_width, + self.ScaleMode.FIT_WINDOW: self.scale_fit_window, + self.ScaleMode.FIT_WIDTH: self.scale_fit_width, # Set to one to scale to 100% when loading files. - self.MANUAL_ZOOM: lambda: 1, + self.ScaleMode.MANUAL_ZOOM: lambda: 1, } edit = action(get_str('editLabel'), self.edit_label, @@ -386,14 +391,14 @@ def __init__(self): self.actions = Actions() - menu = self.menu + add_menu = self.add_menu class Menus: def __init__(self): - self.file = menu(get_str('menu_file')) - self.edit = menu(get_str('menu_edit')) - self.view = menu(get_str('menu_view')) - self.help = menu(get_str('menu_help')) + self.file = add_menu(get_str('menu_file')) + self.edit = add_menu(get_str('menu_edit')) + self.view = add_menu(get_str('menu_view')) + self.help = add_menu(get_str('menu_help')) self.recentFiles = QMenu(get_str('menu_openRecent')) self.labelList = label_menu @@ -436,7 +441,7 @@ def __init__(self): action('&Copy here', self.copy_shape), action('&Move here', self.move_shape))) - self.tools = self.toolbar('Tools') + self.tools = self.add_toolbar('Tools') self.actions.beginner = ( action_open, open_dir, change_save_dir, open_next_image, open_prev_image, verify, save, save_format, None, create, copy, delete, None, zoom_in, zoom, zoom_out, fit_window, fit_width) @@ -495,12 +500,12 @@ def __init__(self): # Add chris Shape.difficult = self.difficult - def xbool(x): + def x_bool(x): if isinstance(x, QVariant): return x.toBool() return bool(x) - if xbool(settings.get(SETTING_ADVANCE_MODE, False)): + if x_bool(settings.get(SETTING_ADVANCE_MODE, False)): self.actions.advancedMode.setChecked(True) self.toggle_advanced_mode() @@ -524,7 +529,7 @@ def xbool(x): # Open Dir if default file if self.file_path and os.path.isdir(self.file_path): - self.open_dir_dialog(dir_path=self.file_path, silent=True) + self.open_dir_dialog(silent=True) def keyReleaseEvent(self, event): if event.key() == Qt.Key_Control: @@ -756,14 +761,10 @@ def button_state(self): if not item: # If not selected Item, take the first one item = self.label_list.item(self.label_list.count() - 1) - difficult = self.diffc_button.isChecked() + difficult = self.difficult_checkbox.isChecked() try: shape = self.items_to_shapes[item] - except: - pass - # Checked and Update - try: if difficult != shape.difficult: shape.difficult = difficult self.set_dirty() @@ -872,21 +873,18 @@ def format_shape(s): if self.label_file_format == LabelFileFormat.PASCAL_VOC: if annotation_file_path[-4:].lower() != ".xml": annotation_file_path += XML_EXT - self.label_file.save_pascal_voc_format(annotation_file_path, shapes, self.file_path, self.image_data, - self.line_color.getRgb(), self.fill_color.getRgb()) + self.label_file.save_pascal_voc_format(annotation_file_path, shapes, self.file_path, self.image_data) elif self.label_file_format == LabelFileFormat.YOLO: if annotation_file_path[-4:].lower() != ".txt": annotation_file_path += TXT_EXT - self.label_file.save_yolo_format(annotation_file_path, shapes, self.file_path, self.image_data, self.label_hist, - self.line_color.getRgb(), self.fill_color.getRgb()) + self.label_file.save_yolo_format(annotation_file_path, shapes, self.file_path, self.image_data, self.label_hist) elif self.label_file_format == LabelFileFormat.CREATE_ML: if annotation_file_path[-5:].lower() != ".json": annotation_file_path += JSON_EXT - self.label_file.save_create_ml_format(annotation_file_path, shapes, self.file_path, self.image_data, - self.label_hist, self.line_color.getRgb(), self.fill_color.getRgb()) - else: - self.label_file.save(annotation_file_path, shapes, self.file_path, self.image_data, - self.line_color.getRgb(), self.fill_color.getRgb()) + self.label_file.save_create_ml_format(annotation_file_path, shapes, self.file_path) + # else: + # self.label_file.save(annotation_file_path, shapes, self.file_path, self.image_data, + # self.line_color.getRgb(), self.fill_color.getRgb()) print('Image:{0} -> Annotation:{1}'.format(self.file_path, annotation_file_path)) return True except LabelFileError as e: @@ -902,11 +900,11 @@ def combo_selection_changed(self, index): text = self.combo_box.cb.itemText(index) for i in range(self.label_list.count()): if text == "": - self.label_list.item(i).setCheckState(2) + self.label_list.item(i).setCheckState(Qt.Checked) elif text != self.label_list.item(i).text(): - self.label_list.item(i).setCheckState(0) + self.label_list.item(i).setCheckState(Qt.Unchecked) else: - self.label_list.item(i).setCheckState(2) + self.label_list.item(i).setCheckState(Qt.Checked) def label_selection_changed(self): item = self.current_item() @@ -915,7 +913,7 @@ def label_selection_changed(self): self.canvas.select_shape(self.items_to_shapes[item]) shape = self.items_to_shapes[item] # Add Chris - self.diffc_button.setChecked(shape.difficult) + self.difficult_checkbox.setChecked(shape.difficult) def label_item_changed(self, item): shape = self.items_to_shapes[item] @@ -948,7 +946,7 @@ def new_shape(self): text = self.default_label_text_line.text() # Add Chris - self.diffc_button.setChecked(False) + self.difficult_checkbox.setChecked(False) if text is not None: self.prev_label_text = text generate_color = generate_color_by_text(text) @@ -975,7 +973,7 @@ def scroll_request(self, delta, orientation): def set_zoom(self, value): self.actions.fitWidth.setChecked(False) self.actions.fitWindow.setChecked(False) - self.zoom_mode = self.MANUAL_ZOOM + self.zoom_mode = self.ScaleMode.MANUAL_ZOOM self.zoom_widget.setValue(value) def add_zoom(self, increment=10): @@ -1030,19 +1028,19 @@ def zoom_request(self, delta): new_h_bar_value = h_bar.value() + move_x * d_h_bar_max new_v_bar_value = v_bar.value() + move_y * d_v_bar_max - h_bar.setValue(new_h_bar_value) - v_bar.setValue(new_v_bar_value) + h_bar.setValue(int(new_h_bar_value)) + v_bar.setValue(int(new_v_bar_value)) def set_fit_window(self, value=True): if value: self.actions.fitWidth.setChecked(False) - self.zoom_mode = self.FIT_WINDOW if value else self.MANUAL_ZOOM + self.zoom_mode = self.ScaleMode.FIT_WINDOW if value else self.ScaleMode.MANUAL_ZOOM self.adjust_scale() def set_fit_width(self, value=True): if value: self.actions.fitWindow.setChecked(False) - self.zoom_mode = self.FIT_WIDTH if value else self.MANUAL_ZOOM + self.zoom_mode = self.ScaleMode.FIT_WIDTH if value else self.ScaleMode.MANUAL_ZOOM self.adjust_scale() def toggle_polygons(self, value): @@ -1076,7 +1074,7 @@ def load_file(self, file_path=None): if unicode_file_path and os.path.exists(unicode_file_path): if LabelFile.is_label_file(unicode_file_path): try: - self.label_file = LabelFile(unicode_file_path) + self.label_file = LabelFile() except LabelFileError as e: self.error_message(u'Error opening file', (u"

%s

" @@ -1085,8 +1083,8 @@ def load_file(self, file_path=None): self.status("Error reading %s" % unicode_file_path) return False self.image_data = self.label_file.image_data - self.line_color = QColor(*self.label_file.lineColor) - self.fill_color = QColor(*self.label_file.fillColor) + self.line_color = QColor(*self.label_file.line_color) + self.fill_color = QColor(*self.label_file.fill_color) self.canvas.verified = self.label_file.verified else: # Load image: @@ -1125,7 +1123,7 @@ def load_file(self, file_path=None): self.label_list.setCurrentItem(self.label_list.item(self.label_list.count() - 1)) self.label_list.item(self.label_list.count() - 1).setSelected(True) - self.canvas.setFocus(True) + self.canvas.setFocus(Qt.TabFocusReason) return True return False @@ -1157,7 +1155,7 @@ def show_bounding_box_from_annotation_file(self, file_path): def resizeEvent(self, event): if self.canvas and not self.image.isNull()\ - and self.zoom_mode != self.MANUAL_ZOOM: + and self.zoom_mode != self.ScaleMode.MANUAL_ZOOM: self.adjust_scale() super(MainWindow, self).resizeEvent(event) @@ -1169,7 +1167,7 @@ def paint_canvas(self): self.canvas.update() def adjust_scale(self, initial=False): - value = self.scalers[self.FIT_WINDOW if initial else self.zoom_mode]() + value = self.scalers[self.ScaleMode.FIT_WINDOW if initial else self.zoom_mode]() self.zoom_widget.setValue(int(100 * value)) def scale_fit_window(self): @@ -1227,7 +1225,8 @@ def load_recent(self, filename): if self.may_continue(): self.load_file(filename) - def scan_all_images(self, folder_path): + @staticmethod + def scan_all_images(folder_path): extensions = ['.%s' % fmt.data().decode("ascii").lower() for fmt in QImageReader.supportedImageFormats()] images = [] @@ -1273,7 +1272,7 @@ def open_annotation_dialog(self, _value=False): filename = filename[0] self.load_pascal_xml_by_filename(filename) - def open_dir_dialog(self, _value=False, dir_path=None, silent=False): + def open_dir_dialog(self, _value=False, silent=False): if not self.may_continue(): return @@ -1478,8 +1477,8 @@ def current_path(self): return os.path.dirname(self.file_path) if self.file_path else '.' def choose_color1(self): - color = self.color_dialog.getColor(self.line_color, u'Choose line color', - default=DEFAULT_LINE_COLOR) + color = self.color_dialog.get_color(self.line_color, u'Choose line color', + default=DEFAULT_LINE_COLOR) if color: self.line_color = color Shape.line_color = color @@ -1495,16 +1494,16 @@ def delete_selected_shape(self): action.setEnabled(False) def choose_shape_line_color(self): - color = self.color_dialog.getColor(self.line_color, u'Choose line color', - default=DEFAULT_LINE_COLOR) + color = self.color_dialog.get_color(self.line_color, u'Choose line color', + default=DEFAULT_LINE_COLOR) if color: self.canvas.selected_shape.line_color = color self.canvas.update() self.set_dirty() def choose_shape_fill_color(self): - color = self.color_dialog.getColor(self.fill_color, u'Choose fill color', - default=DEFAULT_FILL_COLOR) + color = self.color_dialog.get_color(self.fill_color, u'Choose fill color', + default=DEFAULT_FILL_COLOR) if color: self.canvas.selected_shape.fill_color = color self.canvas.update() @@ -1519,9 +1518,9 @@ def move_shape(self): self.canvas.end_move(copy=False) self.set_dirty() - def load_predefined_classes(self, predef_classes_file): - if os.path.exists(predef_classes_file) is True: - with codecs.open(predef_classes_file, 'r', 'utf8') as f: + def load_predefined_classes(self, pre_def_classes_file): + if os.path.exists(pre_def_classes_file) is True: + with codecs.open(pre_def_classes_file, 'r', 'utf8') as f: for line in f: line = line.strip() if self.label_hist is None: @@ -1606,15 +1605,15 @@ def get_main_app(argv=None): app = QApplication(argv) app.setApplicationName(__appname__) app.setWindowIcon(new_icon("app")) - # Tzutalin 201705+: Accept extra agruments to change predefined class file - argparser = argparse.ArgumentParser() - argparser.add_argument("image_dir", nargs="?") - argparser.add_argument("predefined_classes_file", - default=os.path.join(os.path.dirname(__file__), "data", "predefined_classes.txt"), - nargs="?") - argparser.add_argument("save_dir", nargs="?") - args = argparser.parse_args(argv[1:]) - # Usage : labelImg.py image predefClassFile saveDir + # Tzutalin 201705+: Accept extra arguments to change predefined class file + arg_parser = argparse.ArgumentParser() + arg_parser.add_argument("image_dir", nargs="?") + arg_parser.add_argument("predefined_classes_file", + default=os.path.join(os.path.dirname(__file__), "data", "predefined_classes.txt"), + nargs="?") + arg_parser.add_argument("save_dir", nargs="?") + args = arg_parser.parse_args(argv[1:]) + # Usage : labelImg.py image_dir predefined_classes_file save_dir win = MainWindow(args.image_dir, args.predefined_classes_file, args.save_dir) diff --git a/libs/canvas.py b/libs/canvas.py index 77b7867fc..5f21e88c3 100644 --- a/libs/canvas.py +++ b/libs/canvas.py @@ -80,7 +80,7 @@ def leaveEvent(self, ev): def focusOutEvent(self, ev): self.restore_cursor() - def isVisible(self, shape): + def is_visible(self, shape): return self.visible.get(shape, True) def drawing(self): @@ -135,7 +135,7 @@ def mouseMoveEvent(self, ev): clipped_y = min(max(0, pos.y()), size.height()) pos = QPointF(clipped_x, clipped_y) elif len(self.current) > 1 and self.close_enough(pos, self.current[0]): - # Attract line to starting point and colorise to alert the + # Attract line to starting point and colorize to alert the # user: pos = self.current[0] color = self.current.line_color @@ -197,7 +197,7 @@ def mouseMoveEvent(self, ev): # - Highlight vertex # Update shape/vertex fill and tooltip value accordingly. self.setToolTip("Image") - for shape in reversed([s for s in self.shapes if self.isVisible(s)]): + for shape in reversed([s for s in self.shapes if self.is_visible(s)]): # Look for a nearby vertex to highlight. If that fails, # check if we happen to be inside a shape. index = shape.nearest_vertex(pos, self.epsilon) @@ -342,7 +342,7 @@ def select_shape_point(self, point): self.select_shape(shape) return self.h_vertex for shape in reversed(self.shapes): - if self.isVisible(shape) and shape.contains_point(point): + if self.is_visible(shape) and shape.contains_point(point): self.select_shape(shape) self.calculate_offsets(shape, point) return self.selected_shape @@ -395,8 +395,6 @@ def bounded_move_vertex(self, pos): left_index = (index + 1) % 4 right_index = (index + 3) % 4 - left_shift = None - right_shift = None if index % 2 == 0: right_shift = QPointF(shift_pos.x(), 0) left_shift = QPointF(0, shift_pos.y()) @@ -481,7 +479,7 @@ def paintEvent(self, event): Shape.scale = self.scale Shape.label_font_size = self.label_font_size for shape in self.shapes: - if (shape.selected or not self._hide_background) and self.isVisible(shape): + if (shape.selected or not self._hide_background) and self.is_visible(shape): shape.fill = shape.selected or shape == self.h_shape shape.paint(p) if self.current: @@ -503,8 +501,8 @@ def paintEvent(self, event): if self.drawing() and not self.prev_point.isNull() and not self.out_of_pixmap(self.prev_point): p.setPen(QColor(0, 0, 0)) - p.drawLine(self.prev_point.x(), 0, self.prev_point.x(), self.pixmap.height()) - p.drawLine(0, self.prev_point.y(), self.pixmap.width(), self.prev_point.y()) + p.drawLine(int(self.prev_point.x()), 0, int(self.prev_point.x()), int(self.pixmap.height())) + p.drawLine(0, int(self.prev_point.y()), int(self.pixmap.width()), int(self.prev_point.y())) self.setAutoFillBackground(True) if self.verified: @@ -681,7 +679,8 @@ def set_shape_visible(self, shape, value): self.visible[shape] = value self.repaint() - def current_cursor(self): + @staticmethod + def current_cursor(): cursor = QApplication.overrideCursor() if cursor is not None: cursor = cursor.shape() @@ -694,7 +693,8 @@ def override_cursor(self, cursor): else: QApplication.changeOverrideCursor(cursor) - def restore_cursor(self): + @staticmethod + def restore_cursor(): QApplication.restoreOverrideCursor() def reset_state(self): diff --git a/libs/colorDialog.py b/libs/colorDialog.py index 5cd28025c..06baa837d 100644 --- a/libs/colorDialog.py +++ b/libs/colorDialog.py @@ -24,7 +24,7 @@ def __init__(self, parent=None): self.bb.addButton(BB.RestoreDefaults) self.bb.clicked.connect(self.check_restore) - def getColor(self, value=None, title=None, default=None): + def get_color(self, value=None, title=None, default=None): self.default = default if title: self.setWindowTitle(title) diff --git a/libs/combobox.py b/libs/combobox.py index 8743b648e..fbf482b96 100644 --- a/libs/combobox.py +++ b/libs/combobox.py @@ -13,9 +13,12 @@ class ComboBox(QWidget): - def __init__(self, parent=None, items=[]): + def __init__(self, parent=None, items=None): super(ComboBox, self).__init__(parent) + if items is None: + items = [] + layout = QHBoxLayout() self.cb = QComboBox() self.items = items diff --git a/libs/constants.py b/libs/constants.py index 1efda037c..8015ffb39 100644 --- a/libs/constants.py +++ b/libs/constants.py @@ -13,8 +13,8 @@ SETTING_AUTO_SAVE = 'autosave' SETTING_SINGLE_CLASS = 'singleclass' FORMAT_PASCALVOC='PascalVOC' -FORMAT_YOLO='YOLO' -FORMAT_CREATEML='CreateML' +FORMAT_YOLO = 'YOLO' +FORMAT_CREATEML = 'CreateML' SETTING_DRAW_SQUARE = 'draw/square' -SETTING_LABEL_FILE_FORMAT= 'labelFileFormat' +SETTING_LABEL_FILE_FORMAT = 'labelFileFormat' DEFAULT_ENCODING = 'utf-8' diff --git a/libs/create_ml_io.py b/libs/create_ml_io.py index 922ae1f63..c8166c4a8 100644 --- a/libs/create_ml_io.py +++ b/libs/create_ml_io.py @@ -69,7 +69,8 @@ def write(self): Path(self.output_file).write_text(json.dumps(output_dict), ENCODE_METHOD) - def calculate_coordinates(self, x1, x2, y1, y2): + @staticmethod + def calculate_coordinates(x1, x2, y1, y2): if x1 < x2: x_min = x1 x_max = x2 diff --git a/libs/labelFile.py b/libs/labelFile.py index 378576771..da82590c1 100644 --- a/libs/labelFile.py +++ b/libs/labelFile.py @@ -6,7 +6,6 @@ except ImportError: from PyQt4.QtGui import QImage -from base64 import b64encode, b64decode from libs.pascal_voc_io import PascalVocWriter from libs.yolo_io import YOLOWriter from libs.pascal_voc_io import XML_EXT @@ -14,7 +13,6 @@ from libs.create_ml_io import JSON_EXT from enum import Enum import os.path -import sys class LabelFileFormat(Enum): @@ -32,13 +30,13 @@ class LabelFile(object): # suffix = '.lif' suffix = XML_EXT - def __init__(self, filename=None): + def __init__(self): self.shapes = () self.image_path = None self.image_data = None self.verified = False - def save_create_ml_format(self, filename, shapes, image_path, image_data, class_list, line_color=None, fill_color=None, database_src=None): + def save_create_ml_format(self, filename, shapes, image_path): img_folder_path = os.path.dirname(image_path) img_folder_name = os.path.split(img_folder_path)[-1] img_file_name = os.path.basename(image_path) @@ -54,9 +52,7 @@ def save_create_ml_format(self, filename, shapes, image_path, image_data, class_ writer.verified = self.verified writer.write() - - def save_pascal_voc_format(self, filename, shapes, image_path, image_data, - line_color=None, fill_color=None, database_src=None): + def save_pascal_voc_format(self, filename, shapes, image_path, image_data): img_folder_path = os.path.dirname(image_path) img_folder_name = os.path.split(img_folder_path)[-1] img_file_name = os.path.basename(image_path) @@ -85,8 +81,7 @@ def save_pascal_voc_format(self, filename, shapes, image_path, image_data, writer.save(target_file=filename) return - def save_yolo_format(self, filename, shapes, image_path, image_data, class_list, - line_color=None, fill_color=None, database_src=None): + def save_yolo_format(self, filename, shapes, image_path, image_data, class_list): img_folder_path = os.path.dirname(image_path) img_folder_name = os.path.split(img_folder_path)[-1] img_file_name = os.path.basename(image_path) diff --git a/libs/pascal_voc_io.py b/libs/pascal_voc_io.py index d8f7d690b..dc19b7ea3 100644 --- a/libs/pascal_voc_io.py +++ b/libs/pascal_voc_io.py @@ -1,6 +1,5 @@ #!/usr/bin/env python # -*- coding: utf8 -*- -import sys from xml.etree import ElementTree from xml.etree.ElementTree import Element, SubElement from lxml import etree @@ -12,6 +11,7 @@ XML_EXT = '.xml' ENCODE_METHOD = DEFAULT_ENCODING + class PascalVocWriter: def __init__(self, folder_name, filename, img_size, database_src='Unknown', local_img_path=None): @@ -23,7 +23,8 @@ def __init__(self, folder_name, filename, img_size, database_src='Unknown', loca self.local_img_path = local_img_path self.verified = False - def prettify(self, elem): + @staticmethod + def prettify(elem): """ Return a pretty-printed XML string for the Element. """ @@ -31,8 +32,8 @@ def prettify(self, elem): root = etree.fromstring(rough_string) return etree.tostring(root, pretty_print=True, encoding=ENCODE_METHOD).replace(" ".encode(), "\t".encode()) # minidom does not support UTF-8 - # reparsed = minidom.parseString(rough_string) - # return reparsed.toprettyxml(indent="\t", encoding=ENCODE_METHOD) + # re_parsed = minidom.parseString(rough_string) + # return re_parsed.toprettyxml(indent="\t", encoding=ENCODE_METHOD) def gen_xml(self): """ @@ -78,9 +79,13 @@ def gen_xml(self): return top def add_bnd_box(self, x_min, y_min, x_max, y_max, name, difficult): - bnd_box = {'xmin': x_min, 'ymin': y_min, 'xmax': x_max, 'ymax': y_max} - bnd_box['name'] = name - bnd_box['difficult'] = difficult + bnd_box = { + 'xmin': x_min, + 'ymin': y_min, + 'xmax': x_max, + 'ymax': y_max, + 'name': name, + 'difficult': difficult} self.box_list.append(bnd_box) def append_objects(self, top): @@ -112,7 +117,6 @@ def append_objects(self, top): def save(self, target_file=None): root = self.gen_xml() self.append_objects(root) - out_file = None if target_file is None: out_file = codecs.open( self.filename + XML_EXT, 'w', encoding=ENCODE_METHOD) @@ -128,7 +132,7 @@ class PascalVocReader: def __init__(self, file_path): # shapes type: - # [labbel, [(x1,y1), (x2,y2), (x3,y3), (x4,y4)], color, color, difficult] + # [label, [(x1,y1), (x2,y2), (x3,y3), (x4,y4)], color, color, difficult] self.shapes = [] self.file_path = file_path self.verified = False @@ -152,7 +156,6 @@ def parse_xml(self): assert self.file_path.endswith(XML_EXT), "Unsupported file format" parser = etree.XMLParser(encoding=ENCODE_METHOD) xml_tree = ElementTree.parse(self.file_path, parser=parser).getroot() - filename = xml_tree.find('filename').text try: verified = xml_tree.attrib['verified'] if verified == 'yes': diff --git a/libs/settings.py b/libs/settings.py index e3eea7318..5280c7d33 100644 --- a/libs/settings.py +++ b/libs/settings.py @@ -1,6 +1,5 @@ import pickle import os -import sys class Settings(object): diff --git a/libs/stringBundle.py b/libs/stringBundle.py index dfd785908..399159689 100644 --- a/libs/stringBundle.py +++ b/libs/stringBundle.py @@ -42,7 +42,8 @@ def get_string(self, string_id): assert(string_id in self.id_to_message), "Missing string id : " + string_id return self.id_to_message[string_id] - def __create_lookup_fallback_list(self, locale_str): + @staticmethod + def __create_lookup_fallback_list(locale_str): result_paths = [] base_path = ":/strings" result_paths.append(base_path) @@ -56,7 +57,7 @@ def __create_lookup_fallback_list(self, locale_str): return result_paths def __load_bundle(self, path): - PROP_SEPERATOR = '=' + prop_seperator = '=' f = QFile(path) if f.exists(): if f.open(QIODevice.ReadOnly | QFile.Text): @@ -65,9 +66,9 @@ def __load_bundle(self, path): while not text.atEnd(): line = ustr(text.readLine()) - key_value = line.split(PROP_SEPERATOR) + key_value = line.split(prop_seperator) key = key_value[0].strip() - value = PROP_SEPERATOR.join(key_value[1:]).strip().strip('"') + value = prop_seperator.join(key_value[1:]).strip().strip('"') self.id_to_message[key] = value f.close() diff --git a/libs/ustr.py b/libs/ustr.py index bfcaff5d7..943ab61a1 100644 --- a/libs/ustr.py +++ b/libs/ustr.py @@ -1,6 +1,7 @@ import sys from libs.constants import DEFAULT_ENCODING + def ustr(x): """py2/py3 unicode helper""" diff --git a/libs/utils.py b/libs/utils.py index d440a14d4..5e4414262 100644 --- a/libs/utils.py +++ b/libs/utils.py @@ -62,12 +62,6 @@ def label_validator(): return QRegExpValidator(QRegExp(r'^[^ \t].+'), None) -class Struct(object): - - def __init__(self, **kwargs): - self.__dict__.update(kwargs) - - def distance(p): return sqrt(p.x() * p.x() + p.y() * p.y()) @@ -85,19 +79,22 @@ def generate_color_by_text(text): b = int((hash_code / 16581375) % 255) return QColor(r, g, b, 100) + def have_qstring(): """p3/qt5 get rid of QString wrapper as py3 has native unicode str type""" return not (sys.version_info.major >= 3 or QT_VERSION_STR.startswith('5.')) -def util_qt_strlistclass(): - return QStringList if have_qstring() else list -def natural_sort(list, key=lambda s:s): +def natural_sort(input_list, key=lambda s: s): """ Sort the list into natural alphanumeric order. """ - def get_alphanum_key_func(key): - convert = lambda text: int(text) if text.isdigit() else text - return lambda s: [convert(c) for c in re.split('([0-9]+)', key(s))] + def get_alphanum_key_func(internal_key): + + def convert(text): + return int(text) if text.isdigit() else text + + return lambda s: [convert(c) for c in re.split('([0-9]+)', internal_key(s))] + sort_key = get_alphanum_key_func(key) - list.sort(key=sort_key) + input_list.sort(key=sort_key) diff --git a/libs/yolo_io.py b/libs/yolo_io.py index 039acdb6d..fcae56dd9 100644 --- a/libs/yolo_io.py +++ b/libs/yolo_io.py @@ -1,16 +1,13 @@ #!/usr/bin/env python # -*- coding: utf8 -*- -import sys import os -from xml.etree import ElementTree -from xml.etree.ElementTree import Element, SubElement -from lxml import etree import codecs from libs.constants import DEFAULT_ENCODING TXT_EXT = '.txt' ENCODE_METHOD = DEFAULT_ENCODING + class YOLOWriter: def __init__(self, folder_name, filename, img_size, database_src='Unknown', local_img_path=None): @@ -23,12 +20,20 @@ def __init__(self, folder_name, filename, img_size, database_src='Unknown', loca self.verified = False def add_bnd_box(self, x_min, y_min, x_max, y_max, name, difficult): - bnd_box = {'xmin': x_min, 'ymin': y_min, 'xmax': x_max, 'ymax': y_max} - bnd_box['name'] = name - bnd_box['difficult'] = difficult + bnd_box = { + 'xmin': x_min, + 'ymin': y_min, + 'xmax': x_max, + 'ymax': y_max, + 'name': name, + 'difficult': difficult} self.box_list.append(bnd_box) - def bnd_box_to_yolo_line(self, box, class_list=[]): + def bnd_box_to_yolo_line(self, box, class_list=None): + + if class_list is None: + class_list = [] + x_min = box['xmin'] x_max = box['xmax'] y_min = box['ymin'] @@ -49,23 +54,20 @@ def bnd_box_to_yolo_line(self, box, class_list=[]): return class_index, x_center, y_center, w, h - def save(self, class_list=[], target_file=None): + def save(self, class_list=None, target_file=None): - out_file = None # Update yolo .txt - out_class_file = None # Update class list .txt + if class_list is None: + class_list = [] if target_file is None: - out_file = open( - self.filename + TXT_EXT, 'w', encoding=ENCODE_METHOD) + out_file = open(self.filename + TXT_EXT, 'w', encoding=ENCODE_METHOD) classes_file = os.path.join(os.path.dirname(os.path.abspath(self.filename)), "classes.txt") out_class_file = open(classes_file, 'w') - else: out_file = codecs.open(target_file, 'w', encoding=ENCODE_METHOD) classes_file = os.path.join(os.path.dirname(os.path.abspath(target_file)), "classes.txt") out_class_file = open(classes_file, 'w') - for box in self.box_list: class_index, x_center, y_center, w, h = self.bnd_box_to_yolo_line(box, class_list) # print (classIndex, x_center, y_center, w, h) @@ -80,12 +82,11 @@ def save(self, class_list=[], target_file=None): out_file.close() - class YoloReader: def __init__(self, file_path, image, class_list_path=None): # shapes type: - # [labbel, [(x1,y1), (x2,y2), (x3,y3), (x4,y4)], color, color, difficult] + # [label, [(x1,y1), (x2,y2), (x3,y3), (x4,y4)], color, color, difficult] self.shapes = [] self.file_path = file_path diff --git a/tools/label_to_csv.py b/tools/label_to_csv.py index f3b72bab4..4227e19d7 100755 --- a/tools/label_to_csv.py +++ b/tools/label_to_csv.py @@ -174,7 +174,7 @@ def xml2csv(location, training_dir, path_prefix): res = [] # Get all the file in dir for training_type_dir in os.listdir(args["location"]): - # Get the dirname + # Get the dir_name dir_name = f"{args['location']}/{training_type_dir}" # Check whether is dir From 6f9f639f86cb69011e5e19951fadf27527a370d0 Mon Sep 17 00:00:00 2001 From: Cerno_b Date: Wed, 10 Mar 2021 17:29:59 +0100 Subject: [PATCH 11/13] Rename filenames --- labelImg.py | 16 ++++++++-------- libs/{colorDialog.py => color_dialog.py} | 0 libs/{combobox.py => combo_box.py} | 0 ...dgetItem.py => hashable_qlist_widget_item.py} | 0 libs/{labelDialog.py => label_dialog.py} | 0 libs/{labelFile.py => label_file.py} | 0 libs/{stringBundle.py => string_bundle.py} | 0 libs/{toolBar.py => tool_bar.py} | 0 libs/{zoomWidget.py => zoom_widget.py} | 0 9 files changed, 8 insertions(+), 8 deletions(-) rename libs/{colorDialog.py => color_dialog.py} (100%) rename libs/{combobox.py => combo_box.py} (100%) rename libs/{hashableQListWidgetItem.py => hashable_qlist_widget_item.py} (100%) rename libs/{labelDialog.py => label_dialog.py} (100%) rename libs/{labelFile.py => label_file.py} (100%) rename libs/{stringBundle.py => string_bundle.py} (100%) rename libs/{toolBar.py => tool_bar.py} (100%) rename libs/{zoomWidget.py => zoom_widget.py} (100%) diff --git a/labelImg.py b/labelImg.py index 9892ac04a..2bd51f0ae 100755 --- a/labelImg.py +++ b/labelImg.py @@ -25,19 +25,19 @@ from PyQt4.QtGui import * from PyQt4.QtCore import * -from libs.combobox import ComboBox +from libs.combo_box import ComboBox from libs.resources import * from libs.constants import * from libs.utils import * from libs.settings import Settings from libs.shape import Shape, DEFAULT_LINE_COLOR, DEFAULT_FILL_COLOR -from libs.stringBundle import StringBundle +from libs.string_bundle import StringBundle from libs.canvas import Canvas -from libs.zoomWidget import ZoomWidget -from libs.labelDialog import LabelDialog -from libs.colorDialog import ColorDialog -from libs.labelFile import LabelFile, LabelFileError, LabelFileFormat -from libs.toolBar import ToolBar +from libs.zoom_widget import ZoomWidget +from libs.label_dialog import LabelDialog +from libs.color_dialog import ColorDialog +from libs.label_file import LabelFile, LabelFileError, LabelFileFormat +from libs.tool_bar import ToolBar from libs.pascal_voc_io import PascalVocReader from libs.pascal_voc_io import XML_EXT from libs.yolo_io import YoloReader @@ -45,7 +45,7 @@ from libs.create_ml_io import CreateMLReader from libs.create_ml_io import JSON_EXT from libs.ustr import ustr -from libs.hashableQListWidgetItem import HashableQListWidgetItem +from libs.hashable_qlist_widget_item import HashableQListWidgetItem __appname__ = 'labelImg' diff --git a/libs/colorDialog.py b/libs/color_dialog.py similarity index 100% rename from libs/colorDialog.py rename to libs/color_dialog.py diff --git a/libs/combobox.py b/libs/combo_box.py similarity index 100% rename from libs/combobox.py rename to libs/combo_box.py diff --git a/libs/hashableQListWidgetItem.py b/libs/hashable_qlist_widget_item.py similarity index 100% rename from libs/hashableQListWidgetItem.py rename to libs/hashable_qlist_widget_item.py diff --git a/libs/labelDialog.py b/libs/label_dialog.py similarity index 100% rename from libs/labelDialog.py rename to libs/label_dialog.py diff --git a/libs/labelFile.py b/libs/label_file.py similarity index 100% rename from libs/labelFile.py rename to libs/label_file.py diff --git a/libs/stringBundle.py b/libs/string_bundle.py similarity index 100% rename from libs/stringBundle.py rename to libs/string_bundle.py diff --git a/libs/toolBar.py b/libs/tool_bar.py similarity index 100% rename from libs/toolBar.py rename to libs/tool_bar.py diff --git a/libs/zoomWidget.py b/libs/zoom_widget.py similarity index 100% rename from libs/zoomWidget.py rename to libs/zoom_widget.py From 83e5c5aa6178a5eacd8ae7c49755db143324efa7 Mon Sep 17 00:00:00 2001 From: Cerno_b Date: Sun, 21 Mar 2021 13:16:21 +0100 Subject: [PATCH 12/13] Unify action var names and fix some camel case --- labelImg.py | 301 ++++++++++++++++++++++++++-------------------------- 1 file changed, 153 insertions(+), 148 deletions(-) diff --git a/labelImg.py b/labelImg.py index 2bd51f0ae..681189e34 100755 --- a/labelImg.py +++ b/labelImg.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- import argparse import codecs -import os.path +import os import platform import sys import subprocess @@ -212,29 +212,29 @@ def get_str(str_id): action_open = action(get_str('openFile'), self.open_file, 'Ctrl+O', 'open', get_str('openFileDetail')) - open_dir = action(get_str('openDir'), self.open_dir_dialog, - 'Ctrl+u', 'open', get_str('openDir')) + action_open_dir = action(get_str('openDir'), self.open_dir_dialog, + 'Ctrl+u', 'open', get_str('openDir')) - copy_prev_bounding = action(get_str('copyPrevBounding'), self.copy_previous_bounding_boxes, - 'Ctrl+v', 'paste', get_str('copyPrevBounding')) + action_copy_prev_bounding = action(get_str('copyPrevBounding'), self.copy_previous_bounding_boxes, + 'Ctrl+v', 'paste', get_str('copyPrevBounding')) - change_save_dir = action(get_str('changeSaveDir'), self.change_save_dir_dialog, - 'Ctrl+r', 'open', get_str('changeSavedAnnotationDir')) + action_change_save_dir = action(get_str('changeSaveDir'), self.change_save_dir_dialog, + 'Ctrl+r', 'open', get_str('changeSavedAnnotationDir')) - open_annotation = action(get_str('openAnnotation'), self.open_annotation_dialog, - 'Ctrl+Shift+O', 'open', get_str('openAnnotationDetail')) + action_open_annotation = action(get_str('openAnnotation'), self.open_annotation_dialog, + 'Ctrl+Shift+O', 'open', get_str('openAnnotationDetail')) - open_next_image = action(get_str('nextImg'), self.open_next_image, - 'd', 'next', get_str('nextImgDetail')) + action_open_next_image = action(get_str('nextImg'), self.open_next_image, + 'd', 'next', get_str('nextImgDetail')) - open_prev_image = action(get_str('prevImg'), self.open_prev_image, - 'a', 'prev', get_str('prevImgDetail')) + action_open_prev_image = action(get_str('prevImg'), self.open_prev_image, + 'a', 'prev', get_str('prevImgDetail')) - verify = action(get_str('verifyImg'), self.verify_image, - 'space', 'verify', get_str('verifyImgDetail')) + action_verify = action(get_str('verifyImg'), self.verify_image, + 'space', 'verify', get_str('verifyImgDetail')) - save = action(get_str('save'), self.save_file, - 'Ctrl+S', 'save', get_str('saveDetail'), enabled=False) + action_save = action(get_str('save'), self.save_file, + 'Ctrl+S', 'save', get_str('saveDetail'), enabled=False) def get_format_meta(label_format): """ @@ -247,73 +247,78 @@ def get_format_meta(label_format): elif label_format == LabelFileFormat.CREATE_ML: return '&CreateML', 'format_createml' - save_format = action(get_format_meta(self.label_file_format)[0], - self.change_format, 'Ctrl+', - get_format_meta(self.label_file_format)[1], - get_str('changeSaveFormat'), enabled=True) + action_save_format = action(get_format_meta(self.label_file_format)[0], + self.change_format, 'Ctrl+', + get_format_meta(self.label_file_format)[1], + get_str('changeSaveFormat'), enabled=True) - save_as = action(get_str('saveAs'), self.save_file_as, - 'Ctrl+Shift+S', 'save-as', get_str('saveAsDetail'), enabled=False) + action_save_as = action(get_str('saveAs'), self.save_file_as, + 'Ctrl+Shift+S', 'save-as', get_str('saveAsDetail'), enabled=False) - close = action(get_str('closeCur'), self.close_file, 'Ctrl+W', 'close', get_str('closeCurDetail')) + action_close = action(get_str('closeCur'), self.close_file, + 'Ctrl+W', 'close', get_str('closeCurDetail')) - delete_image = action(get_str('deleteImg'), self.delete_image, 'Ctrl+Shift+D', 'close', get_str('deleteImgDetail')) + action_delete_image = action(get_str('deleteImg'), self.delete_image, + 'Ctrl+Shift+D', 'close', get_str('deleteImgDetail')) - reset_all = action(get_str('resetAll'), self.reset_all, None, 'resetall', get_str('resetAllDetail')) + action_reset_all = action(get_str('resetAll'), self.reset_all, + None, 'resetall', get_str('resetAllDetail')) - color1 = action(get_str('boxLineColor'), self.choose_color1, - 'Ctrl+L', 'color_line', get_str('boxLineColorDetail')) + action_color1 = action(get_str('boxLineColor'), self.choose_color1, + 'Ctrl+L', 'color_line', get_str('boxLineColorDetail')) - create_mode = action(get_str('crtBox'), self.set_create_mode, - 'w', 'new', get_str('crtBoxDetail'), enabled=False) - edit_mode = action('&Edit\nRectBox', self.set_edit_mode, - 'Ctrl+J', 'edit', u'Move and edit Boxes', enabled=False) + action_create_mode = action(get_str('crtBox'), self.set_create_mode, + 'w', 'new', get_str('crtBoxDetail'), enabled=False) - create = action(get_str('crtBox'), self.create_shape, - 'w', 'new', get_str('crtBoxDetail'), enabled=False) - delete = action(get_str('delBox'), self.delete_selected_shape, - 'Delete', 'delete', get_str('delBoxDetail'), enabled=False) - copy = action(get_str('dupBox'), self.copy_selected_shape, - 'Ctrl+D', 'copy', get_str('dupBoxDetail'), - enabled=False) + action_edit_mode = action('&Edit\nRectBox', self.set_edit_mode, + 'Ctrl+J', 'edit', u'Move and edit Boxes', enabled=False) - advanced_mode = action(get_str('advancedMode'), self.toggle_advanced_mode, - 'Ctrl+Shift+A', 'expert', get_str('advancedModeDetail'), - checkable=True) + action_create = action(get_str('crtBox'), self.create_shape, + 'w', 'new', get_str('crtBoxDetail'), enabled=False) - hide_all = action('&Hide\nRectBox', partial(self.toggle_polygons, False), - 'Ctrl+H', 'hide', get_str('hideAllBoxDetail'), - enabled=False) - show_all = action('&Show\nRectBox', partial(self.toggle_polygons, True), - 'Ctrl+A', 'hide', get_str('showAllBoxDetail'), - enabled=False) + action_delete = action(get_str('delBox'), self.delete_selected_shape, + 'Delete', 'delete', get_str('delBoxDetail'), enabled=False) - action_help = action(get_str('tutorial'), self.show_tutorial_dialog, None, 'help', get_str('tutorialDetail')) - show_info = action(get_str('info'), self.show_info_dialog, None, 'help', get_str('info')) + action_copy = action(get_str('dupBox'), self.copy_selected_shape, + 'Ctrl+D', 'copy', get_str('dupBoxDetail'), enabled=False) - zoom = QWidgetAction(self) - zoom.setDefaultWidget(self.zoom_widget) + action_advanced_mode = action(get_str('advancedMode'), self.toggle_advanced_mode, + 'Ctrl+Shift+A', 'expert', get_str('advancedModeDetail'), checkable=True) + + action_hide_all = action('&Hide\nRectBox', partial(self.toggle_polygons, False), + 'Ctrl+H', 'hide', get_str('hideAllBoxDetail'), enabled=False) + + action_show_all = action('&Show\nRectBox', partial(self.toggle_polygons, True), + 'Ctrl+A', 'hide', get_str('showAllBoxDetail'), enabled=False) + + action_help = action(get_str('tutorial'), self.show_tutorial_dialog, + None, 'help', get_str('tutorialDetail')) + + action_show_info = action(get_str('info'), self.show_info_dialog, + None, 'help', get_str('info')) + + action_zoom = QWidgetAction(self) + action_zoom.setDefaultWidget(self.zoom_widget) self.zoom_widget.setWhatsThis( u"Zoom in or out of the image. Also accessible with" " %s and %s from the canvas." % (format_shortcut("Ctrl+[-+]"), format_shortcut("Ctrl+Wheel"))) self.zoom_widget.setEnabled(False) - zoom_in = action(get_str('zoomin'), partial(self.add_zoom, 10), - 'Ctrl++', 'zoom-in', get_str('zoominDetail'), enabled=False) - zoom_out = action(get_str('zoomout'), partial(self.add_zoom, -10), - 'Ctrl+-', 'zoom-out', get_str('zoomoutDetail'), enabled=False) - zoom_org = action(get_str('originalsize'), partial(self.set_zoom, 100), - 'Ctrl+=', 'zoom', get_str('originalsizeDetail'), enabled=False) - fit_window = action(get_str('fitWin'), self.set_fit_window, - 'Ctrl+F', 'fit-window', get_str('fitWinDetail'), - checkable=True, enabled=False) - fit_width = action(get_str('fitWidth'), self.set_fit_width, - 'Ctrl+Shift+F', 'fit-width', get_str('fitWidthDetail'), - checkable=True, enabled=False) + action_zoom_in = action(get_str('zoomin'), partial(self.add_zoom, 10), + 'Ctrl++', 'zoom-in', get_str('zoominDetail'), enabled=False) + action_zoom_out = action(get_str('zoomout'), partial(self.add_zoom, -10), + 'Ctrl+-', 'zoom-out', get_str('zoomoutDetail'), enabled=False) + action_zoom_org = action(get_str('originalsize'), partial(self.set_zoom, 100), + 'Ctrl+=', 'zoom', get_str('originalsizeDetail'), enabled=False) + action_fit_window = action(get_str('fitWin'), self.set_fit_window, + 'Ctrl+F', 'fit-window', get_str('fitWinDetail'), checkable=True, enabled=False) + action_fit_width = action(get_str('fitWidth'), self.set_fit_width, + 'Ctrl+Shift+F', 'fit-width', get_str('fitWidthDetail'), checkable=True, enabled=False) + # Group zoom controls into a list for easier toggling. - zoom_actions = (self.zoom_widget, zoom_in, zoom_out, - zoom_org, fit_window, fit_width) + zoom_actions = (self.zoom_widget, action_zoom_in, action_zoom_out, + action_zoom_org, action_fit_window, action_fit_width) self.zoom_mode = self.ScaleMode.MANUAL_ZOOM self.scalers = { self.ScaleMode.FIT_WINDOW: self.scale_fit_window, @@ -322,17 +327,16 @@ def get_format_meta(label_format): self.ScaleMode.MANUAL_ZOOM: lambda: 1, } - edit = action(get_str('editLabel'), self.edit_label, - 'Ctrl+E', 'edit', get_str('editLabelDetail'), - enabled=False) - self.edit_button.setDefaultAction(edit) + action_edit = action(get_str('editLabel'), self.edit_label, + 'Ctrl+E', 'edit', get_str('editLabelDetail'), enabled=False) + + self.edit_button.setDefaultAction(action_edit) + + action_shape_line_color = action(get_str('shapeLineColor'), self.choose_shape_line_color, + icon='color_line', tip=get_str('shapeLineColorDetail'), enabled=False) - shape_line_color = action(get_str('shapeLineColor'), self.choose_shape_line_color, - icon='color_line', tip=get_str('shapeLineColorDetail'), - enabled=False) - shape_fill_color = action(get_str('shapeFillColor'), self.choose_shape_fill_color, - icon='color', tip=get_str('shapeFillColorDetail'), - enabled=False) + action_shape_fill_color = action(get_str('shapeFillColor'), self.choose_shape_fill_color, + icon='color', tip=get_str('shapeFillColorDetail'), enabled=False) labels = self.dock.toggleViewAction() labels.setText(get_str('showHide')) @@ -340,7 +344,7 @@ def get_format_meta(label_format): # Label list context menu. label_menu = QMenu() - add_actions(label_menu, (edit, delete)) + add_actions(label_menu, (action_edit, action_delete)) self.label_list.setContextMenuPolicy(Qt.CustomContextMenu) self.label_list.customContextMenuRequested.connect( self.pop_label_list_menu) @@ -356,38 +360,38 @@ def get_format_meta(label_format): class Actions: def __init__(self): - self.save = save - self.save_format = save_format - self.saveAs = save_as + self.save = action_save + self.save_format = action_save_format + self.save_as = action_save_as self.open = action_open - self.close = close - self.resetAll = reset_all - self.deleteImg = delete_image - self.lineColor = color1 - self.create = create - self.delete = delete - self.edit = edit - self.copy = copy - self.createMode = create_mode - self.editMode = edit_mode - self.advancedMode = advanced_mode - self.shapeLineColor = shape_line_color - self.shapeFillColor = shape_fill_color - self.zoom = zoom - self.zoomIn = zoom_in - self.zoomOut = zoom_out - self.zoomOrg = zoom_org - self.fitWindow = fit_window - self.fitWidth = fit_width - self.zoomActions = zoom_actions - self.fileMenuActions = (action_open, open_dir, save, save_as, close, reset_all, action_quit) + self.close = action_close + self.reset_all = action_reset_all + self.delete_img = action_delete_image + self.line_color = action_color1 + self.create = action_create + self.delete = action_delete + self.edit = action_edit + self.copy = action_copy + self.create_mode = action_create_mode + self.edit_mode = action_edit_mode + self.advanced_mode = action_advanced_mode + self.shape_line_color = action_shape_line_color + self.shape_fill_color = action_shape_fill_color + self.zoom = action_zoom + self.zoom_in = action_zoom_in + self.zoom_out = action_zoom_out + self.zoom_org = action_zoom_org + self.fit_window = action_fit_window + self.fit_width = action_fit_width + self.zoom_actions = zoom_actions + self.file_menu_actions = (action_open, action_open_dir, action_save, action_save_as, action_close, action_reset_all, action_quit) self.beginner = () self.advanced = () - self.editMenu = (edit, copy, delete, None, color1, draw_squares_option) - self.beginnerContext = (create, edit, copy, delete) - self.advancedContext = (create_mode, edit_mode, edit, copy, delete, shape_line_color, shape_fill_color) - self.onLoadActive = (close, create, create_mode, edit_mode) - self.onShapesPresent = (save_as, hide_all, show_all) + self.edit_menu = (action_edit, action_copy, action_delete, None, action_color1, draw_squares_option) + self.beginner_context = (action_create, action_edit, action_copy, action_delete) + self.advanced_context = (action_create_mode, action_edit_mode, action_edit, action_copy, action_delete, action_shape_line_color, action_shape_fill_color) + self.on_load_active = (action_close, action_create, action_create_mode, action_edit_mode) + self.on_shapes_present = (action_save_as, action_hide_all, action_show_all) self.actions = Actions() @@ -399,8 +403,8 @@ def __init__(self): self.edit = add_menu(get_str('menu_edit')) self.view = add_menu(get_str('menu_view')) self.help = add_menu(get_str('menu_help')) - self.recentFiles = QMenu(get_str('menu_openRecent')) - self.labelList = label_menu + self.recent_files = QMenu(get_str('menu_openRecent')) + self.label_list = label_menu self.menus = Menus() @@ -413,7 +417,7 @@ def __init__(self): self.single_class_mode.setShortcut("Ctrl+Shift+S") self.single_class_mode.setCheckable(True) self.single_class_mode.setChecked(settings.get(SETTING_SINGLE_CLASS, False)) - self.lastLabel = None + self.last_label = None # Add option to enable/disable labels being displayed at the top of bounding boxes self.display_label_option = QAction(get_str('displayLabel'), self) self.display_label_option.setShortcut("Ctrl+Shift+P") @@ -422,34 +426,35 @@ def __init__(self): self.display_label_option.triggered.connect(self.toggle_paint_labels_option) add_actions(self.menus.file, - (action_open, open_dir, copy_prev_bounding, change_save_dir, open_annotation, self.menus.recentFiles, save, save_format, save_as, close, reset_all, delete_image, action_quit)) - add_actions(self.menus.help, (action_help, show_info)) + (action_open, action_open_dir, action_copy_prev_bounding, action_change_save_dir, action_open_annotation, self.menus.recent_files, + action_save, action_save_format, action_save_as, action_close, action_reset_all, action_delete_image, action_quit)) + add_actions(self.menus.help, (action_help, action_show_info)) add_actions(self.menus.view, ( self.auto_saving, self.single_class_mode, self.display_label_option, - labels, advanced_mode, None, - hide_all, show_all, None, - zoom_in, zoom_out, zoom_org, None, - fit_window, fit_width)) + labels, action_advanced_mode, None, + action_hide_all, action_show_all, None, + action_zoom_in, action_zoom_out, action_zoom_org, None, + action_fit_window, action_fit_width)) self.menus.file.aboutToShow.connect(self.update_file_menu) # Custom context menu for the canvas widget: - add_actions(self.canvas.menus[0], self.actions.beginnerContext) + add_actions(self.canvas.menus[0], self.actions.beginner_context) add_actions(self.canvas.menus[1], ( action('&Copy here', self.copy_shape), action('&Move here', self.move_shape))) self.tools = self.add_toolbar('Tools') self.actions.beginner = ( - action_open, open_dir, change_save_dir, open_next_image, open_prev_image, verify, save, save_format, None, create, copy, delete, None, - zoom_in, zoom, zoom_out, fit_window, fit_width) + action_open, action_open_dir, action_change_save_dir, action_open_next_image, action_open_prev_image, action_verify, action_save, action_save_format, None, action_create, action_copy, action_delete, None, + action_zoom_in, action_zoom, action_zoom_out, action_fit_window, action_fit_width) self.actions.advanced = ( - action_open, open_dir, change_save_dir, open_next_image, open_prev_image, save, save_format, None, - create_mode, edit_mode, None, - hide_all, show_all) + action_open, action_open_dir, action_change_save_dir, action_open_next_image, action_open_prev_image, action_save, action_save_format, None, + action_create_mode, action_edit_mode, None, + action_hide_all, action_show_all) self.statusBar().showMessage('%s started.' % __appname__) self.statusBar().show() @@ -506,7 +511,7 @@ def x_bool(x): return bool(x) if x_bool(settings.get(SETTING_ADVANCE_MODE, False)): - self.actions.advancedMode.setChecked(True) + self.actions.advanced_mode.setChecked(True) self.toggle_advanced_mode() # Populate the File menu dynamically. @@ -580,25 +585,25 @@ def toggle_advanced_mode(self, value=True): self.populate_mode_actions() self.edit_button.setVisible(not value) if value: - self.actions.createMode.setEnabled(True) - self.actions.editMode.setEnabled(False) + self.actions.create_mode.setEnabled(True) + self.actions.edit_mode.setEnabled(False) self.dock.setFeatures(self.dock.features() | self.dock_features) else: self.dock.setFeatures(self.dock.features() ^ self.dock_features) def populate_mode_actions(self): if self.beginner(): - tool, menu = self.actions.beginner, self.actions.beginnerContext + tool, menu = self.actions.beginner, self.actions.beginner_context else: - tool, menu = self.actions.advanced, self.actions.advancedContext + tool, menu = self.actions.advanced, self.actions.advanced_context self.tools.clear() add_actions(self.tools, tool) self.canvas.menus[0].clear() add_actions(self.canvas.menus[0], menu) self.menus.edit.clear() actions = (self.actions.create,) if self.beginner() \ - else (self.actions.createMode, self.actions.editMode) - add_actions(self.menus.edit, actions + self.actions.editMenu) + else (self.actions.create_mode, self.actions.edit_mode) + add_actions(self.menus.edit, actions + self.actions.edit_menu) def set_beginner(self): self.tools.clear() @@ -619,9 +624,9 @@ def set_clean(self): def toggle_actions(self, value=True): """Enable/Disable widgets which depend on an opened image.""" - for z in self.actions.zoomActions: + for z in self.actions.zoom_actions: z.setEnabled(value) - for action in self.actions.onLoadActive: + for action in self.actions.on_load_active: action.setEnabled(value) @staticmethod @@ -688,7 +693,7 @@ def create_shape(self): def toggle_drawing_sensitive(self, drawing=True): """In the middle of drawing, toggling between modes should be disabled.""" - self.actions.editMode.setEnabled(not drawing) + self.actions.edit_mode.setEnabled(not drawing) if not drawing and self.beginner(): # Cancel creation. print('Cancel creation.') @@ -698,8 +703,8 @@ def toggle_drawing_sensitive(self, drawing=True): def toggle_draw_mode(self, edit=True): self.canvas.set_editing(edit) - self.actions.createMode.setEnabled(edit) - self.actions.editMode.setEnabled(not edit) + self.actions.create_mode.setEnabled(edit) + self.actions.edit_mode.setEnabled(not edit) def set_create_mode(self): assert self.advanced() @@ -715,7 +720,7 @@ def update_file_menu(self): def exists(filename): return os.path.exists(filename) - menu = self.menus.recentFiles + menu = self.menus.recent_files menu.clear() files = [f for f in self.recent_files if f != curr_file_path and exists(f)] @@ -727,7 +732,7 @@ def exists(filename): menu.addAction(action) def pop_label_list_menu(self, point): - self.menus.labelList.exec_(self.label_list.mapToGlobal(point)) + self.menus.label_list.exec_(self.label_list.mapToGlobal(point)) def edit_label(self): if not self.canvas.editing(): @@ -786,8 +791,8 @@ def shape_selection_changed(self, selected=False): self.actions.delete.setEnabled(selected) self.actions.copy.setEnabled(selected) self.actions.edit.setEnabled(selected) - self.actions.shapeLineColor.setEnabled(selected) - self.actions.shapeFillColor.setEnabled(selected) + self.actions.shape_line_color.setEnabled(selected) + self.actions.shape_fill_color.setEnabled(selected) def add_label(self, shape): shape.paint_label = self.display_label_option.isChecked() @@ -798,7 +803,7 @@ def add_label(self, shape): self.items_to_shapes[item] = shape self.shapes_to_items[shape] = item self.label_list.addItem(item) - for action in self.actions.onShapesPresent: + for action in self.actions.on_shapes_present: action.setEnabled(True) self.update_combo_box() @@ -937,11 +942,11 @@ def new_shape(self): parent=self, list_item=self.label_hist) # Sync single class mode from PR#106 - if self.single_class_mode.isChecked() and self.lastLabel: - text = self.lastLabel + if self.single_class_mode.isChecked() and self.last_label: + text = self.last_label else: text = self.label_dialog.pop_up(text=self.prev_label_text) - self.lastLabel = text + self.last_label = text else: text = self.default_label_text_line.text() @@ -956,7 +961,7 @@ def new_shape(self): self.canvas.set_editing(True) self.actions.create.setEnabled(True) else: - self.actions.editMode.setEnabled(True) + self.actions.edit_mode.setEnabled(True) self.set_dirty() if text not in self.label_hist: @@ -971,8 +976,8 @@ def scroll_request(self, delta, orientation): bar.setValue(bar.value() + bar.singleStep() * units) def set_zoom(self, value): - self.actions.fitWidth.setChecked(False) - self.actions.fitWindow.setChecked(False) + self.actions.fit_width.setChecked(False) + self.actions.fit_window.setChecked(False) self.zoom_mode = self.ScaleMode.MANUAL_ZOOM self.zoom_widget.setValue(value) @@ -1033,13 +1038,13 @@ def zoom_request(self, delta): def set_fit_window(self, value=True): if value: - self.actions.fitWidth.setChecked(False) + self.actions.fit_width.setChecked(False) self.zoom_mode = self.ScaleMode.FIT_WINDOW if value else self.ScaleMode.MANUAL_ZOOM self.adjust_scale() def set_fit_width(self, value=True): if value: - self.actions.fitWindow.setChecked(False) + self.actions.fit_window.setChecked(False) self.zoom_mode = self.ScaleMode.FIT_WIDTH if value else self.ScaleMode.MANUAL_ZOOM self.adjust_scale() @@ -1435,7 +1440,7 @@ def close_file(self, _value=False): self.set_clean() self.toggle_actions(False) self.canvas.setEnabled(False) - self.actions.saveAs.setEnabled(False) + self.actions.save_as.setEnabled(False) def delete_image(self): delete_path = self.file_path @@ -1490,7 +1495,7 @@ def delete_selected_shape(self): self.remove_label(self.canvas.delete_selected()) self.set_dirty() if self.no_shapes(): - for action in self.actions.onShapesPresent: + for action in self.actions.on_shapes_present: action.setEnabled(False) def choose_shape_line_color(self): From 4f6029ee7d175c2deb1fd8adfdf71cee23e03a86 Mon Sep 17 00:00:00 2001 From: Cerno_b Date: Mon, 22 Mar 2021 07:26:30 +0100 Subject: [PATCH 13/13] Fix indentation --- libs/string_bundle.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libs/string_bundle.py b/libs/string_bundle.py index 399159689..514afd321 100644 --- a/libs/string_bundle.py +++ b/libs/string_bundle.py @@ -64,11 +64,11 @@ def __load_bundle(self, path): text = QTextStream(f) text.setCodec("UTF-8") - while not text.atEnd(): - line = ustr(text.readLine()) - key_value = line.split(prop_seperator) - key = key_value[0].strip() - value = prop_seperator.join(key_value[1:]).strip().strip('"') - self.id_to_message[key] = value + while not text.atEnd(): + line = ustr(text.readLine()) + key_value = line.split(prop_seperator) + key = key_value[0].strip() + value = prop_seperator.join(key_value[1:]).strip().strip('"') + self.id_to_message[key] = value f.close()