프로젝트

일반

사용자정보

개정판 a4707ffe

IDa4707ffe20bb10626ad74579dfb40f064cb20583
상위 1850e04e
하위 91ebadb1

백흠경이(가) 6년 이상 전에 추가함

modified issue #663:
- 심볼, 텍스트, 라인을 사용자가 선택하여 선별적으로 인식할 수 있도록 한다

차이점 보기:

DTI_PID/DTI_PID/App.py
12 12
from PyQt5.QtSvg import *
13 13
from PyQt5 import QtWidgets
14 14

  
15
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
15 16
from AppDocData import AppDocData
16 17

  
17 18
class App(QApplication):
19
    """
20
    This is App class inherits from QApplication
21
    """
18 22
    def __init__(self, args):
19 23
        super(App, self).__init__(args)
20 24
        appStyle = AppDocData.instance().loadAppStyle()
......
73 77
            AppDocData.instance().setCurrentProject(selectedProject)
74 78
            app._mainWnd = MainWindow.instance()
75 79
            app._mainWnd.show()
80
            sys.exit(app.exec_())
76 81
    except Exception as ex:
77
        print('에러가 발생했습니다.\n', ex)
78

  
79
    sys.exit(app.exec_())  
82
        print('에러가 발생했습니다.\n', ex)
DTI_PID/DTI_PID/MainWindow.py
2 2

  
3 3
import sys
4 4
import os
5

  
6
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
5 7
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Commands')
6 8
import CreateCommand
7 9
import CropCommand
......
48 50
from TextItemFactory import TextItemFactory
49 51

  
50 52
class MainWindow(QMainWindow, MainWindow_UI.Ui_MainWindow, SingletonInstane):
53
    """
54
    This is MainWindow class
55
    """
51 56
    addMessage = pyqtSignal(Enum, str)
52 57

  
53 58
    '''
......
1710 1715
            AppDocData.instance().setCurrentProject(selectedProject)
1711 1716
            app._mainWnd = MainWindow.instance()
1712 1717
            app._mainWnd.show()
1718
            sys.exit(app.exec_())
1713 1719
    except Exception as ex:
1714
        print('에러가 발생했습니다.\n', ex)
1715

  
1716
    sys.exit(app.exec_())
1720
        print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
1721
    finally:
1722
        pass
DTI_PID/DTI_PID/RecognitionDialog.py
77 77
    '''
78 78
    def procCounter(self): # A slot takes no params
79 79
        try:
80
            if self.isSymbolTextChecked:
81
                Worker.executeRecognition(self.drawDetectedItems, self.path, self.listWidget, self.isSymbolTextChecked, self)
80
            if self.isSymbolChecked or self.isTextChecked:
81
                Worker.executeRecognition(self.drawDetectedItems, self.path, self.listWidget, self)
82

  
83
            if self.isLineChecked:
82 84
                Worker.recognizeLine(self.drawDetectedLines, self.path, self.listWidget, self.graphicsView, self)
83
            elif self.isLineChecked:
84
                Worker.recognizeLine(self.path, self.listWidget, self.graphicsView, self)
85
            else:
86
                self.finished.emit()
87 85
        except Exception as ex:
88 86
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
89 87
            self.displayLog.emit(MessageType.Error, message)
88
        finally:
89
            self.finished.emit()
90 90

  
91 91
    '''
92 92
        @brief  remove small objects from given image
......
167 167
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
168 168
            MainWindow.instance().displayMessage.emit(MessageType.Error, message)
169 169

  
170
    '''
170
    @staticmethod
171
    def executeRecognition(drawDetectedItems, path, listWidget, worker):
172
        """
171 173
        @brief      Main function
172 174
        @author     Jeongwoo
173 175
        @date
......
183 185
                    Jeongwoo 2018.06.21 If noteTextInfoList is None, change from None to empty list
184 186
                    humkyung 2018.08.20 remove alreay existing symbol and text item before recognizing
185 187
                                        block until drawing reconized objects
186
    '''
187
    @staticmethod
188
    def executeRecognition(drawDetectedItems, path, listWidget, isSymbolTextChecked, worker):
188
        """
189 189
        import re
190 190
        from TextDetector import TextDetector
191 191
    
......
248 248
                if area is not None:
249 249
                    area.img = appDocData.imgSrc[round(area.y):round(area.y+area.height), round(area.x):round(area.x+area.width)]
250 250
    
251
                maxProgressValue = 0
251 252
                listWidget.addItem("Start recognition : " + mainRes)
252
                worker.displayTitle.emit('심볼 인식 중...') 
253
                if isSymbolTextChecked:
254
                    threadLock.acquire()
255
                    offset = (area.x, area.y) if area is not None else (0,0)
253
                threadLock.acquire()
254
                offset = (area.x, area.y) if area is not None else (0,0)
255
                if worker.isTextChecked:
256 256
                    textAreas = textDetector.detectTextAreas(area.img if area is not None else appDocData.imgSrc, offset)
257
                    ### calculate total count of symbol
258 257
                    maxProgressValue = len(textAreas) + 1 
258

  
259
                if worker.isSymbolChecked:
260
                    ### calculate total count of symbol
259 261
                    for targetItem in targetSymbolList:
260 262
                        if type(targetItem) is list:
261 263
                            maxProgressValue += len(targetItem)
262 264
                        else:
263 265
                            maxProgressValue += 1
264 266
                    ### up to here
265
                    threadLock.release()
267
                threadLock.release()
266 268
    
269
                if worker.isSymbolChecked:
270
                    worker.displayTitle.emit('심볼 인식 중...') 
271

  
267 272
                    # detect equipments
268 273
                    pool = futures.ThreadPoolExecutor(max_workers = THREAD_MAX_WORKER)
269 274
                    for symbol in targetSymbolList[0]:
......
285 290
                        cv2.imwrite(os.path.join(project.getTempPath(), 'Tile', item.getName()+'.png'), _img)
286 291
                    ## up to here
287 292
    
293
                if worker.isTextChecked:
288 294
                    worker.displayTitle.emit('텍스트 인식 중...')
289 295
                    textDetector.recognizeText(appDocData.imgSrc, offset, textAreas, searchedSymbolList, worker, listWidget, maxProgressValue)
290 296
                    textInfoList = textDetector.textInfoList.copy() if textDetector.textInfoList is not None else None
......
299 305
                   
300 306
                    appDocData.imgName = os.path.splitext(os.path.basename(mainRes))[0]
301 307
    
302
                    pool = futures.ThreadPoolExecutor(max_workers = THREAD_MAX_WORKER)
303
                    for sym in searchedSymbolList:
304
                        pool.submit(Worker.removeDetectedSymbol, sym, appDocData.imgSrc)
305
                    pool.shutdown(wait = True)
306
    
307
                    ## Remove Noise
308
                    kernel1 = np.ones((2, 2), np.uint8)
309
                    appDocData.imgSrc = cv2.dilate(appDocData.imgSrc, kernel1)
310
                    appDocData.imgSrc = cv2.erode(appDocData.imgSrc, kernel1)
308
                pool = futures.ThreadPoolExecutor(max_workers = THREAD_MAX_WORKER)
309
                for sym in searchedSymbolList:
310
                    pool.submit(Worker.removeDetectedSymbol, sym, appDocData.imgSrc)
311
                pool.shutdown(wait = True)
311 312
    
312
                    removedSymbolImgPath = os.path.join(project.getTempPath(), os.path.basename(path))
313
                    cv2.imwrite(removedSymbolImgPath, appDocData.imgSrc)
314
    
315
                    area = AppDocData.instance().getArea('Drawing')
316
                    if area is not None:
317
                        area.img = appDocData.imgSrc[round(area.y+1):round(area.y+area.height), round(area.x+1):round(area.x+area.width)]
318
                    cv2.imwrite(os.path.join(project.getTempPath(), "RECT_" + os.path.basename(path)), appDocData.imgSrc)
313
                ## Remove Noise
314
                kernel1 = np.ones((2, 2), np.uint8)
315
                appDocData.imgSrc = cv2.dilate(appDocData.imgSrc, kernel1)
316
                appDocData.imgSrc = cv2.erode(appDocData.imgSrc, kernel1)
317

  
318
                removedSymbolImgPath = os.path.join(project.getTempPath(), os.path.basename(path))
319
                cv2.imwrite(removedSymbolImgPath, appDocData.imgSrc)
319 320
    
320
                    listWidget.addItem("Recognized symbol count : " + str(len(searchedSymbolList)))
321
                area = AppDocData.instance().getArea('Drawing')
322
                if area is not None:
323
                    area.img = appDocData.imgSrc[round(area.y+1):round(area.y+area.height), round(area.x+1):round(area.x+area.width)]
324
                cv2.imwrite(os.path.join(project.getTempPath(), "RECT_" + os.path.basename(path)), appDocData.imgSrc)
325

  
326
                listWidget.addItem("Recognized symbol count : " + str(len(searchedSymbolList)))
321 327
                    
322
                    # get difference between original and recognized image
323
                    foundFilePath = os.path.join(project.getTempPath(), "FOUND_" + os.path.basename(path))
324
                    Worker.getDifference(path, foundFilePath)
325
                    # up to here
328
                # get difference between original and recognized image
329
                foundFilePath = os.path.join(project.getTempPath(), "FOUND_" + os.path.basename(path))
330
                Worker.getDifference(path, foundFilePath)
331
                # up to here
326 332

  
327
                    ## block until drawing recognized objects
328
                    loop = QEventLoop()
329
                    listWidget.addItem('인식 정보 생성 중...')
330
                    worker.displayTitle.emit('인식 정보 생성 중...') 
331
                    drawDetectedItems.emit(searchedSymbolList, textInfoList, otherTextInfoList if otherTextInfoList is not None else [], loop)
332
                    loop.exec_()
333
                    ## up to here
333
                ## block until drawing recognized objects
334
                loop = QEventLoop()
335
                listWidget.addItem('인식 정보 생성 중...')
336
                worker.displayTitle.emit('인식 정보 생성 중...') 
337
                drawDetectedItems.emit(searchedSymbolList, textInfoList, otherTextInfoList if otherTextInfoList is not None else [], loop)
338
                loop.exec_()
339
                ## up to here
334 340
        except Exception as ex:
335 341
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
336 342
            worker.displayLog.emit(MessageType.Error, message)
......
1267 1273
        self.isAccepted = True
1268 1274
        QDialog.accept(self)
1269 1275

  
1270
    '''
1271
        @brief  start recognization
1272
        @author humkyung
1273
    '''
1274 1276
    def recognizeButtonClicked(self, event):
1275
        if self.ui.symbolTextCheckBox.isChecked() or self.ui.lineCheckBox.isChecked():
1277
        """
1278
        @brief      start recognization
1279
        @author     humkyung
1280
        @history    humkyung 2018.10.05 clear imgSrc before recognizing
1281
        """ 
1282
        if self.ui.checkBoxSymbol.isChecked() or self.ui.checkBoxText.isChecked() or self.ui.lineCheckBox.isChecked():
1283
            appDocData = AppDocData.instance()
1284
            appDocData.imgSrc = None
1285

  
1276 1286
            self.ui.recognizeButton.setEnabled(False)
1277 1287
            self.ui.buttonBox.setEnabled(False)
1278 1288
            self.ui.progressBar.setValue(0)
......
1303 1313
    def displayTitle(self, title):
1304 1314
        self.ui.labelTitle.setText(title)
1305 1315

  
1306
    '''
1316
    def startThread(self):
1317
        """
1307 1318
        @brief  start thread
1308 1319
        @author humkyung
1309 1320
        @date   2018.04.??
......
1311 1322
                    2018.05.28  Jeongwoo    Add connects (self.loadRecognitionResult, recognizeLine)
1312 1323
                    2018.05.30  Jeongwoo    Change signal name (drawDetectedItems)
1313 1324
                    humkyung 2018.06.08 connect signal to self.updateProgress
1314
    '''
1315
    def startThread(self):
1325
        """
1316 1326
        import timeit
1317 1327
        from PyQt5 import QtWidgets
1318 1328
        from App import App 
......
1324 1334
        self.obj.path = self.path
1325 1335
        self.obj.listWidget = self.ui.listWidget
1326 1336
        self.obj.graphicsView = self.graphicsView
1327
        self.obj.isSymbolTextChecked = self.ui.symbolTextCheckBox.isChecked()
1337
        self.obj.isSymbolChecked = self.ui.checkBoxSymbol.isChecked()
1338
        self.obj.isTextChecked = self.ui.checkBoxText.isChecked()
1328 1339
        self.obj.isLineChecked = self.ui.lineCheckBox.isChecked()
1329 1340
        self.thread = QThread()  # no parent!
1330 1341

  
DTI_PID/DTI_PID/Recognition_UI.py
1 1
# -*- coding: utf-8 -*-
2 2

  
3
# Form implementation generated from reading ui file '.\ui\dlgRecognition.ui'
3
# Form implementation generated from reading ui file '.\UI\Recognition.ui'
4 4
#
5
# Created by: PyQt5 UI code generator 5.10.1
5
# Created by: PyQt5 UI code generator 5.11.3
6 6
#
7 7
# WARNING! All changes made in this file will be lost!
8 8

  
......
25 25
        self.gridLayout_2.setObjectName("gridLayout_2")
26 26
        self.lineCheckBox = QtWidgets.QCheckBox(Recognition)
27 27
        self.lineCheckBox.setMaximumSize(QtCore.QSize(47, 16777215))
28
        self.lineCheckBox.setChecked(True)
28
        self.lineCheckBox.setChecked(False)
29 29
        self.lineCheckBox.setObjectName("lineCheckBox")
30
        self.gridLayout_2.addWidget(self.lineCheckBox, 0, 1, 1, 1)
31
        self.symbolTextCheckBox = QtWidgets.QCheckBox(Recognition)
32
        self.symbolTextCheckBox.setMaximumSize(QtCore.QSize(103, 16777215))
33
        self.symbolTextCheckBox.setChecked(True)
34
        self.symbolTextCheckBox.setObjectName("symbolTextCheckBox")
35
        self.gridLayout_2.addWidget(self.symbolTextCheckBox, 0, 0, 1, 1)
30
        self.gridLayout_2.addWidget(self.lineCheckBox, 0, 2, 1, 1)
31
        self.checkBoxSymbol = QtWidgets.QCheckBox(Recognition)
32
        self.checkBoxSymbol.setMaximumSize(QtCore.QSize(103, 16777215))
33
        self.checkBoxSymbol.setChecked(True)
34
        self.checkBoxSymbol.setObjectName("checkBoxSymbol")
35
        self.gridLayout_2.addWidget(self.checkBoxSymbol, 0, 0, 1, 1)
36 36
        self.recognizeButton = QtWidgets.QPushButton(Recognition)
37 37
        self.recognizeButton.setObjectName("recognizeButton")
38
        self.gridLayout_2.addWidget(self.recognizeButton, 0, 4, 1, 1, QtCore.Qt.AlignRight)
38
        self.gridLayout_2.addWidget(self.recognizeButton, 0, 5, 1, 1, QtCore.Qt.AlignRight)
39 39
        self.labelTitle = QtWidgets.QLabel(Recognition)
40 40
        palette = QtGui.QPalette()
41 41
        brush = QtGui.QBrush(QtGui.QColor(0, 0, 255))
......
55 55
        self.labelTitle.setText("")
56 56
        self.labelTitle.setAlignment(QtCore.Qt.AlignCenter)
57 57
        self.labelTitle.setObjectName("labelTitle")
58
        self.gridLayout_2.addWidget(self.labelTitle, 0, 3, 1, 1)
58
        self.gridLayout_2.addWidget(self.labelTitle, 0, 4, 1, 1)
59 59
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
60
        self.gridLayout_2.addItem(spacerItem, 0, 2, 1, 1)
60
        self.gridLayout_2.addItem(spacerItem, 0, 3, 1, 1)
61
        self.checkBoxText = QtWidgets.QCheckBox(Recognition)
62
        self.checkBoxText.setMaximumSize(QtCore.QSize(103, 16777215))
63
        self.checkBoxText.setChecked(True)
64
        self.checkBoxText.setObjectName("checkBoxText")
65
        self.gridLayout_2.addWidget(self.checkBoxText, 0, 1, 1, 1)
61 66
        self.gridLayout.addLayout(self.gridLayout_2, 0, 0, 1, 1)
62 67
        self.horizontalLayout = QtWidgets.QHBoxLayout()
63 68
        self.horizontalLayout.setObjectName("horizontalLayout")
......
86 91
        _translate = QtCore.QCoreApplication.translate
87 92
        Recognition.setWindowTitle(_translate("Recognition", "설계정보 인식"))
88 93
        self.lineCheckBox.setText(_translate("Recognition", "라인"))
89
        self.symbolTextCheckBox.setText(_translate("Recognition", "심볼 및 텍스트"))
94
        self.checkBoxSymbol.setText(_translate("Recognition", "심볼"))
90 95
        self.recognizeButton.setText(_translate("Recognition", "정보 인식"))
96
        self.checkBoxText.setText(_translate("Recognition", "텍스트"))
91 97

  
92 98

  
93 99
if __name__ == "__main__":
DTI_PID/DTI_PID/TextDetector.py
172 172
        appDocData = AppDocData.instance()
173 173

  
174 174
        try:
175
            configs = appDocData.getConfigs('Text Recognition', 'Remove White Space')
176
            removeWhiteSpace = 'True' == configs[0].value if len(configs) == 1 else False
177
            configs = appDocData.getConfigs('Text Recognition', 'OldStr')
178
            oldStr = configs[0].value if len(configs) == 1 else ''
179
            configs = appDocData.getConfigs('Text Recognition', 'NewStr')
180
            newStr = configs[0].value if len(configs) == 1 else ''
181

  
182 175
            x = tInfo.getX() - round(offset[0])
183 176
            y = tInfo.getY() - round(offset[1])
184 177
            img = imgOCR[y:y+tInfo.getH(), x:x+tInfo.getW()]
......
197 190
                for result in resultTextInfo:
198 191
                    result.setX(result.getX() + round(offset[0]))
199 192
                    result.setY(result.getY() + round(offset[1]))
200
                    if removeWhiteSpace: result.setText(result.getText().replace(' ', ''))      # remove white space - 2018.07.03 added by humkyung
201
                    if oldStr != '': result.setText(result.getText().replace(oldStr, newStr))   # replace oldStr with newStr - 2018.07.03 added by humkyung
202 193
                    if 'Instrumentation' == category:
203 194
                        text = re.sub('[^a-zA-Z0-9]+', '', result.getText())
204 195
                        result.setText(text)
DTI_PID/DTI_PID/UI/Recognition.ui
27 27
   </item>
28 28
   <item row="0" column="0">
29 29
    <layout class="QGridLayout" name="gridLayout_2">
30
     <item row="0" column="1">
30
     <item row="0" column="2">
31 31
      <widget class="QCheckBox" name="lineCheckBox">
32 32
       <property name="maximumSize">
33 33
        <size>
......
39 39
        <string>라인</string>
40 40
       </property>
41 41
       <property name="checked">
42
        <bool>true</bool>
42
        <bool>false</bool>
43 43
       </property>
44 44
      </widget>
45 45
     </item>
46 46
     <item row="0" column="0">
47
      <widget class="QCheckBox" name="symbolTextCheckBox">
47
      <widget class="QCheckBox" name="checkBoxSymbol">
48 48
       <property name="maximumSize">
49 49
        <size>
50 50
         <width>103</width>
......
52 52
        </size>
53 53
       </property>
54 54
       <property name="text">
55
        <string>심볼 및 텍스트</string>
55
        <string>심볼</string>
56 56
       </property>
57 57
       <property name="checked">
58 58
        <bool>true</bool>
59 59
       </property>
60 60
      </widget>
61 61
     </item>
62
     <item row="0" column="4" alignment="Qt::AlignRight">
62
     <item row="0" column="5" alignment="Qt::AlignRight">
63 63
      <widget class="QPushButton" name="recognizeButton">
64 64
       <property name="text">
65 65
        <string>정보 인식</string>
66 66
       </property>
67 67
      </widget>
68 68
     </item>
69
     <item row="0" column="3">
69
     <item row="0" column="4">
70 70
      <widget class="QLabel" name="labelTitle">
71 71
       <property name="palette">
72 72
        <palette>
......
119 119
       </property>
120 120
      </widget>
121 121
     </item>
122
     <item row="0" column="2">
122
     <item row="0" column="3">
123 123
      <spacer name="horizontalSpacer">
124 124
       <property name="orientation">
125 125
        <enum>Qt::Horizontal</enum>
......
132 132
       </property>
133 133
      </spacer>
134 134
     </item>
135
     <item row="0" column="1">
136
      <widget class="QCheckBox" name="checkBoxText">
137
       <property name="maximumSize">
138
        <size>
139
         <width>103</width>
140
         <height>16777215</height>
141
        </size>
142
       </property>
143
       <property name="text">
144
        <string>텍스트</string>
145
       </property>
146
       <property name="checked">
147
        <bool>true</bool>
148
       </property>
149
      </widget>
150
     </item>
135 151
    </layout>
136 152
   </item>
137 153
   <item row="4" column="0">

내보내기 Unified diff

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