프로젝트

일반

사용자정보

개정판 b3bd19f3

IDb3bd19f3f4ee0515c5d263e3e4d0e2514f27c0cd
상위 315bbbd4
하위 8516a808

함의성이(가) 약 5년 전에 추가함

issue #49: add code table auto fill function

Change-Id: I715ee026c1b3e1d09575e7a9097a1e0b9002b487

차이점 보기:

DTI_PID/DTI_PID/CodeTableDialog.py
3 3
    This is code table dialog module
4 4
"""
5 5
import os
6
import sys
6
import sys, io
7 7
from PyQt5.QtCore import *
8 8
from PyQt5.QtGui import *
9 9
from PyQt5.QtWidgets import *
10 10
from AppDocData import AppDocData, MessageType
11 11
from openpyxl import *
12 12
from openpyxl.styles import *
13

  
14
from PIL import Image
15
import tesseract_ocr_module as TOCR
16
import numpy as np
17

  
13 18
import CodeTable_UI
19
import FenceCommand
20
from GraphicsBoundingBoxItem import QGraphicsBoundingBoxItem
14 21

  
15 22
class QCodeTableDialog(QDialog):
16 23
    """ This code table dialog class """
......
27 34
        self.ui = CodeTable_UI.Ui_CodeTableDialog()
28 35
        self.ui.setupUi(self)
29 36

  
37
        self.code_area = None
38
        self.desc_area = None
39
        self.ui.spinBoxHeight.setValue(50)
40

  
30 41
        self.ui.tableWidgetNominalDiameter.setSortingEnabled(True)
31 42
        self.ui.tableWidgetFluidCode.setSortingEnabled(True)
32 43
        self.ui.tableWidgetInsulationPurpose.setSortingEnabled(True)
......
44 55
        # connect signals
45 56
        self.ui.pushButtonImport.clicked.connect(self.import_code_table)
46 57
        self.ui.pushButtonExport.clicked.connect(self.export_code_table)
58
        self.ui.pushButtonRead.clicked.connect(self.read_from_legend)
59

  
60
        self.fence_cmd = FenceCommand.FenceCommand(self.parent().graphicsView)
61
        self.fence_cmd.onSuccess.connect(self.onAreaCreated)
62

  
63
    def read_from_legend(self):
64
        """ read code data from legend drawing """
65
        if self.ui.pushButtonRead.text() == 'Read from Legend':
66
            self.parent().graphicsView.command = self.fence_cmd
67
            self.ui.pushButtonRead.setText('Draw Code Area')
68
        elif self.ui.pushButtonRead.text() == 'Read' and self.code_area and self.code_area.scene() and self.desc_area and self.desc_area.scene():
69
            # read ocr
70
            code_rect = self.code_area.sceneBoundingRect()
71
            desc_rect = self.desc_area.sceneBoundingRect()
72
            code_img = self.parent().graphicsView.image().copy(code_rect.x(), code_rect.y(), code_rect.width(), code_rect.height())
73
            desc_img = self.parent().graphicsView.image().copy(desc_rect.x(), desc_rect.y(), desc_rect.width(), desc_rect.height())
74
            code_texts = self.detectText(code_img, code_rect)
75
            desc_texts = self.detectText(desc_img, desc_rect)
76

  
77
            # check validate
78
            for code_text in code_texts:
79
                code_text.desc = []
80

  
81
            for desc_index in reversed(range(len(desc_texts))):
82
                for code_index in range(len(code_texts)):
83
                    if abs(desc_texts[desc_index].center[1] - code_texts[code_index].center[1]) < round(self.ui.spinBoxHeight.value() / 2):
84
                        code_texts[code_index].desc.append(desc_texts[desc_index])
85
                        desc_texts.pop(desc_index)
86
                        break
87

  
88
            for desc_index in reversed(range(len(desc_texts))):
89
                min_distance = sys.maxsize
90
                min_code = None
91
                for code_index in range(len(code_texts)):
92
                    distance = desc_texts[desc_index].center[1] - code_texts[code_index].center[1]
93
                    if distance > 0 and distance < min_distance:
94
                        min_distance = distance
95
                        min_code = code_texts[code_index]
96

  
97
                if min_code:
98
                    min_code.desc.append(desc_texts[desc_index])
99
                    desc_texts.pop(desc_index)
100
                    
101
            if desc_texts:
102
                QMessageBox.warning(self, self.tr('Notice'), self.tr('Please check text area.'))
103
                return
104

  
105
            for code_text in code_texts:
106
                desc = ' '.join([desc.getText() for desc in sorted(code_text.desc, key=lambda desc: desc.center[1])])
107
                desc_texts.append(desc)
108

  
109
            # fill table
110
            _tabWidget = self.ui.tabWidget
111
            currentTabIndex = _tabWidget.currentIndex()
112
            tabText = self.replaceText(_tabWidget.tabText(currentTabIndex))
113
            if tabText == 'NominalDiameter':
114
                return
115
            table = self.findTableWidget(tabText)
116

  
117
            table.cellChanged.disconnect(self.cellValueChanged)
118
            
119
            past_count = table.rowCount()
120
            for row_index in range(past_count):
121
                for code_index in reversed(range(len(code_texts))):
122
                    if table.isRowHidden(row_index): continue
123
                    if table.item(row_index, 1).text() == code_texts[code_index].getText():
124
                        table.setItem(row_index, 2, QTableWidgetItem(desc_texts[code_index]))
125
                        code_texts.pop(code_index)
126
                        desc_texts.pop(code_index)
127
                        break
128
            table.setRowCount(past_count + len(code_texts))
129
            for code_index in range(len(code_texts)):
130
                table.setItem(past_count + code_index - 1, 0, QTableWidgetItem(''))
131
                table.setItem(past_count + code_index - 1, 1, QTableWidgetItem(code_texts[code_index].getText()))
132
                table.setItem(past_count + code_index - 1, 2, QTableWidgetItem(desc_texts[code_index]))
133

  
134
            table.cellChanged.connect(self.cellValueChanged)
135

  
136
            if self.code_area:
137
                if self.code_area.scene():
138
                    self.parent().graphicsView.scene.removeItem(self.code_area)
139
                self.code_area = None
140
            if self.desc_area:
141
                if self.desc_area.scene():
142
                    self.parent().graphicsView.scene.removeItem(self.desc_area)
143
                self.desc_area = None
144
            self.ui.pushButtonRead.setText('Read from Legend')
145
        else:
146
            if self.code_area:
147
                if self.code_area.scene():
148
                    self.parent().graphicsView.scene.removeItem(self.code_area)
149
                self.code_area = None
150
            if self.desc_area:
151
                if self.desc_area.scene():
152
                    self.parent().graphicsView.scene.removeItem(self.desc_area)
153
                self.desc_area = None
154
            self.ui.pushButtonRead.setText('Read from Legend')
155

  
156
    def onAreaCreated(self, x, y , width, height):
157
        import uuid
158
        THICKNESS = 5
159

  
160
        if self.ui.pushButtonRead.text() == 'Draw Code Area':
161
            item = QGraphicsBoundingBoxItem(x, y, width, height)
162
            item.setPen(QPen(Qt.red, THICKNESS, Qt.SolidLine))
163
            self.parent().graphicsView.scene.addItem(item)
164
            self.code_area = item
165
            self.ui.pushButtonRead.setText('Draw Description Area')
166
        elif self.ui.pushButtonRead.text() == 'Draw Description Area' and self.code_area and self.code_area.scene():
167
            item = QGraphicsBoundingBoxItem(x, y, width, height)
168
            item.setPen(QPen(Qt.blue, THICKNESS, Qt.SolidLine))
169
            self.parent().graphicsView.scene.addItem(item)
170
            self.desc_area = item
171
            self.ui.pushButtonRead.setText('Read')
172
            self.parent().graphicsView.command = None
173

  
174
    def detectText(self, image, rect):
175
        """ detect text from image, come from OcrResultDialog and modified """
176
        try:
177
            buffer = QBuffer()
178
            buffer.open(QBuffer.ReadWrite)
179
            image.save(buffer, "PNG")
180
            pyImage = Image.open(io.BytesIO(buffer.data()))
181
            img = np.array(pyImage)
182
            
183
            docData = AppDocData.instance()
184
            configs = docData.getConfigs('Text Recognition', 'OCR Data')
185
            ocr_data = configs[0].value if 1 == len(configs) else 'eng'
186

  
187
            whiteCharList = docData.getConfigs('Text Recognition', 'White Character List')
188
            if len(whiteCharList) is 0:
189
                textInfoList = TOCR.getTextInfo(img, (round(rect.x()), round(rect.y())), 0, language=ocr_data)
190
            else:
191
                textInfoList = TOCR.getTextInfo(img, (round(rect.x()), round(rect.y())), 0, language=ocr_data, conf = whiteCharList[0].value)
192

  
193
            if textInfoList is not None and len(textInfoList) > 0:
194
                return textInfoList
195
        except Exception as ex:
196
            from App import App 
197
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
198
            App.mainWnd().addMessage.emit(MessageType.Error, message)
47 199

  
48 200
    '''
49 201
        @brief      Setting Table
......
264 416
                    else:
265 417
                        QMessageBox.warning(self, self.tr('Notice'),
266 418
                                            self.tr('The same code already exists in the table.'))
419
                        table.cellChanged.disconnect(self.cellValueChanged)
267 420
                        item.setText(self.currentCode[tabText][row])
421
                        table.cellChanged.connect(self.cellValueChanged)
268 422
                elif column == 2:
269 423
                    table.resizeColumnToContents(2)
270 424
                else:
DTI_PID/DTI_PID/CodeTable_UI.py
1 1
# -*- coding: utf-8 -*-
2 2

  
3
# Form implementation generated from reading ui file '.\UI\CodeTable.ui'
3
# Form implementation generated from reading ui file './UI/CodeTable.ui'
4 4
#
5
# Created by: PyQt5 UI code generator 5.13.0
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

  
9

  
10 9
from PyQt5 import QtCore, QtGui, QtWidgets
11 10

  
12

  
13 11
class Ui_CodeTableDialog(object):
14 12
    def setupUi(self, CodeTableDialog):
15 13
        CodeTableDialog.setObjectName("CodeTableDialog")
......
20 18
        icon = QtGui.QIcon()
21 19
        icon.addPixmap(QtGui.QPixmap(":/newPrefix/codetable.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
22 20
        CodeTableDialog.setWindowIcon(icon)
23
        CodeTableDialog.setModal(True)
21
        CodeTableDialog.setModal(False)
24 22
        self.gridLayout = QtWidgets.QGridLayout(CodeTableDialog)
25 23
        self.gridLayout.setObjectName("gridLayout")
26 24
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
27 25
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
26
        self.label = QtWidgets.QLabel(CodeTableDialog)
27
        self.label.setObjectName("label")
28
        self.horizontalLayout_2.addWidget(self.label)
29
        self.spinBoxHeight = QtWidgets.QSpinBox(CodeTableDialog)
30
        self.spinBoxHeight.setMaximum(100)
31
        self.spinBoxHeight.setObjectName("spinBoxHeight")
32
        self.horizontalLayout_2.addWidget(self.spinBoxHeight)
33
        self.pushButtonRead = QtWidgets.QPushButton(CodeTableDialog)
34
        self.pushButtonRead.setObjectName("pushButtonRead")
35
        self.horizontalLayout_2.addWidget(self.pushButtonRead)
28 36
        self.pushButtonImport = QtWidgets.QPushButton(CodeTableDialog)
29 37
        self.pushButtonImport.setObjectName("pushButtonImport")
30 38
        self.horizontalLayout_2.addWidget(self.pushButtonImport)
......
237 245
    def retranslateUi(self, CodeTableDialog):
238 246
        _translate = QtCore.QCoreApplication.translate
239 247
        CodeTableDialog.setWindowTitle(_translate("CodeTableDialog", "Code Table"))
248
        self.label.setText(_translate("CodeTableDialog", "Line Height : "))
249
        self.pushButtonRead.setText(_translate("CodeTableDialog", "Read from Legend"))
240 250
        self.pushButtonImport.setText(_translate("CodeTableDialog", "Import"))
241 251
        self.pushButtonExport.setText(_translate("CodeTableDialog", "Export"))
242 252
        self.groupBox.setTitle(_translate("CodeTableDialog", "Nominal Diameter"))
......
265 275
        item = self.tableWidgetDictionary.horizontalHeaderItem(2)
266 276
        item.setText(_translate("CodeTableDialog", "3"))
267 277
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tabDIctionary), _translate("CodeTableDialog", "Dictionary"))
278

  
268 279
import MainWindow_rc
280

  
281
if __name__ == "__main__":
282
    import sys
283
    app = QtWidgets.QApplication(sys.argv)
284
    CodeTableDialog = QtWidgets.QDialog()
285
    ui = Ui_CodeTableDialog()
286
    ui.setupUi(CodeTableDialog)
287
    CodeTableDialog.show()
288
    sys.exit(app.exec_())
289

  
DTI_PID/DTI_PID/MainWindow.py
1158 1158
        from CodeTableDialog import QCodeTableDialog
1159 1159

  
1160 1160
        dlg = QCodeTableDialog(self)
1161
        dlg.show()
1161 1162
        dlg.exec_()
1163
        if dlg.code_area:
1164
            if dlg.code_area.scene():
1165
                self.graphicsView.scene.removeItem(dlg.code_area)
1166
        if dlg.desc_area:
1167
            if dlg.desc_area.scene():
1168
                self.graphicsView.scene.removeItem(dlg.desc_area)
1169
        self.graphicsView.useDefaultCommand()
1162 1170

  
1163 1171
    '''
1164 1172
        @brief  show HMB data
DTI_PID/DTI_PID/OcrResultDialog.py
51 51
        self.ui.redetectPushButton_2.clicked.connect(self.detectText)
52 52
        self.ui.pushButtonMakeTrainingImage.clicked.connect(self.pushButtonMakeTrainingImageClicked)
53 53

  
54
        self.ui.comboBoxOCRData.addItem('eng')
55
        tessdata_path = os.path.join(os.getenv('ALLUSERSPROFILE'), 'Digital PID', 'Tesseract-OCR', 'tessdata')
56
        if os.path.isfile(os.path.join(tessdata_path, appDocData.getCurrentProject().getName() + '.traineddata')):
57
            self.ui.comboBoxOCRData.addItem(appDocData.getCurrentProject().getName())
58

  
59
        configs = appDocData.getConfigs('Text Recognition', 'OCR Data')
60
        value = configs[0].value if 1 == len(configs) else ''
61
        if value:
62
            at = self.ui.comboBoxOCRData.findText(value)
63
            self.ui.comboBoxOCRData.setCurrentIndex(at)
64
        else:
65
            self.ui.comboBoxOCRData.selectedIndex = 0
66

  
54 67
        if self.isModify == False:
55 68
            self.detectText()
56 69
        else:
......
111 124

  
112 125
            docData = AppDocData.instance()
113 126
            
127
            '''
114 128
            # get ocr data of area which has the text
115 129
            pt = self.boundingBox.center()
116 130
            areas = [area for area in docData.getAreaList() if area.contains((pt.x(), pt.y()))]
117 131
            ocr_data = sorted(areas, key=lambda attr: attr.area)[0].OCRData if areas else 'eng'
118 132
            # up to here
133
            '''
134
            ocr_data = self.ui.comboBoxOCRData.currentText()
119 135

  
120 136
            whiteCharList = docData.getConfigs('Text Recognition', 'White Character List')
121 137
            if len(whiteCharList) is 0:
DTI_PID/DTI_PID/OcrResultDialog_UI.py
44 44
        self.targetTextLabel_2.setFont(font)
45 45
        self.targetTextLabel_2.setObjectName("targetTextLabel_2")
46 46
        self.horizontalLayout.addWidget(self.targetTextLabel_2)
47
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
48
        self.horizontalLayout.addItem(spacerItem)
49
        self.label = QtWidgets.QLabel(self.topWidget)
50
        self.label.setObjectName("label")
51
        self.horizontalLayout.addWidget(self.label)
52
        self.comboBoxOCRData = QtWidgets.QComboBox(self.topWidget)
53
        self.comboBoxOCRData.setObjectName("comboBoxOCRData")
54
        self.horizontalLayout.addWidget(self.comboBoxOCRData)
47 55
        self.counterClockPushButton_2 = QtWidgets.QPushButton(self.topWidget)
48 56
        self.counterClockPushButton_2.setMinimumSize(QtCore.QSize(0, 60))
49 57
        self.counterClockPushButton_2.setMaximumSize(QtCore.QSize(60, 60))
......
97 105
        self.detectResultLabel_2.setFont(font)
98 106
        self.detectResultLabel_2.setObjectName("detectResultLabel_2")
99 107
        self.horizontalLayout_3.addWidget(self.detectResultLabel_2)
100
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
101
        self.horizontalLayout_3.addItem(spacerItem)
108
        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
109
        self.horizontalLayout_3.addItem(spacerItem1)
102 110
        self.checkBoxSeperate = QtWidgets.QCheckBox(self.bottomWidget)
103 111
        self.checkBoxSeperate.setChecked(True)
104 112
        self.checkBoxSeperate.setObjectName("checkBoxSeperate")
......
139 147
        _translate = QtCore.QCoreApplication.translate
140 148
        Dialog.setWindowTitle(_translate("Dialog", "OCR"))
141 149
        self.targetTextLabel_2.setText(_translate("Dialog", "Recognition Object"))
150
        self.label.setText(_translate("Dialog", "OCR Source : "))
142 151
        self.counterClockPushButton_2.setToolTip(_translate("Dialog", "반시계 방향 회전"))
143 152
        self.clockPushButton_2.setToolTip(_translate("Dialog", "시계 방향 회전"))
144 153
        self.detectResultLabel_2.setText(_translate("Dialog", "Recognition Result"))
DTI_PID/DTI_PID/TrainingSymbolEditorDialog.py
150 150
    def listCellClicked(self, row, col):
151 151
        self.isChanged = True
152 152
        items = self.graphicsViewTrainingDrawing.scene.selectedItems()
153
        if (len(items) is not 1):
154
            return
155 153
        label = self.ui.tableWidget.item(row, col).text()
156 154
        self.onCharChanged(label)
157 155

  
......
233 231
    def pushButtonChangeClicked(self):
234 232
        self.isChanged = True
235 233
        items = self.graphicsViewTrainingDrawing.scene.selectedItems()
236
        if len(items) is not 1:
237
            return
238 234

  
239 235
        label = self.ui.lineEditChar.text()
240 236
        if label == '' or label == 'None':
241 237
            return
242 238

  
243
        items[0].char = label
244
        items[0].textShowBox.setHtml(label)
239
        for box in [box for box in items if type(box) is QTrainingBoxItem]:
240
            box.char = label
241
            box.textShowBox.setHtml(label)
245 242

  
246 243
        rowCount = self.ui.tableWidget.rowCount()
247 244
        for index in range(rowCount):
......
434 431
    def keyPressEvent(self, event):
435 432
        try:
436 433
            items = self.graphicsViewTrainingDrawing.scene.selectedItems()
437
            if len(items) is not 1 or type(items[0]) is not QTrainingBoxItem:
434
            if items and type(items[0]) is not QTrainingBoxItem:
438 435
                return
436
                
439 437
            selectedItem = items[0]
440 438
            closestItem = None
441 439
            x = selectedItem.rect().x()
......
469 467
            elif event.key() == Qt.Key_Return and not self.ui.lineEditChar.hasFocus():
470 468
                if self.ui.tableWidget.selectedItems():
471 469
                    self.isChanged = True
472
                    self.onCharChanged(self.ui.tableWidget.selectedItems()[0].text())                    
470
                    self.onCharChanged(self.ui.tableWidget.selectedItems()[0].text())
473 471
        except Exception as ex:
474 472
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
475 473
            from App import App
DTI_PID/DTI_PID/UI/CodeTable.ui
23 23
    <normaloff>:/newPrefix/codetable.png</normaloff>:/newPrefix/codetable.png</iconset>
24 24
  </property>
25 25
  <property name="modal">
26
   <bool>true</bool>
26
   <bool>false</bool>
27 27
  </property>
28 28
  <layout class="QGridLayout" name="gridLayout">
29 29
   <item row="2" column="0">
30 30
    <layout class="QHBoxLayout" name="horizontalLayout_2">
31 31
     <item>
32
      <widget class="QLabel" name="label">
33
       <property name="text">
34
        <string>Line Height : </string>
35
       </property>
36
      </widget>
37
     </item>
38
     <item>
39
      <widget class="QSpinBox" name="spinBoxHeight">
40
       <property name="maximum">
41
        <number>100</number>
42
       </property>
43
      </widget>
44
     </item>
45
     <item>
46
      <widget class="QPushButton" name="pushButtonRead">
47
       <property name="text">
48
        <string>Read from Legend</string>
49
       </property>
50
      </widget>
51
     </item>
52
     <item>
32 53
      <widget class="QPushButton" name="pushButtonImport">
33 54
       <property name="text">
34 55
        <string>Import</string>
DTI_PID/DTI_PID/UI/OcrResultDialog.ui
85 85
            </widget>
86 86
           </item>
87 87
           <item>
88
            <spacer name="horizontalSpacer_2">
89
             <property name="orientation">
90
              <enum>Qt::Horizontal</enum>
91
             </property>
92
             <property name="sizeHint" stdset="0">
93
              <size>
94
               <width>40</width>
95
               <height>20</height>
96
              </size>
97
             </property>
98
            </spacer>
99
           </item>
100
           <item>
101
            <widget class="QLabel" name="label">
102
             <property name="text">
103
              <string>OCR Source : </string>
104
             </property>
105
            </widget>
106
           </item>
107
           <item>
108
            <widget class="QComboBox" name="comboBoxOCRData"/>
109
           </item>
110
           <item>
88 111
            <widget class="QPushButton" name="counterClockPushButton_2">
89 112
             <property name="minimumSize">
90 113
              <size>

내보내기 Unified diff

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