# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from qtpy import QtWidgets, QtGui, QtCore from qtpy.QtCore import Qt # Note, bbox annotation is more convenient than the default boundingBox generated by QGrpaphicItem class BBoxAnnotation(QtWidgets.QGraphicsPathItem): def __init__( self, labelIndex, polyline, borderColor=[0, 0, 255], cocoIndex=None, parent=None, ): super(BBoxAnnotation, self).__init__(parent) self.polyline = polyline self.corner_points = [] self.upper_right = QtCore.QPointF() self.bottom_left = QtCore.QPointF() self.w = -1.0 self.h = -1.0 self.parent = parent self.is_added = False if self.parent is not None: self.is_added = True self.labelIndex = labelIndex self.coco_id = cocoIndex self.bbox_hovering = True # set rendering attributes self.setZValue(10) # b = borderColor # self.borderColor = QtGui.QColor(b[0], b[1], b[2]) self.borderColor = QtGui.QColor(128, 128, 128) self.borderColor.setAlphaF(0.8) pen = QtGui.QPen(self.borderColor, 1.2) pen.setStyle(Qt.DashDotLine) self.setPen(pen) self.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable, False) self.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, False) self.setFlag(QtWidgets.QGraphicsItem.ItemSendsGeometryChanges, True) self.setFlag(QtWidgets.QGraphicsItem.ItemIsFocusable, False) self.setAcceptHoverEvents(False) # self.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) @property def scnenePoints(self): # return 4 corner points raise Exception("Not Implemented Yet!") def setAnning(self, isAnning=True): raise Exception("Not Implemented Yet!") def remove(self): raise Exception("Not Implemented Yet!") # ===== generate geometry info def create_corners(self): bbox_rect_geo = self.polyline.boundingRect() self.bottom_left = bbox_rect_geo.bottomLeft() self.upper_right = bbox_rect_geo.topRight() self.corner_points.clear() self.corner_points.extend([ self.bottom_left, bbox_rect_geo.topLeft(), self.upper_right, bbox_rect_geo.bottomRight(), ]) self.w = self.corner_points[3].x() - self.corner_points[1].x() self.h = self.corner_points[3].y() - self.corner_points[1].y() if self.corner_points[1].x() > 512 or self.corner_points[1].x( ) + self.w > 512: pass if self.corner_points[1].y() > 512 or self.corner_points[1].y( ) + self.h > 512: pass return self.corner_points def create_lines(self): pass # ===== graphic interface to update in scene tree def update(self): l = len(self.polyline.points) # print("up L:", l, " is_added:", self.is_added) if l < 3: if self.is_added: self.remove_from_scene() else: # 大于三个点就可以更新,小于三个点删除多边形 if self.is_added: self.add_to_scene() else: path_geo = QtGui.QPainterPath() self.create_corners() path_geo.moveTo(self.corner_points[0]) for i in range(4): path_geo.lineTo(self.corner_points[(i + 1) % 4]) self.setPath(QtGui.QPainterPath(path_geo)) pass pass pass def add_to_scene(self): # self.parentItem().scene().addItem(self) self.setParentItem(self.parent) self.is_added = True def remove_from_scene(self): # self.parentItem().scene().removeItem(self) self.setParentItem(None) self.is_added = False # ===== annotation info # @return : [x, y, w, h] def to_array(self): np_array = [ self._round(self.corner_points[1].x()), self._round(self.corner_points[1].y()), # topLeft self._round(self.w), self._round(self.h), ] return np_array def _round(self, number, ind=0): nint, ndec = str(number).split(".") res = float(nint + "." + ndec[:ind]) if res <= 0: res = 0.0 return res def __del__(self): self.corner_points.clear()