Apply PEP recommendation on formatting
Running pylint to make the code complient with PEP recommendations on lintage.
This commit is contained in:
+31
-28
@@ -13,12 +13,14 @@ from shape import Shape
|
||||
from lib import distance
|
||||
|
||||
CURSOR_DEFAULT = Qt.ArrowCursor
|
||||
CURSOR_POINT = Qt.PointingHandCursor
|
||||
CURSOR_DRAW = Qt.CrossCursor
|
||||
CURSOR_MOVE = Qt.ClosedHandCursor
|
||||
CURSOR_GRAB = Qt.OpenHandCursor
|
||||
CURSOR_POINT = Qt.PointingHandCursor
|
||||
CURSOR_DRAW = Qt.CrossCursor
|
||||
CURSOR_MOVE = Qt.ClosedHandCursor
|
||||
CURSOR_GRAB = Qt.OpenHandCursor
|
||||
|
||||
# class Canvas(QGLWidget):
|
||||
|
||||
|
||||
#class Canvas(QGLWidget):
|
||||
class Canvas(QWidget):
|
||||
zoomRequest = pyqtSignal(int)
|
||||
scrollRequest = pyqtSignal(int, int)
|
||||
@@ -37,8 +39,8 @@ class Canvas(QWidget):
|
||||
self.mode = self.EDIT
|
||||
self.shapes = []
|
||||
self.current = None
|
||||
self.selectedShape=None # save the selected shape here
|
||||
self.selectedShapeCopy=None
|
||||
self.selectedShape = None # save the selected shape here
|
||||
self.selectedShapeCopy = None
|
||||
self.lineColor = QColor(0, 0, 255)
|
||||
self.line = Shape(line_color=self.lineColor)
|
||||
self.prevPoint = QPointF()
|
||||
@@ -78,7 +80,7 @@ class Canvas(QWidget):
|
||||
|
||||
def setEditing(self, value=True):
|
||||
self.mode = self.EDIT if value else self.CREATE
|
||||
if not value: # Create
|
||||
if not value: # Create
|
||||
self.unHighlight()
|
||||
self.deSelectShape()
|
||||
|
||||
@@ -106,7 +108,8 @@ class Canvas(QWidget):
|
||||
# Project the point to the pixmap's edges.
|
||||
pos = self.intersectionPoint(self.current[-1], pos)
|
||||
elif len(self.current) > 1 and self.closeEnough(pos, self.current[0]):
|
||||
# Attract line to starting point and colorise to alert the user:
|
||||
# Attract line to starting point and colorise to alert the
|
||||
# user:
|
||||
pos = self.current[0]
|
||||
color = self.current.line_color
|
||||
self.overrideCursor(CURSOR_POINT)
|
||||
@@ -164,12 +167,13 @@ class Canvas(QWidget):
|
||||
if self.selectedVertex():
|
||||
self.hShape.highlightClear()
|
||||
self.hVertex, self.hShape = None, shape
|
||||
self.setToolTip("Click & drag to move shape '%s'" % shape.label)
|
||||
self.setToolTip(
|
||||
"Click & drag to move shape '%s'" % shape.label)
|
||||
self.setStatusTip(self.toolTip())
|
||||
self.overrideCursor(CURSOR_GRAB)
|
||||
self.update()
|
||||
break
|
||||
else: # Nothing found, clear highlights, reset state.
|
||||
else: # Nothing found, clear highlights, reset state.
|
||||
if self.hShape:
|
||||
self.hShape.highlightClear()
|
||||
self.update()
|
||||
@@ -270,7 +274,7 @@ class Canvas(QWidget):
|
||||
def selectShapePoint(self, point):
|
||||
"""Select the first shape created which contains this point."""
|
||||
self.deSelectShape()
|
||||
if self.selectedVertex(): # A vertex is marked for selection.
|
||||
if self.selectedVertex(): # A vertex is marked for selection.
|
||||
index, shape = self.hVertex, self.hShape
|
||||
shape.highlightVertex(index, shape.MOVE_VERTEX)
|
||||
return
|
||||
@@ -315,14 +319,14 @@ class Canvas(QWidget):
|
||||
|
||||
def boundedMoveShape(self, shape, pos):
|
||||
if self.outOfPixmap(pos):
|
||||
return False # No need to move
|
||||
return False # No need to move
|
||||
o1 = pos + self.offsets[0]
|
||||
if self.outOfPixmap(o1):
|
||||
pos -= QPointF(min(0, o1.x()), min(0, o1.y()))
|
||||
o2 = pos + self.offsets[1]
|
||||
if self.outOfPixmap(o2):
|
||||
pos += QPointF(min(0, self.pixmap.width() - o2.x()),
|
||||
min(0, self.pixmap.height()- o2.y()))
|
||||
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
|
||||
@@ -419,8 +423,8 @@ class Canvas(QWidget):
|
||||
area = super(Canvas, self).size()
|
||||
w, h = self.pixmap.width() * s, self.pixmap.height() * s
|
||||
aw, ah = area.width(), area.height()
|
||||
x = (aw-w)/(2*s) if aw > w else 0
|
||||
y = (ah-h)/(2*s) if ah > h else 0
|
||||
x = (aw - w) / (2 * s) if aw > w else 0
|
||||
y = (ah - h) / (2 * s) if ah > h else 0
|
||||
return QPointF(x, y)
|
||||
|
||||
def outOfPixmap(self, p):
|
||||
@@ -439,7 +443,7 @@ class Canvas(QWidget):
|
||||
def closeEnough(self, p1, p2):
|
||||
#d = distance(p1 - p2)
|
||||
#m = (p1-p2).manhattanLength()
|
||||
#print "d %.2f, m %d, %.2f" % (d, m, d - m)
|
||||
# print "d %.2f, m %d, %.2f" % (d, m, d - m)
|
||||
return distance(p1 - p2) < self.epsilon
|
||||
|
||||
def intersectionPoint(self, p1, p2):
|
||||
@@ -447,7 +451,7 @@ class Canvas(QWidget):
|
||||
# and find the one intersecting the current line segment.
|
||||
# http://paulbourke.net/geometry/lineline2d/
|
||||
size = self.pixmap.size()
|
||||
points = [(0,0),
|
||||
points = [(0, 0),
|
||||
(size.width(), 0),
|
||||
(size.width(), size.height()),
|
||||
(0, size.height())]
|
||||
@@ -455,12 +459,12 @@ class Canvas(QWidget):
|
||||
x2, y2 = p2.x(), p2.y()
|
||||
d, i, (x, y) = min(self.intersectingEdges((x1, y1), (x2, y2), points))
|
||||
x3, y3 = points[i]
|
||||
x4, y4 = points[(i+1)%4]
|
||||
x4, y4 = points[(i + 1) % 4]
|
||||
if (x, y) == (x1, y1):
|
||||
# Handle cases where previous point is on one of the edges.
|
||||
if x3 == x4:
|
||||
return QPointF(x3, min(max(0, y2), max(y3, y4)))
|
||||
else: # y3 == y4
|
||||
else: # y3 == y4
|
||||
return QPointF(min(max(0, x2), max(x3, x4)), y3)
|
||||
return QPointF(x, y)
|
||||
|
||||
@@ -473,10 +477,10 @@ class Canvas(QWidget):
|
||||
x2, y2 = x2y2
|
||||
for i in range(4):
|
||||
x3, y3 = points[i]
|
||||
x4, y4 = points[(i+1) % 4]
|
||||
denom = (y4-y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)
|
||||
nua = (x4-x3) * (y1-y3) - (y4-y3) * (x1-x3)
|
||||
nub = (x2-x1) * (y1-y3) - (y2-y1) * (x1-x3)
|
||||
x4, y4 = points[(i + 1) % 4]
|
||||
denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)
|
||||
nua = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)
|
||||
nub = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)
|
||||
if denom == 0:
|
||||
# This covers two cases:
|
||||
# nua == nub == 0: Coincident
|
||||
@@ -486,7 +490,7 @@ class Canvas(QWidget):
|
||||
if 0 <= ua <= 1 and 0 <= ub <= 1:
|
||||
x = x1 + ua * (x2 - x1)
|
||||
y = y1 + ua * (y2 - y1)
|
||||
m = QPointF((x3 + x4)/2, (y3 + y4)/2)
|
||||
m = QPointF((x3 + x4) / 2, (y3 + y4) / 2)
|
||||
d = distance(m - QPointF(x2, y2))
|
||||
yield d, i, (x, y)
|
||||
|
||||
@@ -507,8 +511,8 @@ class Canvas(QWidget):
|
||||
self.zoomRequest.emit(ev.delta())
|
||||
else:
|
||||
self.scrollRequest.emit(ev.delta(),
|
||||
Qt.Horizontal if (Qt.ShiftModifier == int(mods))\
|
||||
else Qt.Vertical)
|
||||
Qt.Horizontal if (Qt.ShiftModifier == int(mods))
|
||||
else Qt.Vertical)
|
||||
else:
|
||||
self.scrollRequest.emit(ev.delta(), Qt.Horizontal)
|
||||
ev.accept()
|
||||
@@ -571,4 +575,3 @@ class Canvas(QWidget):
|
||||
self.restoreCursor()
|
||||
self.pixmap = None
|
||||
self.update()
|
||||
|
||||
|
||||
+3
-2
@@ -8,13 +8,15 @@ except ImportError:
|
||||
|
||||
BB = QDialogButtonBox
|
||||
|
||||
|
||||
class ColorDialog(QColorDialog):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super(ColorDialog, self).__init__(parent)
|
||||
self.setOption(QColorDialog.ShowAlphaChannel)
|
||||
# The Mac native dialog does not support our restore button.
|
||||
self.setOption(QColorDialog.DontUseNativeDialog)
|
||||
## Add a restore defaults button.
|
||||
# Add a restore defaults button.
|
||||
# The default is set at invocation time, so that it
|
||||
# works across dialogs for different elements.
|
||||
self.default = None
|
||||
@@ -33,4 +35,3 @@ class ColorDialog(QColorDialog):
|
||||
def checkRestore(self, button):
|
||||
if self.bb.buttonRole(button) & BB.ResetRole and self.default:
|
||||
self.setCurrentColor(self.default)
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ from lib import newIcon, labelValidator
|
||||
|
||||
BB = QDialogButtonBox
|
||||
|
||||
|
||||
class LabelDialog(QDialog):
|
||||
|
||||
def __init__(self, text="Enter object label", parent=None, listItem=None):
|
||||
|
||||
+11
-8
@@ -11,9 +11,11 @@ from pascal_voc_io import PascalVocWriter
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
|
||||
class LabelFileError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class LabelFile(object):
|
||||
# It might be changed as window creates
|
||||
suffix = '.lif'
|
||||
@@ -26,7 +28,7 @@ class LabelFile(object):
|
||||
self.load(filename)
|
||||
|
||||
def savePascalVocFormat(self, filename, shapes, imagePath, imageData,
|
||||
lineColor=None, fillColor=None, databaseSrc=None):
|
||||
lineColor=None, fillColor=None, databaseSrc=None):
|
||||
imgFolderPath = os.path.dirname(imagePath)
|
||||
imgFolderName = os.path.split(imgFolderPath)[-1]
|
||||
imgFileName = os.path.basename(imagePath)
|
||||
@@ -35,8 +37,9 @@ class LabelFile(object):
|
||||
# Pascal format
|
||||
image = QImage()
|
||||
image.load(imagePath)
|
||||
imageShape = [image.height(), image.width(), 1 if image.isGrayscale() else 3]
|
||||
writer = PascalVocWriter(imgFolderName, imgFileNameWithoutExt,\
|
||||
imageShape = [image.height(), image.width(),
|
||||
1 if image.isGrayscale() else 3]
|
||||
writer = PascalVocWriter(imgFolderName, imgFileNameWithoutExt,
|
||||
imageShape, localImgPath=imagePath)
|
||||
bSave = False
|
||||
for shape in shapes:
|
||||
@@ -47,7 +50,7 @@ class LabelFile(object):
|
||||
bSave = True
|
||||
|
||||
if bSave:
|
||||
writer.save(targetFile = filename)
|
||||
writer.save(targetFile=filename)
|
||||
return
|
||||
|
||||
@staticmethod
|
||||
@@ -64,10 +67,10 @@ class LabelFile(object):
|
||||
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)
|
||||
xmin = min(x, xmin)
|
||||
ymin = min(y, ymin)
|
||||
xmax = max(x, xmax)
|
||||
ymax = max(y, ymax)
|
||||
|
||||
# Martin Kersner, 2015/11/12
|
||||
# 0-valued coordinates of BB caused an error while
|
||||
|
||||
+7
-2
@@ -12,6 +12,7 @@ except ImportError:
|
||||
def newIcon(icon):
|
||||
return QIcon(':/' + icon)
|
||||
|
||||
|
||||
def newButton(text, icon=None, slot=None):
|
||||
b = QPushButton(text)
|
||||
if icon is not None:
|
||||
@@ -20,8 +21,9 @@ def newButton(text, icon=None, slot=None):
|
||||
b.clicked.connect(slot)
|
||||
return b
|
||||
|
||||
|
||||
def newAction(parent, text, slot=None, shortcut=None, icon=None,
|
||||
tip=None, checkable=False, enabled=True):
|
||||
tip=None, checkable=False, enabled=True):
|
||||
"""Create a new action and assign callbacks, shortcuts, etc."""
|
||||
a = QAction(text, parent)
|
||||
if icon is not None:
|
||||
@@ -51,18 +53,21 @@ def addActions(widget, actions):
|
||||
else:
|
||||
widget.addAction(action)
|
||||
|
||||
|
||||
def labelValidator():
|
||||
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())
|
||||
|
||||
|
||||
def fmtShortcut(text):
|
||||
mod, key = text.split('+', 1)
|
||||
return '<b>%s</b>+<b>%s</b>' % (mod, key)
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import codecs
|
||||
|
||||
XML_EXT = '.xml'
|
||||
|
||||
|
||||
class PascalVocWriter:
|
||||
|
||||
def __init__(self, foldername, filename, imgSize, databaseSrc='Unknown', localImgPath=None):
|
||||
@@ -102,7 +103,8 @@ class PascalVocWriter:
|
||||
self.appendObjects(root)
|
||||
out_file = None
|
||||
if targetFile is None:
|
||||
out_file = codecs.open(self.filename + XML_EXT, 'w', encoding='utf-8')
|
||||
out_file = codecs.open(
|
||||
self.filename + XML_EXT, 'w', encoding='utf-8')
|
||||
else:
|
||||
out_file = codecs.open(targetFile, 'w', encoding='utf-8')
|
||||
|
||||
|
||||
+9
-9
@@ -18,13 +18,14 @@ DEFAULT_SELECT_FILL_COLOR = QColor(0, 128, 255, 155)
|
||||
DEFAULT_VERTEX_FILL_COLOR = QColor(0, 255, 0, 255)
|
||||
DEFAULT_HVERTEX_FILL_COLOR = QColor(255, 0, 0)
|
||||
|
||||
|
||||
class Shape(object):
|
||||
P_SQUARE, P_ROUND = range(2)
|
||||
|
||||
MOVE_VERTEX, NEAR_VERTEX = range(2)
|
||||
|
||||
## The following class variables influence the drawing
|
||||
## of _all_ shape objects.
|
||||
# The following class variables influence the drawing
|
||||
# of _all_ shape objects.
|
||||
line_color = DEFAULT_LINE_COLOR
|
||||
fill_color = DEFAULT_FILL_COLOR
|
||||
select_line_color = DEFAULT_SELECT_LINE_COLOR
|
||||
@@ -46,7 +47,7 @@ class Shape(object):
|
||||
self._highlightSettings = {
|
||||
self.NEAR_VERTEX: (4, self.P_ROUND),
|
||||
self.MOVE_VERTEX: (1.5, self.P_SQUARE),
|
||||
}
|
||||
}
|
||||
|
||||
self._closed = False
|
||||
|
||||
@@ -61,7 +62,7 @@ class Shape(object):
|
||||
self._closed = True
|
||||
|
||||
def reachMaxPoints(self):
|
||||
if len(self.points) >=4:
|
||||
if len(self.points) >= 4:
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -124,9 +125,9 @@ class Shape(object):
|
||||
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)
|
||||
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)
|
||||
path.addEllipse(point, d / 2.0, d / 2.0)
|
||||
else:
|
||||
assert False, "unsupported vertex shape"
|
||||
|
||||
@@ -162,8 +163,8 @@ class Shape(object):
|
||||
self._highlightIndex = None
|
||||
|
||||
def copy(self):
|
||||
shape = Shape("Copy of %s" % self.label )
|
||||
shape.points= [p for p in self.points]
|
||||
shape = Shape("Copy of %s" % self.label)
|
||||
shape.points = [p for p in self.points]
|
||||
shape.fill = self.fill
|
||||
shape.selected = self.selected
|
||||
shape._closed = self._closed
|
||||
@@ -181,4 +182,3 @@ class Shape(object):
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
self.points[key] = value
|
||||
|
||||
|
||||
+2
-1
@@ -8,6 +8,7 @@ except ImportError:
|
||||
|
||||
|
||||
class ToolBar(QToolBar):
|
||||
|
||||
def __init__(self, title):
|
||||
super(ToolBar, self).__init__(title)
|
||||
layout = self.layout()
|
||||
@@ -29,10 +30,10 @@ class ToolBar(QToolBar):
|
||||
class ToolButton(QToolButton):
|
||||
"""ToolBar companion class which ensures all buttons have the same size."""
|
||||
minSize = (60, 60)
|
||||
|
||||
def minimumSizeHint(self):
|
||||
ms = super(ToolButton, self).minimumSizeHint()
|
||||
w1, h1 = ms.width(), ms.height()
|
||||
w2, h2 = self.minSize
|
||||
ToolButton.minSize = max(w1, w2), max(h1, h2)
|
||||
return QSize(*ToolButton.minSize)
|
||||
|
||||
|
||||
+2
-1
@@ -6,7 +6,9 @@ except ImportError:
|
||||
from PyQt4.QtGui import *
|
||||
from PyQt4.QtCore import *
|
||||
|
||||
|
||||
class ZoomWidget(QSpinBox):
|
||||
|
||||
def __init__(self, value=100):
|
||||
super(ZoomWidget, self).__init__()
|
||||
self.setButtonSymbols(QAbstractSpinBox.NoButtons)
|
||||
@@ -22,4 +24,3 @@ class ZoomWidget(QSpinBox):
|
||||
fm = QFontMetrics(self.font())
|
||||
width = fm.width(str(self.maximum()))
|
||||
return QSize(width, height)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user