프로젝트

일반

사용자정보

개정판 3d2440f0

ID3d2440f0efb0c67ffc17302453daac4caf6154db
상위 d1cf37a9
하위 2e71e478

김정우 이(가) 6년 이상 전에 추가함

Contour로 텍스트 영역 검출 함수 생성 및 환경설정에서 지정한 TypeA/B 값에 따라, Azure 혹은 Contour로 텍스트 영역 획득하도록 수정

차이점 보기:

DTI_PID/DTI_PID/Configuration_UI.py
11 11
class Ui_ConfigurationDialog(object):
12 12
    def setupUi(self, ConfigurationDialog):
13 13
        ConfigurationDialog.setObjectName("ConfigurationDialog")
14
        ConfigurationDialog.resize(550, 474)
14
        ConfigurationDialog.resize(550, 502)
15 15
        font = QtGui.QFont()
16 16
        font.setFamily("맑은 고딕")
17 17
        ConfigurationDialog.setFont(font)
......
139 139
        self.gridLayout_14.setObjectName("gridLayout_14")
140 140
        self.verticalLayout_5 = QtWidgets.QVBoxLayout()
141 141
        self.verticalLayout_5.setObjectName("verticalLayout_5")
142
        self.horizontalLayout_14 = QtWidgets.QHBoxLayout()
143
        self.horizontalLayout_14.setObjectName("horizontalLayout_14")
144
        self.label_19 = QtWidgets.QLabel(self.groupBoxText)
145
        self.label_19.setObjectName("label_19")
146
        self.horizontalLayout_14.addWidget(self.label_19)
147
        self.textAreaTypeARadioButton = QtWidgets.QRadioButton(self.groupBoxText)
148
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
149
        sizePolicy.setHorizontalStretch(0)
150
        sizePolicy.setVerticalStretch(0)
151
        sizePolicy.setHeightForWidth(self.textAreaTypeARadioButton.sizePolicy().hasHeightForWidth())
152
        self.textAreaTypeARadioButton.setSizePolicy(sizePolicy)
153
        self.textAreaTypeARadioButton.setChecked(True)
154
        self.textAreaTypeARadioButton.setObjectName("textAreaTypeARadioButton")
155
        self.buttonGroup = QtWidgets.QButtonGroup(ConfigurationDialog)
156
        self.buttonGroup.setObjectName("buttonGroup")
157
        self.buttonGroup.addButton(self.textAreaTypeARadioButton)
158
        self.horizontalLayout_14.addWidget(self.textAreaTypeARadioButton)
159
        self.textAreaTypeBRadioButton = QtWidgets.QRadioButton(self.groupBoxText)
160
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
161
        sizePolicy.setHorizontalStretch(0)
162
        sizePolicy.setVerticalStretch(0)
163
        sizePolicy.setHeightForWidth(self.textAreaTypeBRadioButton.sizePolicy().hasHeightForWidth())
164
        self.textAreaTypeBRadioButton.setSizePolicy(sizePolicy)
165
        self.textAreaTypeBRadioButton.setObjectName("textAreaTypeBRadioButton")
166
        self.buttonGroup.addButton(self.textAreaTypeBRadioButton)
167
        self.horizontalLayout_14.addWidget(self.textAreaTypeBRadioButton)
168
        self.textAreaHelpLabel = QtWidgets.QLabel(self.groupBoxText)
169
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
170
        sizePolicy.setHorizontalStretch(0)
171
        sizePolicy.setVerticalStretch(0)
172
        sizePolicy.setHeightForWidth(self.textAreaHelpLabel.sizePolicy().hasHeightForWidth())
173
        self.textAreaHelpLabel.setSizePolicy(sizePolicy)
174
        self.textAreaHelpLabel.setMinimumSize(QtCore.QSize(20, 20))
175
        self.textAreaHelpLabel.setMaximumSize(QtCore.QSize(20, 20))
176
        self.textAreaHelpLabel.setText("")
177
        self.textAreaHelpLabel.setTextFormat(QtCore.Qt.AutoText)
178
        self.textAreaHelpLabel.setPixmap(QtGui.QPixmap("../res/info.png"))
179
        self.textAreaHelpLabel.setScaledContents(True)
180
        self.textAreaHelpLabel.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
181
        self.textAreaHelpLabel.setObjectName("textAreaHelpLabel")
182
        self.horizontalLayout_14.addWidget(self.textAreaHelpLabel)
183
        self.verticalLayout_5.addLayout(self.horizontalLayout_14)
142 184
        self.horizontalLayout_13 = QtWidgets.QHBoxLayout()
143 185
        self.horizontalLayout_13.setObjectName("horizontalLayout_13")
144 186
        self.label_17 = QtWidgets.QLabel(self.groupBoxText)
......
328 370
        self.label_2.setText(_translate("ConfigurationDialog", "Delimiter : "))
329 371
        self.pushButtonAddProperty.setText(_translate("ConfigurationDialog", "추가"))
330 372
        self.groupBoxText.setTitle(_translate("ConfigurationDialog", "텍스트 검출"))
373
        self.label_19.setText(_translate("ConfigurationDialog", "텍스트 영역 검출 방식 : "))
374
        self.textAreaTypeARadioButton.setText(_translate("ConfigurationDialog", "Type A"))
375
        self.textAreaTypeBRadioButton.setText(_translate("ConfigurationDialog", "Type B"))
331 376
        self.label_17.setText(_translate("ConfigurationDialog", "Minimum Text Size : "))
332 377
        self.label_18.setText(_translate("ConfigurationDialog", "Maximum Text Size : "))
333 378
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.Recognition), _translate("ConfigurationDialog", "인식"))
DTI_PID/DTI_PID/DTI_PID.py
705 705
    @date       
706 706
    @history    humkyung 2018.04.06 check if file exists
707 707
                Jeongwoo 2018.05.09 Use Tesseract OCR after Azure OCR (Azure OCR : Getting text area)
708
                Jeongwoo 2018.05.25 Add condition on if-statemen
708
                Jeongwoo 2018.05.25 Add condition on if-statement
709
                Jeongwoo 2018.06.05 Get text area data list by config.type
709 710
'''
710 711
def initMainSrc(mainRes):
711 712
    global srcGray
......
718 719
            ocrCompletedSrc = srcGray.copy()
719 720

  
720 721
            area = AppDocData.instance().getArea('Drawing')
721

  
722
            configs = AppDocData.instance().getConfigs('Text Area', 'Text Area')
723
            type = int(configs[0].value) if 1 == len(configs) else 0
722 724
            #(_tempOcrSrc, textInfoList) = OCR.removeTextFromNpArray(area.img if area is not None else srcGray, area.x if area is not None else 0, area.y if area is not None else 0)
723
            (_tempOcrSrc, tInfoList) = OCR.removeTextFromNpArray(area.img if area is not None else srcGray, area.x if area is not None else 0, area.y if area is not None else 0)
725
            tInfoList = []
726
            if type == 0:
727
                (_tempOcrSrc, tInfoList) = OCR.removeTextFromNpArray(area.img if area is not None else srcGray, area.x if area is not None else 0, area.y if area is not None else 0)
728
            else:
729
                tInfoList = getTextAreaInfo(area.img if area is not None else srcGray, area.x if area is not None else 0, area.y if area is not None else 0)
724 730
            
725 731
            global MIN_TEXT_SIZE
726 732
            for tInfo in tInfoList:
......
983 989
        print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
984 990
    
985 991
    #return res
992

  
993
'''
994
    @brief      Get Text Area info by contour
995
    @author     Jeongwoo
996
    @date       2018.06.05
997
'''
998
def getTextAreaInfo(imgGray, offsetX, offsetY):
999
    contourImg = np.ones(imgGray.shape, np.uint8) * 255
1000
    contourOcrImg = contourImg.copy()
1001
    binaryImg,mask = cv2.threshold(imgGray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
1002
    
1003
    image, contours, hierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
1004
    for contour in contours:
1005
        area = cv2.contourArea(contour, True)
1006
        if area >= 0:
1007
            [x, y, w, h] = cv2.boundingRect(contour)
1008

  
1009
            # remove too big or small one
1010
            if (w > 100 or h > 100) or (w < 5 or h < 5): continue
1011

  
1012
            cv2.drawContours(contourImg, [contour], -1, (0,0,0), 1)
1013
            cv2.drawContours(contourOcrImg, [contour], -1, (0,0,0), -1)
1014
        else:
1015
            cv2.drawContours(contourOcrImg, [contour], -1, (255,255,255), -1)
1016

  
1017
    rects = []
1018
    kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (8, 8))
1019
    eroded = cv2.erode(contourImg, kernel)
1020
    image, contours, hierarchy = cv2.findContours(eroded, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
1021
    for contour in contours:
1022
        area = cv2.contourArea(contour, True)
1023
        if area >= 0:
1024
            [x, y, w, h] = cv2.boundingRect(contour)
1025
            # remove small one less than character size
1026
            if (w < 20 or h < 20): continue
1027
            rects.append(QRect(x, y, w, h)) # expand rect
1028

  
1029
    intersected = True
1030
    while intersected:
1031
        intersected = False
1032
        for rect in rects[:]:
1033
            matches = [x for x in rects if rect.intersects(x)]
1034
            if len(matches) > 1:
1035
                united = matches[0]
1036
                for _rect in matches:
1037
                    united = united.united(_rect)
1038
                    if _rect in rects: rects.remove(_rect)
1039
                rects.append(united)
1040
                intersected = True
1041
                break
1042

  
1043
    list = []
1044
    for rect in rects:
1045
        list.append(ti.TextInfo('', int(offsetX) + rect.x(), int(offsetY) + rect.y(), rect.width(), rect.height(), 0))
1046
    return list
986 1047
    
987 1048
if __name__ == '__main__':
988 1049
    import DTI_PID_UI
......
993 1054

  
994 1055
    start = timeit.default_timer()
995 1056
    img = cv2.imread('D:/Visual Studio Project/DTIPID/DTIPID/DTI_PID/DTI_PID/res/Result/PC-K/PC-K-2203_P1_800DPI.png', 1)
996
    ocrImg = img.copy()
997 1057
    imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
998 1058
    contourImg = np.ones(imgGray.shape, np.uint8)*255
999 1059
    contourOcrImg = contourImg.copy()
DTI_PID/DTI_PID/QConfigurationDialog.py
45 45
                    humkyung 2018.05.09 read line no tag rule configuration
46 46
                    Jeongwoo 2018.05.18 read Small Line Minimum Length
47 47
                    Jeongwoo 2018.06.04 read Min/Max Text Size
48
                    Jeongwoo 2018.06.05 read Text Area Detection Method
48 49
    '''
49 50
    def __init__(self, parent):
50 51
        QDialog.__init__(self, parent)
......
58 59
        self.itemModel = QStandardItemModel()
59 60

  
60 61
        docData = AppDocData.instance()
62
        configs = docData.getConfigs('Text Area', 'Text Area')
63
        value = int(configs[0].value) if 1 == len(configs) else 0
64
        if value == 0:
65
            self.ui.textAreaTypeARadioButton.setChecked(True)
66
        else:
67
            self.ui.textAreaTypeBRadioButton.setChecked(True)
68

  
61 69
        configs = docData.getConfigs('Text Size', 'Min Text Size')
62 70
        self.ui.minTextSizeSpinBox.setValue(int(configs[0].value)) if 1 == len(configs) else self.ui.minTextSizeSpinBox.setValue(30)
63 71
        configs = docData.getConfigs('Text Size', 'Max Text Size')
......
156 164
                    humkyung 2018.05.09 save line no tag rule
157 165
                    Jeongwoo 2018.05.18 save Small Line Minimum Length
158 166
                    Jeongwoo 2018.06.04 save Min/Max Text Size
167
                    Jeongwoo 2018.06.05 save Text Area Detection Method
159 168
    '''
160 169
    def accept(self):
161 170
        try:
162 171
            self.isAccepted = True
163 172

  
164 173
            configs = []
174
            configs.append(Config('Text Area', 'Text Area', 0 if self.ui.textAreaTypeARadioButton.isChecked() else 1))
165 175
            configs.append(Config('Text Size', 'Min Text Size', self.ui.minTextSizeSpinBox.value()))
166 176
            configs.append(Config('Text Size', 'Max Text Size', self.ui.maxTextSizeSpinBox.value()))
167 177
            configs.append(Config('Size', 'Delimiter', self.ui.lineEditSizeDelimiter.text()))
DTI_PID/DTI_PID/UI/Configuration.ui
7 7
    <x>0</x>
8 8
    <y>0</y>
9 9
    <width>550</width>
10
    <height>474</height>
10
    <height>502</height>
11 11
   </rect>
12 12
  </property>
13 13
  <property name="font">
......
228 228
          <item row="0" column="0">
229 229
           <layout class="QVBoxLayout" name="verticalLayout_5">
230 230
            <item>
231
             <layout class="QHBoxLayout" name="horizontalLayout_14">
232
              <item>
233
               <widget class="QLabel" name="label_19">
234
                <property name="text">
235
                 <string>텍스트 영역 검출 방식 : </string>
236
                </property>
237
               </widget>
238
              </item>
239
              <item>
240
               <widget class="QRadioButton" name="textAreaTypeARadioButton">
241
                <property name="sizePolicy">
242
                 <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
243
                  <horstretch>0</horstretch>
244
                  <verstretch>0</verstretch>
245
                 </sizepolicy>
246
                </property>
247
                <property name="text">
248
                 <string>Type A</string>
249
                </property>
250
                <property name="checked">
251
                 <bool>true</bool>
252
                </property>
253
                <attribute name="buttonGroup">
254
                 <string notr="true">buttonGroup</string>
255
                </attribute>
256
               </widget>
257
              </item>
258
              <item>
259
               <widget class="QRadioButton" name="textAreaTypeBRadioButton">
260
                <property name="sizePolicy">
261
                 <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
262
                  <horstretch>0</horstretch>
263
                  <verstretch>0</verstretch>
264
                 </sizepolicy>
265
                </property>
266
                <property name="text">
267
                 <string>Type B</string>
268
                </property>
269
                <attribute name="buttonGroup">
270
                 <string notr="true">buttonGroup</string>
271
                </attribute>
272
               </widget>
273
              </item>
274
              <item>
275
               <widget class="QLabel" name="textAreaHelpLabel">
276
                <property name="sizePolicy">
277
                 <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
278
                  <horstretch>0</horstretch>
279
                  <verstretch>0</verstretch>
280
                 </sizepolicy>
281
                </property>
282
                <property name="minimumSize">
283
                 <size>
284
                  <width>20</width>
285
                  <height>20</height>
286
                 </size>
287
                </property>
288
                <property name="maximumSize">
289
                 <size>
290
                  <width>20</width>
291
                  <height>20</height>
292
                 </size>
293
                </property>
294
                <property name="text">
295
                 <string/>
296
                </property>
297
                <property name="textFormat">
298
                 <enum>Qt::AutoText</enum>
299
                </property>
300
                <property name="pixmap">
301
                 <pixmap>../res/info.png</pixmap>
302
                </property>
303
                <property name="scaledContents">
304
                 <bool>true</bool>
305
                </property>
306
                <property name="alignment">
307
                 <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
308
                </property>
309
               </widget>
310
              </item>
311
             </layout>
312
            </item>
313
            <item>
231 314
             <layout class="QHBoxLayout" name="horizontalLayout_13">
232 315
              <item alignment="Qt::AlignLeft">
233 316
               <widget class="QLabel" name="label_17">
......
542 625
   </hints>
543 626
  </connection>
544 627
 </connections>
628
 <buttongroups>
629
  <buttongroup name="buttonGroup"/>
630
 </buttongroups>
545 631
</ui>

내보내기 Unified diff

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