mirror of
https://github.com/PaddlePaddle/PaddleOCR.git
synced 2025-12-28 15:38:18 +00:00
[New feature]: label box can rotate by using short cut 'x' or 'c', but only support rotate one box at the same time
This commit is contained in:
parent
07530794f6
commit
3dca523120
@ -849,7 +849,7 @@ class MainWindow(QMainWindow):
|
||||
|
||||
box = ast.literal_eval(item.text())
|
||||
# print('shape in labelItemChanged is',shape.points)
|
||||
if box != [(p.x(), p.y()) for p in shape.points]:
|
||||
if box != [(int(p.x()), int(p.y())) for p in shape.points]:
|
||||
# shape.points = box
|
||||
shape.points = [QPointF(p[0], p[1]) for p in box]
|
||||
|
||||
|
||||
@ -11,19 +11,13 @@
|
||||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
try:
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtWidgets import *
|
||||
except ImportError:
|
||||
from PyQt4.QtGui import *
|
||||
from PyQt4.QtCore import *
|
||||
|
||||
#from PyQt4.QtOpenGL import *
|
||||
import copy
|
||||
|
||||
from PyQt5.QtCore import Qt, pyqtSignal, QPointF, QPoint
|
||||
from PyQt5.QtGui import QPainter, QBrush, QColor, QPixmap
|
||||
from PyQt5.QtWidgets import QWidget, QMenu, QApplication
|
||||
from libs.shape import Shape
|
||||
from libs.utils import distance
|
||||
import copy
|
||||
|
||||
CURSOR_DEFAULT = Qt.ArrowCursor
|
||||
CURSOR_POINT = Qt.PointingHandCursor
|
||||
@ -31,8 +25,6 @@ CURSOR_DRAW = Qt.CrossCursor
|
||||
CURSOR_MOVE = Qt.ClosedHandCursor
|
||||
CURSOR_GRAB = Qt.OpenHandCursor
|
||||
|
||||
# class Canvas(QGLWidget):
|
||||
|
||||
|
||||
class Canvas(QWidget):
|
||||
zoomRequest = pyqtSignal(int)
|
||||
@ -129,7 +121,6 @@ class Canvas(QWidget):
|
||||
def selectedVertex(self):
|
||||
return self.hVertex is not None
|
||||
|
||||
|
||||
def mouseMoveEvent(self, ev):
|
||||
"""Update line with last point and current coordinates."""
|
||||
pos = self.transformPos(ev.pos())
|
||||
@ -333,7 +324,6 @@ class Canvas(QWidget):
|
||||
|
||||
self.movingShape = False
|
||||
|
||||
|
||||
def endMove(self, copy=False):
|
||||
assert self.selectedShapes and self.selectedShapesCopy
|
||||
assert len(self.selectedShapesCopy) == len(self.selectedShapes)
|
||||
@ -410,7 +400,6 @@ class Canvas(QWidget):
|
||||
self.selectionChanged.emit(shapes)
|
||||
self.update()
|
||||
|
||||
|
||||
def selectShapePoint(self, point, multiple_selection_mode):
|
||||
"""Select the first shape created which contains this point."""
|
||||
if self.selectedVertex(): # A vertex is marked for selection.
|
||||
@ -494,7 +483,6 @@ class Canvas(QWidget):
|
||||
else:
|
||||
shape.moveVertexBy(index, shiftPos)
|
||||
|
||||
|
||||
def boundedMoveShape(self, shapes, pos):
|
||||
if type(shapes).__name__ != 'list': shapes = [shapes]
|
||||
if self.outOfPixmap(pos):
|
||||
@ -515,6 +503,7 @@ class Canvas(QWidget):
|
||||
if dp:
|
||||
for shape in shapes:
|
||||
shape.moveBy(dp)
|
||||
shape.close()
|
||||
self.prevPoint = pos
|
||||
return True
|
||||
return False
|
||||
@ -728,6 +717,31 @@ class Canvas(QWidget):
|
||||
self.moveOnePixel('Up')
|
||||
elif key == Qt.Key_Down and self.selectedShapes:
|
||||
self.moveOnePixel('Down')
|
||||
elif key == Qt.Key_X and self.selectedShapes:
|
||||
for i in range(len(self.selectedShapes)):
|
||||
self.selectedShape = self.selectedShapes[i]
|
||||
if self.rotateOutOfBound(0.01):
|
||||
continue
|
||||
self.selectedShape.rotate(0.01)
|
||||
self.shapeMoved.emit()
|
||||
self.update()
|
||||
|
||||
elif key == Qt.Key_C and self.selectedShapes:
|
||||
for i in range(len(self.selectedShapes)):
|
||||
self.selectedShape = self.selectedShapes[i]
|
||||
if self.rotateOutOfBound(-0.01):
|
||||
continue
|
||||
self.selectedShape.rotate(-0.01)
|
||||
self.shapeMoved.emit()
|
||||
self.update()
|
||||
|
||||
def rotateOutOfBound(self, angle):
|
||||
for shape in range(len(self.selectedShapes)):
|
||||
self.selectedShape = self.selectedShapes[shape]
|
||||
for i, p in enumerate(self.selectedShape.points):
|
||||
if self.outOfPixmap(self.selectedShape.rotatePoint(p, angle)):
|
||||
return True
|
||||
return False
|
||||
|
||||
def moveOnePixel(self, direction):
|
||||
# print(self.selectedShape.points)
|
||||
|
||||
@ -10,20 +10,15 @@
|
||||
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
#!/usr/bin/python
|
||||
# !/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 libs.utils import distance
|
||||
import math
|
||||
import sys
|
||||
|
||||
from PyQt5.QtCore import QPointF
|
||||
from PyQt5.QtGui import QColor, QPen, QPainterPath, QFont
|
||||
from libs.utils import distance
|
||||
|
||||
DEFAULT_LINE_COLOR = QColor(0, 255, 0, 128)
|
||||
DEFAULT_FILL_COLOR = QColor(255, 0, 0, 128)
|
||||
DEFAULT_SELECT_LINE_COLOR = QColor(255, 255, 255)
|
||||
@ -59,6 +54,8 @@ class Shape(object):
|
||||
self.difficult = difficult
|
||||
self.paintLabel = paintLabel
|
||||
self.locked = False
|
||||
self.direction = 0
|
||||
self.center = None
|
||||
self._highlightIndex = None
|
||||
self._highlightMode = self.NEAR_VERTEX
|
||||
self._highlightSettings = {
|
||||
@ -74,7 +71,24 @@ class Shape(object):
|
||||
# is used for drawing the pending line a different color.
|
||||
self.line_color = line_color
|
||||
|
||||
def rotate(self, theta):
|
||||
for i, p in enumerate(self.points):
|
||||
self.points[i] = self.rotatePoint(p, theta)
|
||||
self.direction -= theta
|
||||
self.direction = self.direction % (2 * math.pi)
|
||||
|
||||
def rotatePoint(self, p, theta):
|
||||
order = p - self.center
|
||||
cosTheta = math.cos(theta)
|
||||
sinTheta = math.sin(theta)
|
||||
pResx = cosTheta * order.x() + sinTheta * order.y()
|
||||
pResy = - sinTheta * order.x() + cosTheta * order.y()
|
||||
pRes = QPointF(self.center.x() + pResx, self.center.y() + pResy)
|
||||
return pRes
|
||||
|
||||
def close(self):
|
||||
self.center = QPointF((self.points[0].x() + self.points[2].x()) / 2,
|
||||
(self.points[0].y() + self.points[2].y()) / 2)
|
||||
self._closed = True
|
||||
|
||||
def reachMaxPoints(self):
|
||||
@ -83,7 +97,9 @@ class Shape(object):
|
||||
return False
|
||||
|
||||
def addPoint(self, point):
|
||||
if not self.reachMaxPoints(): # 4个点时发出close信号
|
||||
if self.reachMaxPoints():
|
||||
self.close()
|
||||
else:
|
||||
self.points.append(point)
|
||||
|
||||
def popPoint(self):
|
||||
@ -112,7 +128,7 @@ class Shape(object):
|
||||
# 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(vrtx_path, 0)
|
||||
|
||||
for i, p in enumerate(self.points):
|
||||
line_path.lineTo(p)
|
||||
@ -136,9 +152,9 @@ class Shape(object):
|
||||
font.setPointSize(8)
|
||||
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)
|
||||
|
||||
@ -198,6 +214,8 @@ class Shape(object):
|
||||
def copy(self):
|
||||
shape = Shape("%s" % self.label)
|
||||
shape.points = [p for p in self.points]
|
||||
shape.center = self.center
|
||||
shape.direction = self.direction
|
||||
shape.fill = self.fill
|
||||
shape.selected = self.selected
|
||||
shape._closed = self._closed
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user