프로젝트

일반

사용자정보

통계
| 브랜치(Branch): | 개정판:

hytos / DTI_PID / DTI_PID / TrainingEditorDialog.py @ 6fa02c93

이력 | 보기 | 이력해설 | 다운로드 (12.1 KB)

1
import sys
2
import os
3
from PyQt5.QtCore import *
4
from PyQt5.QtGui import *
5
from PyQt5.QtWidgets import *
6
from AppDocData import AppDocData, Source
7
import TrainingEditor_UI
8
import QtImageViewer
9
from GraphicsBoundingBoxItem import QGraphicsBoundingBoxItem
10
from TrainingBoxItem import QTrainingBoxItem
11
import cv2
12
from PIL import Image
13
import AreaZoomCommand
14
import PlaceLineCommand
15

    
16

    
17

    
18
class QTrainingEditorDialog(QDialog):
19
    def __init__(self, parent, trainingImgPath, trainingBoxPath, boundaryOcrData):
20
        self.spinBoxFlag = False
21
        QDialog.__init__(self, parent)
22
        self.setWindowFlag(Qt.WindowMinMaxButtonsHint)
23

    
24
        self.trainingImgPath = trainingImgPath
25
        self.trainingBoxPath = trainingBoxPath
26
        self.boundaryOcrData = boundaryOcrData
27
        self.isChanged = False
28

    
29
        appDocData = AppDocData.instance()
30
        project = appDocData.getCurrentProject()
31

    
32
        self.ui = TrainingEditor_UI.Ui_TrainingEditorDialog()
33
        self.ui.setupUi(self)
34

    
35
        self.graphicsViewTrainingDrawing = QtImageViewer.QtImageViewer(self)
36
        self.graphicsViewTrainingDrawing.setParent(self.ui.centralWidget)
37
        self.graphicsViewTrainingDrawing.useDefaultCommand()
38
        self.ui.verticalLayoutTrainingDrawing.addWidget(self.graphicsViewTrainingDrawing)
39

    
40
        self.graphicsViewZoomDrawing = QGraphicsView(self)
41
        self.graphicsViewZoomDrawing.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
42
        self.graphicsViewZoomDrawing.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
43
        self.graphicsViewZoomDrawing.setParent(self.ui.leftSideWidget)
44
        self.ui.horizontalLayoutZoomDrawing.addWidget(self.graphicsViewZoomDrawing)
45
        
46
        
47
        # 학습 이미지 읽어서 메인 뷰에 그림, 사이드 뷰에 추가
48
        try:
49
            #trainingImgPath = os.path.join(project.getTrainingFilePath(), 'seed.seedF.exp0.tif')
50
            cvImg = cv2.cvtColor(cv2.imread(trainingImgPath), cv2.COLOR_BGR2GRAY)
51
            blur = cv2.GaussianBlur(cvImg, (5,5),0)
52
            cvImg = cv2.threshold(cvImg, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
53
            bytesPerLine = cvImg.shape[1]
54
            image = QImage(cvImg.data, cvImg.shape[1], cvImg.shape[0], bytesPerLine, QImage.Format_Indexed8)
55

    
56
            self.graphicsViewTrainingDrawing.setImage(image)
57

    
58
            # 사이드 뷰
59
            if type(image) is QPixmap:
60
                pixmap = image
61
            elif type(image) is QImage:
62
                pixmap = QPixmap.fromImage(image)
63
            scene = QGraphicsScene()
64
            self.graphicsViewZoomDrawing.setScene(scene)
65
            self._pixmapHandle = self.graphicsViewZoomDrawing.scene().addPixmap(pixmap)
66
            rect = QGraphicsRectItem(0, 0, 0, 0)
67
            pen = QPen(Qt.SolidLine)
68
            pen.setColor(Qt.green)
69
            pen.setWidthF(1)
70
            pen.setJoinStyle(Qt.MiterJoin)
71
            rect.setPen(pen)
72
            rect.setOpacity(0.7)
73
            self.graphicsViewZoomDrawing.scene().addItem(rect)
74

    
75
        except Exception as ex:
76
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
77

    
78
        # 박스 읽어서 메인 뷰에 그림
79
        try:
80
            boxList = []
81
            if self.boundaryOcrData is None:
82
                fBox = open(trainingBoxPath, 'r', encoding='utf8')
83
                SBox = fBox.read()
84
                fBox.close()
85
                boxList = SBox.split('\n')
86
            else:
87
                boxList = boundaryOcrData.split('\n')
88

    
89
            for box in boxList:
90
                if box == '': continue
91
                boxComponent = box.split(' ')
92
                singleBox = QTrainingBoxItem(str(boxComponent[0]), int(boxComponent[1]), cvImg.shape[0] - int(boxComponent[4]), int(boxComponent[3]) - int(boxComponent[1]), int(boxComponent[4]) - int(boxComponent[2]))
93
                singleBox.transfer.onRemoved.connect(self.itemRemoved)
94
                singleBox.addTextItemToScene(self.ui, self.graphicsViewTrainingDrawing, self.graphicsViewZoomDrawing, self.spinBoxFlag)
95
            
96
        except Exception as ex:
97
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
98

    
99
        #'''test'''
100
        #item = QGraphicsBoundingBoxItem(0, 0, 30, 30)
101
        #item.isSymbol = True
102
        #item.angle = 0
103
        #item.setPen(QPen(Qt.red, 1, Qt.SolidLine))
104
        #self.graphicsViewTrainingDrawing.scene.addItem(item)
105

    
106
        self.removedItems = []
107

    
108
        self.ui.pushButtonZoom.clicked.connect(self.onAreaZoom)
109
        self.ui.pushButtonSave.clicked.connect(self.pushButtonSaveClicked)
110
        self.ui.pushButtonCancel.clicked.connect(self.pushButtonCancelClicked)
111
        self.ui.pushButtonChange.clicked.connect(self.pushButtonChangeClicked)
112
        self.ui.pushButtonDelete.clicked.connect(self.pushButtonDeleteClicked)
113
        self.ui.pushButtonAdd.clicked.connect(self.pushButtonAddClicked)
114
        self.ui.pushButtonSplit.clicked.connect(self.pushButtonSplitClicked)
115
        self.ui.spinBoxLeft.valueChanged.connect(self.spinBoxChangedEvent)
116
        self.ui.spinBoxTop.valueChanged.connect(self.spinBoxChangedEvent)
117
        self.ui.spinBoxWidth.valueChanged.connect(self.spinBoxChangedEvent)
118
        self.ui.spinBoxHeight.valueChanged.connect(self.spinBoxChangedEvent)
119

    
120
    '''
121
        @brief      split boxitem by button click
122
        @author     euisung
123
        @date       2018.10.31
124
    '''
125
    def pushButtonSplitClicked(self):
126
        self.isChanged = True
127
        items = self.graphicsViewTrainingDrawing.scene.selectedItems()
128
        if len(items) is not 1:
129
            return
130
        rect = items[0].rect()
131
        secondBox = QTrainingBoxItem('', rect.x() + round(rect.width() / 2), rect.y(), round(rect.width() / 2), rect.height())
132
        secondBox.transfer.onRemoved.connect(self.itemRemoved)
133
        secondBox.addTextItemToScene(self.ui, self.graphicsViewTrainingDrawing, self.graphicsViewZoomDrawing, self.spinBoxFlag)
134
        items[0].setRect(rect.x(), rect.y(), round(rect.width() / 2), rect.height())
135

    
136
    '''
137
        @brief      add boxitem by button click
138
        @author     euisung
139
        @date       2018.10.17
140
    '''
141
    def pushButtonAddClicked(self):
142
        self.isChanged = True
143
        items = self.graphicsViewTrainingDrawing.scene.selectedItems()
144
        allItems = self.graphicsViewTrainingDrawing.scene.items()
145
        totalWidth = 0
146
        totalHeight = 0
147
        count = 0
148
        if len(items) is 1:
149
            rect = items[0].rect()
150
        elif len(allItems) > 1:
151
            for item in allItems:
152
                if type(item) is QGraphicsPixmapItem:
153
                    x = int(item.boundingRect().width() / 2)
154
                    y = int(item.boundingRect().height()/ 2)
155
                else:
156
                    count += 1
157
                    totalWidth += item.rect().width()
158
                    totalHeight += item.rect().height()
159
            rect = QRectF(x, y, round(totalWidth / count), round(totalHeight / count))
160
        else:
161
            for item in allItems:
162
                if type(item) is QGraphicsPixmapItem:
163
                    x = int(item.boundingRect().width() / 2)
164
                    y = int(item.boundingRect().height()/ 2)
165
            rect = QRectF(x, y, 5, 10)
166
        singleBox = QTrainingBoxItem('', rect.x() + 3, rect.y(), rect.width(), rect.height())
167
        singleBox.transfer.onRemoved.connect(self.itemRemoved)
168
        singleBox.addTextItemToScene(self.ui, self.graphicsViewTrainingDrawing, self.graphicsViewZoomDrawing, self.spinBoxFlag)
169

    
170
    '''
171
        @brief      delete boxitem by button click
172
        @author     euisung
173
        @date       2018.10.17
174
    '''
175
    def pushButtonDeleteClicked(self):
176
        self.isChanged = True
177
        items = self.graphicsViewTrainingDrawing.scene.selectedItems()
178
        for item in items:
179
            item.transfer.onRemoved.emit(item)
180

    
181
    '''
182
        @brief      change boxitem char by button click
183
        @author     euisung
184
        @date       2018.10.17
185
    '''
186
    def pushButtonChangeClicked(self):
187
        self.isChanged = True
188
        items = self.graphicsViewTrainingDrawing.scene.selectedItems()
189
        if len(items) is not 1:
190
            return
191
        items[0].char = self.ui.lineEditChar.text()
192

    
193
    '''
194
        @brief      close dialog by button click
195
        @author     euisung
196
        @date       2018.10.17
197
    '''
198
    def pushButtonCancelClicked(self):
199
        if self.isChanged:
200
            reply = QMessageBox.question(self, 'Continue?', '변경사항이 저장되지 않았을 수 있습니다.', QMessageBox.Ignore, QMessageBox.Cancel)
201
            if reply == QMessageBox.Ignore:
202
                QDialog.reject(self)
203
        else:
204
            QDialog.reject(self)
205

    
206
    '''
207
        @brief      save box item by button click
208
        @author     euisung
209
        @date       2018.10.16
210
    '''
211
    def pushButtonSaveClicked(self):
212
        items = self.graphicsViewTrainingDrawing.scene.items()
213
        outBox = ""
214
        for item in items:
215
            if type(item) is QGraphicsPixmapItem:
216
                imgHeight = int(item.boundingRect().height())
217
                imgWidth = int(item.boundingRect().width())
218
        for item in items:
219
            if type(item) is QTrainingBoxItem:
220
                rect = item.rect()
221
                char, x, y, width, height = item.char, int(rect.x()), int(rect.y()), int(rect.width()), int(rect.height())
222
                bx, by, bx2, by2 = str(x), str(imgHeight - y - height), str(x + width), str(imgHeight - y)
223
                if char == '':
224
                    continue
225
                outBox += char + " " + bx + " " + by + " " + bx2 + " " + by2 + "\n"
226
        fw = open(self.trainingBoxPath, 'w')
227
        fw.write(outBox)
228
        fw.close()
229
        self.isChanged = False
230
        QMessageBox.about(self, "알림", '저장하였습니다.')
231

    
232
    '''
233
        @brief      chane box item's rect by button click
234
        @author     euisung
235
        @date       2018.10.16
236
    '''
237
    def spinBoxChangedEvent(self, event):
238
        self.isChanged = True
239
        items = self.graphicsViewTrainingDrawing.scene.selectedItems()
240
        if (len(items) is not 1) or self.spinBoxFlag:
241
            return
242
        spinBoxName = self.sender().objectName()
243
        rect = items[0].rect()
244
        bound = self.graphicsViewZoomDrawing.scene().items()[0]
245

    
246
        if spinBoxName == 'spinBoxLeft':
247
            spinBoxValue = self.ui.spinBoxLeft.value()
248
            items[0].setRect(QRectF(spinBoxValue, rect.y(), rect.width(), rect.height()))
249
        elif spinBoxName == 'spinBoxTop':
250
            spinBoxValue = self.ui.spinBoxTop.value()
251
            items[0].setRect(QRectF(rect.x(), spinBoxValue, rect.width(), rect.height()))
252
        elif spinBoxName == 'spinBoxWidth':
253
            spinBoxValue = self.ui.spinBoxWidth.value()
254
            items[0].setRect(QRectF(rect.x(),  rect.y(), spinBoxValue, rect.height()))
255
        elif spinBoxName == 'spinBoxHeight':
256
            spinBoxValue = self.ui.spinBoxHeight.value()
257
            items[0].setRect(QRectF(rect.x(), rect.y(), rect.width(), spinBoxValue))
258
        
259
        rect = items[0].rect()        
260
        bound.setRect(rect)
261
        rectSide = QRectF(rect.x() -3, rect.y() -3, rect.width() +6,  rect.height() +6)
262
        self.graphicsViewZoomDrawing.fitInView(rectSide)
263
        self.graphicsViewTrainingDrawing.scene.update()
264
    
265
    def onAreaZoom(self, action):
266
        if self.ui.pushButtonZoom.isChecked():
267
            cmd = AreaZoomCommand.AreaZoomCommand(self.graphicsViewTrainingDrawing)
268
            cmd.onRejected.connect(self.onCommandRejected)
269
            self.graphicsViewTrainingDrawing.command = cmd
270

    
271
    def onCommandRejected(self, cmd):
272
        try:
273
            if type(cmd) is AreaZoomCommand.AreaZoomCommand:
274
                self.ui.pushButtonZoom.setChecked(False)
275
        finally:
276
            self.graphicsViewTrainingDrawing.useDefaultCommand()
277

    
278
    def itemRemoved(self, item):
279
        try:
280
            if type(item) is QTrainingBoxItem:
281
                self.removedItems.append(str(item.uid))
282

    
283
            if item.scene is not None: item.scene.removeItem(item)
284
        except Exception as ex:
285
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
286

    
287
        
288
        
289

    
290
        
클립보드 이미지 추가 (최대 크기: 500 MB)