From 5936a7f16c19e0849305f76f16733422004f0e30 Mon Sep 17 00:00:00 2001 From: jkranabetter Date: Sat, 6 Aug 2022 11:27:22 -0600 Subject: [PATCH 1/7] Initial changes to box color for class 0 --- .gitignore | 2 ++ JoshToDo.md | 4 ++++ labelImg.py | 21 ++++----------------- libs/canvas.py | 11 ++++------- libs/shape.py | 11 +++-------- libs/utils.py | 8 +++++++- 6 files changed, 24 insertions(+), 33 deletions(-) create mode 100644 JoshToDo.md diff --git a/.gitignore b/.gitignore index 63754ecf1..78577b456 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,5 @@ __pycache__/ .unison* .attach* tmp.* + +.venv/ diff --git a/JoshToDo.md b/JoshToDo.md new file mode 100644 index 000000000..96acabf38 --- /dev/null +++ b/JoshToDo.md @@ -0,0 +1,4 @@ +## To Do +- easy swap class colors +- hotkey to remove drag and click corner underneath +- undo \ No newline at end of file diff --git a/labelImg.py b/labelImg.py index efd8a2976..da404abfe 100755 --- a/labelImg.py +++ b/labelImg.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python + # -*- coding: utf-8 -*- import argparse import codecs @@ -9,20 +9,9 @@ import webbrowser as wb from functools import partial -try: - from PyQt5.QtGui import * - from PyQt5.QtCore import * - from PyQt5.QtWidgets import * -except ImportError: - # needed for py3+qt4 - # Ref: - # http://pyqt.sourceforge.net/Docs/PyQt4/incompatible_apis.html - # http://stackoverflow.com/questions/21217399/pyqt4-qtcore-qvariant-object-instead-of-a-string - if sys.version_info.major >= 3: - import sip - sip.setapi('QVariant', 2) - from PyQt4.QtGui import * - from PyQt4.QtCore import * +from PyQt5.QtGui import * +from PyQt5.QtCore import * +from PyQt5.QtWidgets import * from libs.combobox import ComboBox from libs.default_label_combobox import DefaultLabelComboBox @@ -50,7 +39,6 @@ __appname__ = 'labelImg' - class WindowMixin(object): def menu(self, title, actions=None): @@ -69,7 +57,6 @@ 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)) diff --git a/libs/canvas.py b/libs/canvas.py index ca7986ff3..07a6025bf 100644 --- a/libs/canvas.py +++ b/libs/canvas.py @@ -1,11 +1,8 @@ -try: - from PyQt5.QtGui import * - from PyQt5.QtCore import * - from PyQt5.QtWidgets import * -except ImportError: - from PyQt4.QtGui import * - from PyQt4.QtCore import * +from PyQt5.QtGui import * +from PyQt5.QtCore import * +from PyQt5.QtWidgets import * + # from PyQt4.QtOpenGL import * diff --git a/libs/shape.py b/libs/shape.py index 65b5bac12..a9b91d44b 100644 --- a/libs/shape.py +++ b/libs/shape.py @@ -1,13 +1,8 @@ #!/usr/bin/python # -*- coding: utf-8 -*- - -try: - from PyQt5.QtGui import * - from PyQt5.QtCore import * -except ImportError: - from PyQt4.QtGui import * - from PyQt4.QtCore import * +from PyQt5.QtGui import * +from PyQt5.QtCore import * from libs.utils import distance import sys @@ -16,7 +11,7 @@ DEFAULT_FILL_COLOR = QColor(255, 0, 0, 128) DEFAULT_SELECT_LINE_COLOR = QColor(255, 255, 255) DEFAULT_SELECT_FILL_COLOR = QColor(0, 128, 255, 155) -DEFAULT_VERTEX_FILL_COLOR = QColor(0, 255, 0, 255) +DEFAULT_VERTEX_FILL_COLOR = QColor(59, 219, 255, 50) DEFAULT_HVERTEX_FILL_COLOR = QColor(255, 0, 0) diff --git a/libs/utils.py b/libs/utils.py index d511c151b..21486b558 100644 --- a/libs/utils.py +++ b/libs/utils.py @@ -81,11 +81,17 @@ def format_shortcut(text): def generate_color_by_text(text): s = ustr(text) + print('generating color by text...') + print(f'{s} {type(s)}') 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) + if text == '0': + color = QColor(255, 88, 59, 100) + else: + color = QColor(r, g, b, 100) + return color def have_qstring(): From c801e312d1f955c89f2221bd4c93cb14b7d9fb74 Mon Sep 17 00:00:00 2001 From: Joshua Kranabetter Date: Sat, 6 Aug 2022 22:24:22 -0600 Subject: [PATCH 2/7] Custom Colors and Toggle Vertices --- JoshToDo.md | 20 +++++++++++++++++++- labelImg.py | 17 +++++++++++++++-- libs/canvas.py | 6 +++--- libs/constants.py | 10 ++++++++++ libs/shape.py | 24 ++++++++++++++++-------- libs/stringBundle.py | 10 +++------- libs/utils.py | 21 ++++++--------------- resources/strings/strings.properties | 4 ++++ 8 files changed, 76 insertions(+), 36 deletions(-) diff --git a/JoshToDo.md b/JoshToDo.md index 96acabf38..6bf72392f 100644 --- a/JoshToDo.md +++ b/JoshToDo.md @@ -1,4 +1,22 @@ +## Getting Started + +After creating and activating a virutal env, run these commands to get setup: +``` +pip install pyqt5 +pip install lxml +pyrcc5 -o libs/resources.py resources.qrc +``` +Then finally run: +``` + +``` + ## To Do - easy swap class colors - hotkey to remove drag and click corner underneath -- undo \ No newline at end of file +- undo +- dark mode + +# Done +- Several custom colors in constants.py file +- toggle vertices in view tab \ No newline at end of file diff --git a/labelImg.py b/labelImg.py index da404abfe..ef68e8074 100755 --- a/labelImg.py +++ b/labelImg.py @@ -20,6 +20,7 @@ from libs.utils import * from libs.settings import Settings from libs.shape import Shape, DEFAULT_LINE_COLOR, DEFAULT_FILL_COLOR +import libs.shape from libs.stringBundle import StringBundle from libs.canvas import Canvas from libs.zoomWidget import ZoomWidget @@ -281,6 +282,13 @@ def get_format_meta(format): 'Ctrl+A', 'hide', get_str('showAllBoxDetail'), enabled=False) + hide_vertices = action(get_str('hideAllVertices'), partial(self.toggle_vertices, False), + 'Ctrl+k', 'hide', get_str('hideAllBoxDetail'), + enabled=False) + show_vertices = action(get_str('showAllVertices'), partial(self.toggle_vertices, True), + 'Ctrl+T', 'hide', get_str('showAllBoxDetail'), + enabled=False) + help_default = action(get_str('tutorialDefault'), self.show_default_tutorial_dialog, None, 'help', get_str('tutorialDetail')) show_info = action(get_str('info'), self.show_info_dialog, None, 'help', get_str('info')) show_shortcut = action(get_str('shortcut'), self.show_shortcuts_dialog, None, 'help', get_str('shortcut')) @@ -386,7 +394,7 @@ def get_format_meta(format): delete, shape_line_color, shape_fill_color), onLoadActive=( close, create, create_mode, edit_mode), - onShapesPresent=(save_as, hide_all, show_all)) + onShapesPresent=(save_as, hide_all, show_all, hide_vertices, show_vertices)) self.menus = Struct( file=self.menu(get_str('menu_file')), @@ -422,6 +430,7 @@ def get_format_meta(format): self.display_label_option, labels, advanced_mode, None, hide_all, show_all, None, + hide_vertices, show_vertices, None, zoom_in, zoom_out, zoom_org, None, fit_window, fit_width, None, light_brighten, light_darken, light_org)) @@ -443,7 +452,7 @@ def get_format_meta(format): self.actions.advanced = ( 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) + hide_all, show_all, hide_vertices, show_vertices) self.statusBar().showMessage('%s started.' % __appname__) self.statusBar().show() @@ -1077,6 +1086,10 @@ def toggle_polygons(self, value): for item, shape in self.items_to_shapes.items(): item.setCheckState(Qt.Checked if value else Qt.Unchecked) + def toggle_vertices(self, value): + libs.shape.ENABLE_VERTICES = value + print(f'!!!!!!!!!!!!!!!!!! {libs.shape.ENABLE_VERTICES}') + def load_file(self, file_path=None): """Load the specified file, or the last opened file if None.""" self.reset_state() diff --git a/libs/canvas.py b/libs/canvas.py index 07a6025bf..aa40c1532 100644 --- a/libs/canvas.py +++ b/libs/canvas.py @@ -5,7 +5,7 @@ # from PyQt4.QtOpenGL import * - +from libs.constants import * from libs.shape import Shape from libs.utils import distance @@ -535,7 +535,7 @@ def paintEvent(self, event): p.drawRect(int(left_top.x()), int(left_top.y()), int(rect_width), int(rect_height)) 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.setPen(DRAWING_COLOR) 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())) @@ -546,7 +546,7 @@ def paintEvent(self, event): self.setPalette(pal) else: pal = self.palette() - pal.setColor(self.backgroundRole(), QColor(232, 232, 232, 255)) + pal.setColor(self.backgroundRole(), BACKGROUND_COLOR) self.setPalette(pal) p.end() diff --git a/libs/constants.py b/libs/constants.py index 1efda037c..2cd9c58dd 100644 --- a/libs/constants.py +++ b/libs/constants.py @@ -18,3 +18,13 @@ SETTING_DRAW_SQUARE = 'draw/square' SETTING_LABEL_FILE_FORMAT= 'labelFileFormat' DEFAULT_ENCODING = 'utf-8' + +# DEFINE COLORS +from PyQt5.QtGui import * +CLASS_COLOR_0 = QColor(0, 0, 255, 200) +DRAWING_COLOR = QColor(0, 0, 0) +BACKGROUND_COLOR = QColor(0, 0, 0, 200) + +HOVER_COLOR = QColor(106, 180, 255, 125) +VERTEX_FILL_COLOR = QColor(0, 0, 0, 0) + diff --git a/libs/shape.py b/libs/shape.py index a9b91d44b..539e7e5df 100644 --- a/libs/shape.py +++ b/libs/shape.py @@ -5,6 +5,7 @@ from PyQt5.QtCore import * from libs.utils import distance +from libs.constants import * import sys DEFAULT_LINE_COLOR = QColor(0, 255, 0, 128) @@ -13,6 +14,7 @@ DEFAULT_SELECT_FILL_COLOR = QColor(0, 128, 255, 155) DEFAULT_VERTEX_FILL_COLOR = QColor(59, 219, 255, 50) DEFAULT_HVERTEX_FILL_COLOR = QColor(255, 0, 0) +ENABLE_VERTICES = False class Shape(object): @@ -126,7 +128,8 @@ def paint(self, painter): painter.drawText(int(min_x), int(min_y), self.label) if self.fill: - color = self.select_fill_color if self.selected else self.fill_color + # color = self.select_fill_color if self.selected else self.fill_color + color = self.select_fill_color if self.selected else HOVER_COLOR painter.fillPath(line_path, color) def draw_vertex(self, path, i): @@ -138,14 +141,19 @@ def draw_vertex(self, path, i): d *= size if self._highlight_index is not None: self.vertex_fill_color = self.h_vertex_fill_color + if shape == self.P_SQUARE: + path.addRect(point.x() - d / 2, point.y() - d / 2, d, d) + elif shape == self.P_ROUND: + path.addEllipse(point, d / 2.0, d / 2.0) else: - self.vertex_fill_color = Shape.vertex_fill_color - if shape == self.P_SQUARE: - path.addRect(point.x() - d / 2, point.y() - d / 2, d, d) - elif shape == self.P_ROUND: - path.addEllipse(point, d / 2.0, d / 2.0) - else: - assert False, "unsupported vertex shape" + self.vertex_fill_color = VERTEX_FILL_COLOR + if ENABLE_VERTICES: + if shape == self.P_SQUARE: + path.addRect(point.x() - d / 2, point.y() - d / 2, d, d) + elif shape == self.P_ROUND: + path.addEllipse(point, d / 2.0, d / 2.0) + + def nearest_vertex(self, point, epsilon): index = None diff --git a/libs/stringBundle.py b/libs/stringBundle.py index c8877d66d..8ec3c7c36 100644 --- a/libs/stringBundle.py +++ b/libs/stringBundle.py @@ -11,13 +11,9 @@ import locale from libs.ustr import ustr -try: - from PyQt5.QtCore import * -except ImportError: - if sys.version_info.major >= 3: - import sip - sip.setapi('QVariant', 2) - from PyQt4.QtCore import * + +from PyQt5.QtCore import * + class StringBundle: diff --git a/libs/utils.py b/libs/utils.py index 21486b558..16bc737fa 100644 --- a/libs/utils.py +++ b/libs/utils.py @@ -3,22 +3,16 @@ import hashlib import re import sys +from libs.constants import * -try: - from PyQt5.QtGui import * - from PyQt5.QtCore import * - from PyQt5.QtWidgets import * - QT5 = True -except ImportError: - from PyQt4.QtGui import * - from PyQt4.QtCore import * - QT5 = False - +from PyQt5.QtGui import * +from PyQt5.QtCore import * +from PyQt5.QtWidgets import * +QT5 = True def new_icon(icon): return QIcon(':/' + icon) - def new_button(text, icon=None, slot=None): b = QPushButton(text) if icon is not None: @@ -27,7 +21,6 @@ def new_button(text, icon=None, slot=None): b.clicked.connect(slot) return b - 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.""" @@ -81,14 +74,12 @@ def format_shortcut(text): def generate_color_by_text(text): s = ustr(text) - print('generating color by text...') - print(f'{s} {type(s)}') 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) if text == '0': - color = QColor(255, 88, 59, 100) + color = CLASS_COLOR_0 else: color = QColor(r, g, b, 100) return color diff --git a/resources/strings/strings.properties b/resources/strings/strings.properties index 8c5d14ce8..409e259fc 100644 --- a/resources/strings/strings.properties +++ b/resources/strings/strings.properties @@ -37,6 +37,8 @@ editBox=&Edit RectBox editBoxDetail=Move and edit Boxs hideAllBox=&Hide RectBox showAllBox=&Show RectBox +hideAllVertices=&Hide Vertices +showAllVertices=&Show Vertices tutorialDefault=Tutorial tutorialChrome=Tutorial(Chrome) tutorialDetail=Show demo @@ -79,6 +81,8 @@ advancedMode=Advanced Mode advancedModeDetail=Swtich to advanced mode showAllBoxDetail=Show all bounding boxes hideAllBoxDetail=Hide all bounding boxes +showAllVerticesDetail=Show all vertices +hideAllVerticesDetail=Hide all vertices menu_file=&File menu_edit=&Edit menu_view=&View From ec7c8fb7f616abc565647a86a91805fcd92e05cc Mon Sep 17 00:00:00 2001 From: Joshua Kranabetter Date: Mon, 8 Aug 2022 10:02:09 -0600 Subject: [PATCH 3/7] Rename Readme --- JoshToDo.md => better_readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename JoshToDo.md => better_readme.md (75%) diff --git a/JoshToDo.md b/better_readme.md similarity index 75% rename from JoshToDo.md rename to better_readme.md index 6bf72392f..e1062f49c 100644 --- a/JoshToDo.md +++ b/better_readme.md @@ -8,7 +8,7 @@ pyrcc5 -o libs/resources.py resources.qrc ``` Then finally run: ``` - +labelImg.py ``` ## To Do @@ -18,5 +18,5 @@ Then finally run: - dark mode # Done -- Several custom colors in constants.py file -- toggle vertices in view tab \ No newline at end of file +- Several custom colors, changeable in constants.py file +- toggle vertices on/off in view tab \ No newline at end of file From eaeb59fd882d1b4d08f5372ae8e274d44b2f02f0 Mon Sep 17 00:00:00 2001 From: Joshua Kranabetter Date: Tue, 9 Aug 2022 17:13:12 -0600 Subject: [PATCH 4/7] Darken the Blue --- libs/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/constants.py b/libs/constants.py index 2cd9c58dd..0d0c6c23f 100644 --- a/libs/constants.py +++ b/libs/constants.py @@ -21,7 +21,7 @@ # DEFINE COLORS from PyQt5.QtGui import * -CLASS_COLOR_0 = QColor(0, 0, 255, 200) +CLASS_COLOR_0 = QColor(0, 0, 255, 255) DRAWING_COLOR = QColor(0, 0, 0) BACKGROUND_COLOR = QColor(0, 0, 0, 200) From 6aeed9feb5e9a456c52dc151d1b19c0b198b300b Mon Sep 17 00:00:00 2001 From: Joshua Kranabetter Date: Fri, 12 Aug 2022 15:50:20 -0600 Subject: [PATCH 5/7] Add todo/remove test print --- better_readme.md | 3 ++- labelImg.py | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/better_readme.md b/better_readme.md index e1062f49c..e91dce2a6 100644 --- a/better_readme.md +++ b/better_readme.md @@ -13,9 +13,10 @@ labelImg.py ## To Do - easy swap class colors -- hotkey to remove drag and click corner underneath - undo - dark mode +- Integrate Model +- Model outputs preview/generate # Done - Several custom colors, changeable in constants.py file diff --git a/labelImg.py b/labelImg.py index ef68e8074..c2711d4e2 100755 --- a/labelImg.py +++ b/labelImg.py @@ -1088,7 +1088,6 @@ def toggle_polygons(self, value): def toggle_vertices(self, value): libs.shape.ENABLE_VERTICES = value - print(f'!!!!!!!!!!!!!!!!!! {libs.shape.ENABLE_VERTICES}') def load_file(self, file_path=None): """Load the specified file, or the last opened file if None.""" From cbcfae31d4e720f276f3b466c55a7771a7e4f03f Mon Sep 17 00:00:00 2001 From: Joshua Kranabetter Date: Fri, 12 Aug 2022 17:28:48 -0600 Subject: [PATCH 6/7] Update better_readme.md --- better_readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/better_readme.md b/better_readme.md index e91dce2a6..9e7c4804d 100644 --- a/better_readme.md +++ b/better_readme.md @@ -17,6 +17,7 @@ labelImg.py - dark mode - Integrate Model - Model outputs preview/generate +- poly labelling # Done - Several custom colors, changeable in constants.py file From 988cb11455d3c12229994e53d45b934892bf26c8 Mon Sep 17 00:00:00 2001 From: Joshua Kranabetter Date: Tue, 23 Aug 2022 11:30:16 -0600 Subject: [PATCH 7/7] Add color for class 1 --- libs/constants.py | 1 + libs/utils.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/libs/constants.py b/libs/constants.py index 0d0c6c23f..d89d11924 100644 --- a/libs/constants.py +++ b/libs/constants.py @@ -22,6 +22,7 @@ # DEFINE COLORS from PyQt5.QtGui import * CLASS_COLOR_0 = QColor(0, 0, 255, 255) +CLASS_COLOR_1 = QColor(153, 51, 255, 255) DRAWING_COLOR = QColor(0, 0, 0) BACKGROUND_COLOR = QColor(0, 0, 0, 200) diff --git a/libs/utils.py b/libs/utils.py index 16bc737fa..e66194752 100644 --- a/libs/utils.py +++ b/libs/utils.py @@ -80,6 +80,8 @@ def generate_color_by_text(text): b = int((hash_code / 16581375) % 255) if text == '0': color = CLASS_COLOR_0 + if text == '1': + color = CLASS_COLOR_1 else: color = QColor(r, g, b, 100) return color