From a1d1c3a9c057e24e4fc2ea69a71e1d97ff3bbbaf Mon Sep 17 00:00:00 2001 From: philokey Date: Mon, 14 Mar 2016 09:51:41 +0800 Subject: [PATCH 1/6] update --- Athena/.idea/workspace.xml | 131 +++++++++++++++++++------------------ Athena/athena.py | 1 - 2 files changed, 68 insertions(+), 64 deletions(-) diff --git a/Athena/.idea/workspace.xml b/Athena/.idea/workspace.xml index 6ad3f9f..39c22ec 100644 --- a/Athena/.idea/workspace.xml +++ b/Athena/.idea/workspace.xml @@ -2,7 +2,6 @@ - @@ -21,7 +20,7 @@ - + - + - + - - + + @@ -524,7 +529,8 @@ - @@ -562,11 +568,11 @@ - - - - - + + + + + @@ -617,11 +623,11 @@ - - - - - + + + + + @@ -672,11 +678,11 @@ - - - - - + + + + + @@ -727,11 +733,11 @@ - - - - - + + + + + @@ -772,11 +778,11 @@ - - - - - + + + + + @@ -817,11 +823,11 @@ - - - - - + + + + + @@ -862,11 +868,11 @@ - - - - - + + + + + @@ -897,11 +903,11 @@ - - - - - + + + + + @@ -1016,7 +1022,6 @@ - @@ -1051,15 +1056,15 @@ - - + + - - - - - + + + + + diff --git a/Athena/athena.py b/Athena/athena.py index ae4df76..da25d97 100644 --- a/Athena/athena.py +++ b/Athena/athena.py @@ -25,7 +25,6 @@ def __init__(self): self.settings = QtCore.QSettings('setting.ini', QtCore.QSettings.IniFormat) # 读入路径 self.imageFolder = self.showFileDialog() - # print(self.imageFolder,"............") # self.imageFolder = '/Users/philokey/Comic' #调试方便 # 屏幕居中 From 0dcb191f3a92a411dec799d106026253b8ae40b6 Mon Sep 17 00:00:00 2001 From: philokey Date: Mon, 14 Mar 2016 20:07:31 +0800 Subject: [PATCH 2/6] circle --- Athena/.idea/workspace.xml | 174 ++++++++++++++--------------------- Athena/athena.py | 97 +------------------- Athena/imageContainer.py | 182 +++++++++++++++---------------------- 3 files changed, 145 insertions(+), 308 deletions(-) diff --git a/Athena/.idea/workspace.xml b/Athena/.idea/workspace.xml index 39c22ec..64e603e 100644 --- a/Athena/.idea/workspace.xml +++ b/Athena/.idea/workspace.xml @@ -4,6 +4,7 @@ + @@ -20,7 +21,7 @@ - + - + - - + + - - - - - + + + - + - - + + - - - @@ -96,6 +92,11 @@ @@ -487,32 +488,38 @@ - + - + + + + - - - @@ -530,11 +537,12 @@ - - @@ -545,9 +553,6 @@ - - - @@ -568,11 +573,9 @@ - - - - - + + + @@ -600,9 +603,6 @@ - - - @@ -623,11 +623,9 @@ - - - - - + + + @@ -655,9 +653,6 @@ - - - @@ -678,11 +673,9 @@ - - - - - + + + @@ -710,9 +703,6 @@ - - - @@ -733,11 +723,9 @@ - - - - - + + + @@ -755,9 +743,6 @@ - - - @@ -778,11 +763,9 @@ - - - - - + + + @@ -800,9 +783,6 @@ - - - @@ -823,11 +803,9 @@ - - - - - + + + @@ -845,9 +823,6 @@ - - - @@ -868,11 +843,9 @@ - - - - - + + + @@ -890,9 +863,6 @@ - - - @@ -903,11 +873,9 @@ - - - - - + + + @@ -925,9 +893,6 @@ - - - @@ -1041,30 +1006,25 @@ - + - - + + - - - - + + + + - + - - + + - - - - - - + diff --git a/Athena/athena.py b/Athena/athena.py index da25d97..760ffb6 100644 --- a/Athena/athena.py +++ b/Athena/athena.py @@ -24,8 +24,8 @@ def __init__(self): self.settings = QtCore.QSettings('setting.ini', QtCore.QSettings.IniFormat) # 读入路径 - self.imageFolder = self.showFileDialog() - # self.imageFolder = '/Users/philokey/Comic' #调试方便 + # self.imageFolder = self.showFileDialog() + self.imageFolder = '/Users/philokey/Comic' #调试方便 # 屏幕居中 self.screen = QtWidgets.QDesktopWidget().screenGeometry() @@ -107,25 +107,10 @@ def initButton(self): slGroup.addButton(self.larRad) buttonLayout.addLayout(slButtonLayout) - - # radio group - fbGroup = QtWidgets.QButtonGroup(self) - fbradButtonLayout = QtWidgets.QHBoxLayout() - self.frameRad = QtWidgets.QRadioButton("Frame") - self.frameRad.clicked.connect(self.clickFrameRad) - self.ballRad = QtWidgets.QRadioButton("Balloon") - self.ballRad.clicked.connect(self.clickBallRad) - self.frameRad.setChecked(True) - fbradButtonLayout.addWidget(self.frameRad) - fbradButtonLayout.addWidget(self.ballRad) - fbGroup.addButton(self.frameRad) - fbGroup.addButton(self.ballRad) - buttonLayout.addLayout(fbradButtonLayout) - # box shape rpGroup = QtWidgets.QButtonGroup(self) rpradButtonLayout = QtWidgets.QHBoxLayout() - self.recRad = QtWidgets.QRadioButton("Rectangle") + self.recRad = QtWidgets.QRadioButton("Circle") self.recRad.clicked.connect(self.clickRecRad) self.recRad.setChecked(True) self.polyRad = QtWidgets.QRadioButton("Polygon") @@ -136,24 +121,6 @@ def initButton(self): rpGroup.addButton(self.polyRad) buttonLayout.addLayout(rpradButtonLayout) - # checkBox - self.confusedCheckBox = QtWidgets.QCheckBox("Confused") - self.confusedCheckBox.clicked.connect(self.clickConfusedCheckBox) - buttonLayout.addWidget(self.confusedCheckBox) - - # detect - self.detectOfflineBox = QtWidgets.QCheckBox("Detect Offline") - # self.detectModeBox.clicked.connect(self.clickDetectModeBox) - buttonLayout.addWidget(self.detectOfflineBox) - - decLayout = QtWidgets.QVBoxLayout() - self.detectBtn = QtWidgets.QPushButton('Auto Detect') - self.detectBtn.clicked.connect(self.clickDetectBtn) - decLayout.addWidget(self.detectBtn) - self.dectState = QtWidgets.QLabel('') - self.dectState.setMaximumHeight(10) - decLayout.addWidget(self.dectState) - buttonLayout.addLayout(decLayout) self.deleteBtn = QtWidgets.QPushButton('Delete') self.deleteBtn.clicked.connect(self.clickDeleteBtnBtn) @@ -192,66 +159,18 @@ def clickLarRad(self): self.imageContainer.isLarge = True self.imageContainer.loadImage(self.imageContainer.imagePath) - def clickFrameRad(self): - self.imageContainer.type = 0 - - def clickBallRad(self): - self.imageContainer.type = 1 - def clickRecRad(self): self.imageContainer.boxShape = 0 def clickPolyRad(self): self.imageContainer.boxShape = 1 - def clickConfusedCheckBox(self): - if self.confusedCheckBox.isChecked(): - self.imageContainer.isConfused = True - else: - self.imageContainer.isConfused = False - def clickClearBtn(self): self.imageContainer.clearImage() def clickReloadBtn(self): self.imageContainer.loadImage(self.imageContainer.imagePath) - def clickDetectBtn(self): - if self.imageContainer.imagePath == '': - print("Where is image?") - return - exeDir = osp.join(os.getcwd(), 'Storyboard') - if self.detectOfflineBox.isChecked(): - if osp.isfile(exeDir): - print("local") - self.dectState.setText("detecting...") - self.repaint() - resultDir, resultName = self.imageContainer.getOutputFileName(0) # 0 is frame - fullPath = os.path.join(resultDir, resultName) - # print(exeDir+' ' + self.imageContainer.imagePath + ' ' + fullPath) - subprocess.run([exeDir, self.imageContainer.imagePath, fullPath]) - # os.system(exeDir+' ' + self.imageContainer.imagePath + ' ' + fullPath) - text = open(fullPath).read() - self.dectState.setText("") - else: - QtWidgets.QMessageBox.critical(self, "Error", "Local detecting program is NOT FOUND!") - return - else: - url = 'http://10.1.89.8:8080/' - img = {'file':open(self.imageContainer.imagePath, 'rb')} - self.dectState.setText("detecting...") - self.repaint() - try: - # print(url) - r = requests.post(url, files=img) - except: - QtWidgets.QMessageBox.critical(self, "Error", "Failed to establish connection.") - return - text = r.text - self.repaint() - self.imageContainer.parseDetectedResult(text, 0) - self.imageContainer.paintTotalResult() - self.imageContainer.isModified = True def clickDeleteBtnBtn(self): tp = self.imageContainer.type @@ -279,20 +198,12 @@ def clickPreBtn(self): def dirTreeClicked(self): #获取选择的路径 pathSelected = self.dirModel.filePath(self.dirTreeView.selectedIndexes()[0]) + self.imageContainer.setMinimumWidth(self.geometry().width()*0.6) if os.path.isfile(pathSelected) and pathSelected.split('.')[-1].lower() in FILE_TYPE: - self.confusedCheckBox.setChecked(False) self.imageContainer.loadImage(pathSelected) resultDir, r0 = self.imageContainer.getOutputFileName(0) resultDir, r1 = self.imageContainer.getOutputFileName(1) - if not os.path.isfile(os.path.join(resultDir, r0)) and not os.path.isfile(os.path.join(resultDir, r1)): - self.dectState.setText("Not Detected") - else: - self.dectState.setText("") - if self.frameRad.isChecked(): - self.imageContainer.type = 0 - else: - self.imageContainer.type = 1 def showFileDialog(self): # 获取标注图片的文件夹 # fname = QtWidgets.QFileDialog.getOpenFileName(self, 'Open file', '/home') diff --git a/Athena/imageContainer.py b/Athena/imageContainer.py index 48861f0..5b80eca 100644 --- a/Athena/imageContainer.py +++ b/Athena/imageContainer.py @@ -1,10 +1,11 @@ from PyQt5 import QtWidgets, QtCore, QtGui import os +import math MAXWIDTH = 750 MAXHEIGHT = 600 -RECT = 0 +CIRC = 0 POLY = 1 class ImageContainer(QtWidgets.QFrame): @@ -25,10 +26,9 @@ def __init__(self, widgets = None): # 当前绘制的多边形的顶点 self.vertexes = [] # frames and balloons - self.result = [[], []] + self.result = [] self.isModified = False - self.isConfused = False self.isLarge = False # 0 for rectangle, 1 for polygon self.boxShape = 0 @@ -37,14 +37,12 @@ def __init__(self, widgets = None): self.preImagePath = '' self.type = 0 # 0 frame, 1 Balloon self.boxColor = (QtCore.Qt.blue, QtCore.Qt.red) - self.typeName = ('Frame', 'Balloon') self.typeId = (0, 1) def loadImage(self, path): self.vertexes = [] - self.result = [[], []] + self.result = [] self.isModified = False - self.isConfused = False print(path) self.image.load(path, '1') #read image self.imagePath = path @@ -72,9 +70,13 @@ def loadImage(self, path): else: self.scale = 1 self.oriImage = self.image.copy() - self.loadExistResult(path) + # self.loadExistResult(path) + scene = QtWidgets.QGraphicsScene() + scene.addPixmap(self.image) + self.graphicsView.setScene(scene) def loadExistResult(self, path): + ''' splitedPath = self.imagePath.split('/') baseDir = '/'.join(splitedPath[:-1]) imageName = splitedPath[-1] @@ -86,11 +88,13 @@ def loadExistResult(self, path): resultTxt = open(fullPath).read() self.parseDetectedResult(resultTxt, t) self.paintTotalResult() + ''' + pass def clearImage(self): if self.imagePath != '': self.isModified = True - self.result = ([], []) + self.result = [] self.vertexes.clear() self.image = self.oriImage.copy() scene = QtWidgets.QGraphicsScene() @@ -102,39 +106,14 @@ def clearImage(self): def mousePressEvent(self, event): if event.button() == QtCore.Qt.LeftButton: self.paintVertex(event) - if self.boxShape == POLY: - self.paintLine(True) elif event.button() == QtCore.Qt.RightButton: self.isModified = True if len(self.vertexes) < 2: return - if self.boxShape == RECT: - if len(self.vertexes) == 2: - self.paintRectangle() - else: - self.paintPolygon() - else: - self.paintLine(False) + if self.boxShape == CIRC: + self.paintCircle() - def paintLine(self, isLeft): - n = len(self.vertexes) - if n < 2: return - tp = self.type - painter = self.initMyPainter(tp) - if isLeft: - painter.drawLine(self.vertexes[n - 2], self.vertexes[n - 1]) - else: - mx = sum(v.x() for v in self.vertexes) / n - my = sum(v.y() for v in self.vertexes) / n - self.result[tp].append(self.vertexes[:]) - painter.drawLine(self.vertexes[-1], self.vertexes[0]) - painter.drawText(QtCore.QPoint(mx, my), str(len(self.result[tp]))) - self.vertexes.clear() - scene = QtWidgets.QGraphicsScene() - # scene.addPixmap(QtGui.QPixmap.fromImage(self.image)) - scene.addPixmap(self.image) - self.graphicsView.setScene(scene) def paintVertex(self, event): painter = QtGui.QPainter(self.image) @@ -147,7 +126,7 @@ def paintVertex(self, event): p = self.graphicsView.mapToScene(event.pos()) - self.graphicsView.pos() - QtCore.QPoint(2, 1) p = QtCore.QPoint(p.x(), p.y()) painter.drawPoint(p) - + print(p) # print('maptosence: ', p) self.vertexes.append(p) scene = QtWidgets.QGraphicsScene() @@ -167,36 +146,33 @@ def initMyPainter(self, tp): painter.setFont(font) return painter - def paintRectangle(self): - painter = self.initMyPainter(self.type) - topLeft = QtCore.QPoint(min(self.vertexes[0].x(), self.vertexes[1].x()), - min(self.vertexes[0].y(), self.vertexes[1].y())) - topRight = QtCore.QPoint(min(self.vertexes[0].x(), self.vertexes[1].x()), - max(self.vertexes[0].y(), self.vertexes[1].y())) - bottomleft = QtCore.QPoint(max(self.vertexes[0].x(), self.vertexes[1].x()), - min(self.vertexes[0].y(), self.vertexes[1].y())) - bottomRight = QtCore.QPoint(max(self.vertexes[0].x(), self.vertexes[1].x()), - max(self.vertexes[0].y(), self.vertexes[1].y())) - self.result[self.type].append([topLeft, topRight, bottomRight, bottomleft]) - rect = QtCore.QRect(topLeft, bottomRight) - painter.drawRect(rect) - mx = (self.vertexes[0].x() + self.vertexes[1].x()) / 2 - my = (self.vertexes[0].y() + self.vertexes[1].y()) / 2 - painter.drawText(QtCore.QPoint(mx, my), str(len(self.result[self.type]))) - scene = QtWidgets.QGraphicsScene() - scene.addPixmap(self.image) - self.graphicsView.setScene(scene) - self.vertexes.clear() - def paintPolygon(self): - self.result[self.type].append(self.vertexes[:]) - n = len(self.vertexes) - painter = self.initMyPainter(self.type) - mx = sum(v.x() for v in self.vertexes) / n - my = sum(v.y() for v in self.vertexes) / n - painter.drawPolygon(QtGui.QPolygon(self.vertexes)) + def fitCircle(self): + p1x, p1y = self.vertexes[-3].x(), self.vertexes[-3].y() + p2x, p2y = self.vertexes[-2].x(), self.vertexes[-2].y() + p3x, p3y = self.vertexes[-1].x(), self.vertexes[-1].y() + + midP1x = (p2x + p1x) / 2 + midP1y = (p2y + p1y) / 2 - painter.drawText(QtCore.QPoint(mx, my), str(len(self.result[self.type]))) + midP2x = (p3x + p1x) / 2 + midP2y = (p3y + p1y) / 2 + + k1 = -(p2x - p1x) / (p2y - p1y) + k2 = -(p3x - p1x) / (p3y - p1y) + cx = (midP2y - midP1y - k2 * midP2x + k1 * midP1x) / (k1 - k2) + cy = midP1y + k1 * (midP2y - midP1y - k2 * midP2x + k2 * midP1x) / (k1 - k2) + r = math.sqrt((cx - p1x)*(cx - p1x) + (cy - p1y) * (cy - p1y)) + print(cx, cy, r) + return cx, cy, r + + def paintCircle(self): + circle = self.fitCircle() + self.result.append(circle) + painter = self.initMyPainter(self.type) + cx, cy, r = circle[0], circle[1], circle[2] + painter.drawEllipse(cx - r, cy - r, r*2, r*2) + # painter.drawText(QtCore.QPoint(mx, my), str(len(self.result[self.type]))) scene = QtWidgets.QGraphicsScene() scene.addPixmap(self.image) self.graphicsView.setScene(scene) @@ -219,34 +195,34 @@ def parseDetectedResult(self, result, tp): except: print("Parse Error! Result's format is wrong!") - def paintTotalResult(self): - for tp in self.typeId: - painter = self.initMyPainter(tp) - for id, vertexes in enumerate(self.result[tp]): - n = len(vertexes) - mx = sum(v.x() for v in vertexes) / n - my = sum(v.y() for v in vertexes) / n - painter.drawPolygon(QtGui.QPolygon(vertexes)) - painter.drawText(QtCore.QPoint(mx, my), str(id + 1)) - painter.end() - scene = QtWidgets.QGraphicsScene() - scene.addPixmap(self.image) - self.graphicsView.setScene(scene) + # def paintTotalResult(self): + # for tp in self.typeId: + # painter = self.initMyPainter(tp) + # for id, vertexes in enumerate(self.result[tp]): + # n = len(vertexes) + # mx = sum(v.x() for v in vertexes) / n + # my = sum(v.y() for v in vertexes) / n + # painter.drawPolygon(QtGui.QPolygon(vertexes)) + # painter.drawText(QtCore.QPoint(mx, my), str(id + 1)) + # painter.end() + # scene = QtWidgets.QGraphicsScene() + # scene.addPixmap(self.image) + # self.graphicsView.setScene(scene) - def deleteBoxes(self, dlst): - # A naive way to delete boxes. To be update. - l = [] - tp = self.type - n = len(self.result[tp]) - for i in range(n): - if i not in dlst: - l.append(self.result[tp][i]) - - self.result[tp] = l - self.image = self.oriImage.copy() - self.paintTotalResult() - self.isModified = True - # self.paintTotalResult(tp ^ 1) + # def deleteBoxes(self, dlst): + # # A naive way to delete boxes. To be update. + # l = [] + # tp = self.type + # n = len(self.result[tp]) + # for i in range(n): + # if i not in dlst: + # l.append(self.result[tp][i]) + # + # self.result[tp] = l + # self.image = self.oriImage.copy() + # self.paintTotalResult() + # self.isModified = True + # # self.paintTotalResult(tp ^ 1) def getOutputFileName(self, t): splitedPath = self.imagePath.split('/') @@ -255,36 +231,26 @@ def getOutputFileName(self, t): resultDir = os.path.join(baseDir, 'result') if os.path.exists(resultDir) == False: os.mkdir(resultDir) - resultName = self.typeName[t] + '_' + imageName + '.txt' + resultName = 'circle' + '_' + imageName + '.txt' return resultDir, resultName def saveResult(self): if self.isModified: for t in (0, 1): - n = len(self.result[t]) + n = len(self.result) resultDir, resultName = self.getOutputFileName(t) outFile = open(os.path.join(resultDir, resultName), 'w') outFile.write(str(n)+'\n') - for res in self.result[t]: - m = len(res) - outFile.write(str(m)) + print(self.result) + for res in self.result: if self.scale != 1: res = [p * self.scale for p in res] - for i in range(m): - outFile.write(' ' + str(res[i].x()) + ' ' + str(res[i].y())) - outFile.write('\n') + # print(res) + outFile.write(str(res[0]) + ' ' + str(res[1]) + ' ' + str(res[2]) + '\n') outFile.close() else: print("Nothing to save!") - if self.isConfused: - splitedPath = self.imagePath.split('/') - baseDir = '/'.join(splitedPath[:-1]) - resultDir = os.path.join(baseDir, 'result') - if os.path.exists(resultDir) == False: - os.mkdir(resultDir) - outFile = open(os.path.join(resultDir, 'confused.txt'), 'a+', encoding='utf-8') - outFile.write(self.imagePath + '\n') - outFile.close() + From b4c16d1e26efdda14b5112b031194c97ea2d3604 Mon Sep 17 00:00:00 2001 From: philokey Date: Mon, 14 Mar 2016 21:39:18 +0800 Subject: [PATCH 3/6] Add README --- Athena/.idea/workspace.xml | 66 +++++++++++++++++++++++--------------- Athena/README | 7 ++++ Athena/imageContainer.py | 10 +++--- 3 files changed, 53 insertions(+), 30 deletions(-) create mode 100644 Athena/README diff --git a/Athena/.idea/workspace.xml b/Athena/.idea/workspace.xml index 64e603e..e045c83 100644 --- a/Athena/.idea/workspace.xml +++ b/Athena/.idea/workspace.xml @@ -2,8 +2,8 @@ + - @@ -21,7 +21,7 @@ - + @@ -494,7 +505,13 @@ @@ -503,7 +520,6 @@ - @@ -514,6 +530,7 @@ + @@ -538,7 +555,8 @@ - @@ -547,16 +565,6 @@ - - - - - - - - - - @@ -1006,10 +1014,18 @@ + + + + + + + + - - + + @@ -1021,8 +1037,8 @@ - - + + diff --git a/Athena/README b/Athena/README new file mode 100644 index 0000000..9c51fec --- /dev/null +++ b/Athena/README @@ -0,0 +1,7 @@ +#Branch for Circle Annotation + +##Useage + +Select three points by click left mouse button, click right mouse button to fit the circle. + +Circles will be saved in ./result \ No newline at end of file diff --git a/Athena/imageContainer.py b/Athena/imageContainer.py index 5b80eca..d0f0b25 100644 --- a/Athena/imageContainer.py +++ b/Athena/imageContainer.py @@ -180,18 +180,18 @@ def paintCircle(self): def parseDetectedResult(self, result, tp): lines = result.strip().split('\n') - self.result[tp].clear() + self.result.clear() try: n = int(lines[0]) for i in range(1, n + 1): points = list(map(int, lines[i].strip().split())) - m = points[0] * 2 + 1 + if self.scale != 1: points = [p / self.scale for p in points] vs = [] - for j in range(1, m, 2): - vs.append(QtCore.QPoint(points[j], points[j + 1])) - self.result[tp].append(vs) + for j in range(3): + vs.append(points[j]) + self.result.append(vs) except: print("Parse Error! Result's format is wrong!") From 48267bc9c259e0bc1d464c46852915e558bc3fc3 Mon Sep 17 00:00:00 2001 From: philokey Date: Wed, 23 Mar 2016 11:06:45 +0800 Subject: [PATCH 4/6] add ellipse --- Athena/.idea/workspace.xml | 246 +++++++++++++++---------------------- Athena/athena.py | 8 +- Athena/imageContainer.py | 23 +++- 3 files changed, 121 insertions(+), 156 deletions(-) diff --git a/Athena/.idea/workspace.xml b/Athena/.idea/workspace.xml index e045c83..d8c1f00 100644 --- a/Athena/.idea/workspace.xml +++ b/Athena/.idea/workspace.xml @@ -2,8 +2,8 @@ - + @@ -21,7 +21,7 @@ - + @@ -118,8 +96,8 @@ @@ -159,7 +137,6 @@ - @@ -181,13 +158,14 @@ + - + - + @@ -516,27 +494,27 @@ - + - + - - + + @@ -565,20 +543,41 @@ - + - + - + + + + - + + + + + + + + + + + + + + + + + + + @@ -588,43 +587,55 @@ - + - + - + - + - + + - + - + - + + + + - + - + - + + + + + + + + + @@ -665,20 +676,10 @@ - - - - - - - - - - - + @@ -691,7 +692,7 @@ - + @@ -715,16 +716,6 @@ - - - - - - - - - - @@ -738,29 +729,29 @@ - + - + + + + - + - - - - + - + - + - + @@ -795,20 +786,10 @@ - - - - - - - - - - - + @@ -821,30 +802,20 @@ - + - + - - - - - - - - - - @@ -858,17 +829,17 @@ - + - + - + @@ -878,7 +849,7 @@ - + @@ -888,29 +859,35 @@ - + - + + + + - + - + - + + + + - + - + - + @@ -974,16 +951,6 @@ - - - - - - - - - - @@ -991,21 +958,6 @@ - - - - - - - - - - - - - - - @@ -1024,8 +976,8 @@ - - + + @@ -1037,8 +989,8 @@ - - + + diff --git a/Athena/athena.py b/Athena/athena.py index 760ffb6..7b7c367 100644 --- a/Athena/athena.py +++ b/Athena/athena.py @@ -12,8 +12,8 @@ import pickle FILE_TYPE = ['jpg', 'jpeg', 'tif', 'bmp', 'gif', 'png'] -RECT = 0 -POLY = 1 +CIRC = 0 +ELLI = 1 class MainWindow(QtWidgets.QMainWindow): # _signal = QtCore.pyqtSignal() @@ -24,8 +24,8 @@ def __init__(self): self.settings = QtCore.QSettings('setting.ini', QtCore.QSettings.IniFormat) # 读入路径 - # self.imageFolder = self.showFileDialog() - self.imageFolder = '/Users/philokey/Comic' #调试方便 + self.imageFolder = self.showFileDialog() + # self.imageFolder = '/Users/philokey/Comic' #调试方便 # 屏幕居中 self.screen = QtWidgets.QDesktopWidget().screenGeometry() diff --git a/Athena/imageContainer.py b/Athena/imageContainer.py index d0f0b25..0893bb7 100644 --- a/Athena/imageContainer.py +++ b/Athena/imageContainer.py @@ -1,12 +1,14 @@ from PyQt5 import QtWidgets, QtCore, QtGui import os import math +import cv2 +import numpy as np MAXWIDTH = 750 MAXHEIGHT = 600 CIRC = 0 -POLY = 1 +ELLI = 1 class ImageContainer(QtWidgets.QFrame): def __init__(self, widgets = None): @@ -14,7 +16,7 @@ def __init__(self, widgets = None): containerLayout = QtWidgets.QVBoxLayout() self.graphicsView = QtWidgets.QGraphicsView() - self.graphicsView.setCursor(QtCore.Qt.CrossCursor) + # self.graphicsView.setCursor(QtCore.Qt.CrossCursor) self.graphicsView.setObjectName("graphicsView") # self.image can be painted self.image = QtGui.QPixmap() @@ -31,11 +33,10 @@ def __init__(self, widgets = None): self.isModified = False self.isLarge = False # 0 for rectangle, 1 for polygon - self.boxShape = 0 + self.boxShape = ELLI self.scale = 1 self.imagePath = '' self.preImagePath = '' - self.type = 0 # 0 frame, 1 Balloon self.boxColor = (QtCore.Qt.blue, QtCore.Qt.red) self.typeId = (0, 1) @@ -113,7 +114,8 @@ def mousePressEvent(self, event): return if self.boxShape == CIRC: self.paintCircle() - + elif self.boxShape == ELLI: + self.fitEllipse() def paintVertex(self, event): painter = QtGui.QPainter(self.image) @@ -166,6 +168,17 @@ def fitCircle(self): print(cx, cy, r) return cx, cy, r + def fitEllipse(self): + points = [] + for v in self.vertexes: + x, y = v.x(), v.y() + points.append((x, y)) + points = np.array(points) + # print(points) + ell = cv2.fitEllipse(points) + print("%.6f %.6f %.6f %.6f %.3f" %(ell[0][0], ell[0][1], ell[1][0] / 2, ell[1][1] / 2, ell[2])) + self.vertexes.clear() + def paintCircle(self): circle = self.fitCircle() self.result.append(circle) From 7b0e062dfb11ff763ea9c58e7096ca6bd2f34b73 Mon Sep 17 00:00:00 2001 From: philokey Date: Wed, 23 Mar 2016 11:09:32 +0800 Subject: [PATCH 5/6] add ellipse --- Athena/.idea/workspace.xml | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/Athena/.idea/workspace.xml b/Athena/.idea/workspace.xml index d8c1f00..2f5e0d3 100644 --- a/Athena/.idea/workspace.xml +++ b/Athena/.idea/workspace.xml @@ -3,8 +3,6 @@ - - @@ -489,7 +487,13 @@ @@ -498,23 +502,23 @@ + + + - - - @@ -534,7 +538,8 @@ - From 7e3d4756d488d485589b83509551cb2a18dfdde1 Mon Sep 17 00:00:00 2001 From: philokey Date: Wed, 23 Mar 2016 11:10:04 +0800 Subject: [PATCH 6/6] add ellipse --- Athena/.idea/workspace.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Athena/.idea/workspace.xml b/Athena/.idea/workspace.xml index 2f5e0d3..ca39b0b 100644 --- a/Athena/.idea/workspace.xml +++ b/Athena/.idea/workspace.xml @@ -493,7 +493,13 @@