From ee04f9f994e5cb73a917650af494015c73351cde Mon Sep 17 00:00:00 2001 From: txh0001 Date: Mon, 2 Sep 2024 13:21:42 +0800 Subject: [PATCH 1/4] Update default_config.yaml add selrectangle tag --- labelme/config/default_config.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/labelme/config/default_config.yaml b/labelme/config/default_config.yaml index 128dc6d6a..5cd3edd0c 100644 --- a/labelme/config/default_config.yaml +++ b/labelme/config/default_config.yaml @@ -81,6 +81,7 @@ canvas: linestrip: false ai_polygon: false ai_mask: false + selrectangle: false shortcuts: close: Ctrl+W @@ -118,6 +119,7 @@ shortcuts: edit_label: Ctrl+E toggle_keep_prev_mode: Ctrl+P remove_selected_point: [Meta+H, Backspace] + rectangle_select: null show_all_polygons: null hide_all_polygons: null From d3bee7d28ab9df685b46a1f5df4b05c2d27b6ef2 Mon Sep 17 00:00:00 2001 From: txh0001 Date: Mon, 2 Sep 2024 13:22:22 +0800 Subject: [PATCH 2/4] Update canvas.py --- labelme/widgets/canvas.py | 47 ++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/labelme/widgets/canvas.py b/labelme/widgets/canvas.py index a78f073d3..caf95cabb 100644 --- a/labelme/widgets/canvas.py +++ b/labelme/widgets/canvas.py @@ -58,6 +58,7 @@ def __init__(self, *args, **kwargs): "linestrip": False, "ai_polygon": False, "ai_mask": False, + "selrectangle": False }, ) super(Canvas, self).__init__(*args, **kwargs) @@ -124,6 +125,7 @@ def createMode(self, value): "linestrip", "ai_polygon", "ai_mask", + "selrectangle" ]: raise ValueError("Unsupported createMode: %s" % value) self._createMode = value @@ -282,6 +284,10 @@ def mouseMoveEvent(self, ev): self.line.points = [self.current[0], pos] self.line.point_labels = [1, 1] self.line.close() + elif self.createMode == "selrectangle": + self.line.points = [self.current[0], pos] + self.line.point_labels = [1, 1] + self.line.close() elif self.createMode == "circle": self.line.points = [self.current[0], pos] self.line.point_labels = [1, 1] @@ -418,7 +424,7 @@ def mousePressEvent(self, ev): self.line[0] = self.current[-1] if self.current.isClosed(): self.finalise() - elif self.createMode in ["rectangle", "circle", "line"]: + elif self.createMode in ["rectangle", "circle", "line","selrectangle"]: assert len(self.current.points) == 1 self.current.points = self.line.points self.finalise() @@ -835,11 +841,40 @@ def finalise(self): ) self.current.close() - self.shapes.append(self.current) - self.storeShapes() - self.current = None - self.setHiding(False) - self.newShape.emit() + # self.shapes.append(self.current) + # self.storeShapes() + # self.current = None + # self.setHiding(False) + # self.newShape.emit() + if self.createMode != "selrectangle": # do not store shape,because it is not a real shape + self.shapes.append(self.current) + self.storeShapes() + self.current = None + self.setHiding(False) + self.newShape.emit() + else: + + x1 = self.current.points[0].x() + y1 = self.current.points[0].y() + x2 = self.current.points[1].x() + y2 = self.current.points[1].y() + xMax = max([x1, x2]) + yMax = max([y1, y2]) + xMin = min([x1, x2]) + yMin = min([y1, y2]) + + for shape in self.shapes: + if shape is None: continue + for pnt in shape.points: + if xMax >= pnt.x() >= xMin and yMax >= pnt.y() >= yMin: + shape.selected = True + self.selectedShapes.append(shape) + break + + self.current = None # clear current shape + self.selectionChanged.emit(self.selectedShapes) + self.setEditing(True) + self.update() def closeEnough(self, p1, p2): From 843f57b88728f4cf390f0e595557f25ac489181f Mon Sep 17 00:00:00 2001 From: txh0001 Date: Mon, 2 Sep 2024 13:22:44 +0800 Subject: [PATCH 3/4] Update shape.py --- labelme/shape.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/labelme/shape.py b/labelme/shape.py index 0f1fd9fdb..6e4acb3dd 100644 --- a/labelme/shape.py +++ b/labelme/shape.py @@ -111,6 +111,7 @@ def shape_type(self, value): "linestrip", "points", "mask", + "selrectangle" ]: raise ValueError("Unexpected shape_type: {}".format(value)) self._shape_type = value @@ -217,7 +218,7 @@ def paint(self, painter): vrtx_path = QtGui.QPainterPath() negative_vrtx_path = QtGui.QPainterPath() - if self.shape_type in ["rectangle", "mask"]: + if self.shape_type in ["rectangle", "mask","selrectangle"]: assert len(self.points) in [1, 2] if len(self.points) == 2: rectangle = QtCore.QRectF( @@ -228,6 +229,9 @@ def paint(self, painter): if self.shape_type == "rectangle": for i in range(len(self.points)): self.drawVertex(vrtx_path, i) + if self.shape_type == "selrectangle": + for i in range(len(self.points)): + self.drawVertex(vrtx_path, i) elif self.shape_type == "circle": assert len(self.points) in [1, 2] if len(self.points) == 2: From 7c826e369396209cbe5b49d7b25080dd55bf6788 Mon Sep 17 00:00:00 2001 From: txh0001 Date: Mon, 2 Sep 2024 13:23:05 +0800 Subject: [PATCH 4/4] Update app.py --- labelme/app.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/labelme/app.py b/labelme/app.py index 7bbce4936..e236dd493 100644 --- a/labelme/app.py +++ b/labelme/app.py @@ -334,6 +334,14 @@ def __init__( self.tr("Start drawing rectangles"), enabled=False, ) + rectangleSelectMode = action( + self.tr("Rectangle Select"), + lambda: self.toggleDrawMode(False, createMode="selrectangle"), + shortcuts["rectangle_select"], + "objects", + self.tr("Start selecting rectangles"), + enabled=False, + ) createCircleMode = action( self.tr("Create Circle"), lambda: self.toggleDrawMode(False, createMode="circle"), @@ -643,6 +651,7 @@ def __init__( createMode=createMode, editMode=editMode, createRectangleMode=createRectangleMode, + rectangleSelectMode=rectangleSelectMode, createCircleMode=createCircleMode, createLineMode=createLineMode, createPointMode=createPointMode, @@ -681,6 +690,7 @@ def __init__( menu=( createMode, createRectangleMode, + rectangleSelectMode, createCircleMode, createLineMode, createPointMode, @@ -976,6 +986,7 @@ def setClean(self): self.actions.createLineStripMode.setEnabled(True) self.actions.createAiPolygonMode.setEnabled(True) self.actions.createAiMaskMode.setEnabled(True) + self.actions.createRectangleMode.setEnabled(True) title = __appname__ if self.filename is not None: title = "{} - {}".format(title, self.filename) @@ -1107,6 +1118,7 @@ def toggleDrawMode(self, edit=True, createMode="polygon"): draw_actions = { "polygon": self.actions.createMode, "rectangle": self.actions.createRectangleMode, + "selrectangle": self.actions.rectangleSelectMode, "circle": self.actions.createCircleMode, "point": self.actions.createPointMode, "line": self.actions.createLineMode, @@ -1123,6 +1135,7 @@ def toggleDrawMode(self, edit=True, createMode="polygon"): else: for draw_mode, draw_action in draw_actions.items(): draw_action.setEnabled(createMode != draw_mode) + self.actions.rectangleSelectMode.setEnabled(True) self.actions.editMode.setEnabled(not edit) def setEditMode(self):