프로젝트

일반

사용자정보

개정판 ae3a61a6

IDae3a61a6def4860f84dd001e553a0755a40b7619
상위 cd46c9ff
하위 0dde3765

백흠경이(가) 약 5년 전에 추가함

issue #1124: Title Block 속성 설정하지 않았을때 발생 오류 수정

Change-Id: Id639a748dac50843f08eab92b1564d3918d5a1a5

차이점 보기:

DTI_PID/DTI_PID/AppDocData.py
892 892
        self._titleBlockProperties = None
893 893

  
894 894
    def getTitleBlockProperties(self):
895
        '''
896
            @brief  return title block properties
897
            @author euisung
898
            @date   2018.11.09
899
        '''
895
        """"return title block properties"""
896

  
900 897
        res = None
901 898
        if self._titleBlockProperties is None:
902 899
            self._titleBlockProperties = []
DTI_PID/DTI_PID/ItemDataExportDialog.py
614 614
    def fill_special_items(self):
615 615
        """ fill table widget with special items """
616 616

  
617
        app_doc_data = AppDocData.instance()
618
        drawings = self.checked_drawings
619
        special_items = app_doc_data.get_special_items(drawings if drawings else None)
620
        merged_special_items = []
621
        for item in special_items:
622
            matches = [merged for merged in merged_special_items if merged['Line No'] == item[0]]
623
            if matches:
624
                matches[item[1]] = 'O'
625
            else:
626
                merged_special_items.append({'Line No': item[0], item[1]: 'O'})
617
        try:
618
            app_doc_data = AppDocData.instance()
619
            drawings = self.checked_drawings
620
            special_items = app_doc_data.get_special_items(drawings if drawings else None)
621
            merged_special_items = []
622
            for item in special_items:
623
                matches = [merged for merged in merged_special_items if merged['Line No'] == item[0]]
624
                if matches:
625
                    matches[0][item[1]] = 'O'
626
                else:
627
                    merged_special_items.append({'Line No': item[0], item[1]: 'O'})
627 628

  
628
        self.ui.tableWidgetSpecialItems.setRowCount(len(merged_special_items))
629
            self.ui.tableWidgetSpecialItems.setRowCount(len(merged_special_items))
629 630

  
630
        row = 0
631
        for item in merged_special_items:
632
            for col in range(self.ui.tableWidgetSpecialItems.columnCount()):
633
                if self.ui.tableWidgetSpecialItems.isColumnHidden(col): continue
634
                col_name = self.ui.tableWidgetSpecialItems.horizontalHeaderItem(col).text()
635
                widget_item = QTableWidgetItem(item[col_name]) if col_name in item.keys() else QTableWidgetItem('X')
636
                widget_item.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
637
                widget_item.setFlags(Qt.ItemIsEnabled)
638
                self.ui.tableWidgetSpecialItems.setItem(row, col, widget_item)
639
            row += 1
631
            row = 0
632
            for item in merged_special_items:
633
                for col in range(self.ui.tableWidgetSpecialItems.columnCount()):
634
                    if self.ui.tableWidgetSpecialItems.isColumnHidden(col): continue
635
                    col_name = self.ui.tableWidgetSpecialItems.horizontalHeaderItem(col).text()
636
                    widget_item = QTableWidgetItem(item[col_name]) if col_name in item.keys() else QTableWidgetItem('X')
637
                    widget_item.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
638
                    widget_item.setFlags(Qt.ItemIsEnabled)
639
                    self.ui.tableWidgetSpecialItems.setItem(row, col, widget_item)
640
                row += 1
641
        except Exception as ex:
642
            from App import App
643
            from AppDocData import MessageType
644

  
645
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
646
                                                           sys.exc_info()[-1].tb_lineno)
647
            App.mainWnd().addMessage.emit(MessageType.Error, message)
640 648

  
641 649
    def show_item_data_format_dialog(self):
642 650
        """ show item data format dialog """
DTI_PID/DTI_PID/TextDetector.py
18 18
MIN_TEXT_SIZE = 10
19 19
THREAD_MAX_WORKER = os.cpu_count()
20 20

  
21

  
21 22
class TextDetector:
22 23
    '''
23 24
        @brief  constructor
24 25
        @author humkyung
25 26
        @date   2018.07.11
26 27
    '''
28

  
27 29
    def __init__(self):
28 30
        self.textInfoList = []
29 31
        self.otherTextInfoList = []
......
34 36
        @author humkyung
35 37
        @date   2018.06.16
36 38
    '''
39

  
37 40
    def detectTextAreas(self, img, offset):
38 41
        tInfoList = []
39 42
        try:
40 43
            tInfoList = self.getTextAreaInfo(img, offset[0], offset[1])
41 44
        except Exception as ex:
42
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
45
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
46
                                                       sys.exc_info()[-1].tb_lineno))
43 47

  
44 48
        return tInfoList
45 49

  
......
50 54
        @history    2018.06.08  Jeongwoo    Add angle
51 55
                    humkyung 2018.06.18 fixed logic to detect text area
52 56
    '''
57

  
53 58
    def getTextAreaInfo(self, imgGray, offsetX, offsetY):
54 59
        from AppDocData import AppDocData
55 60

  
......
61 66
        minSize = 5
62 67

  
63 68
        contourImg = np.ones(imgGray.shape, np.uint8) * 255
64
        binaryImg,mask = cv2.threshold(imgGray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
69
        binaryImg, mask = cv2.threshold(imgGray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
65 70

  
66 71
        contours, hierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
67 72
        for contour in contours:
......
74 79
                if (w > maxTextSize or h > maxTextSize) or (w <= minSize and h <= minSize): continue
75 80

  
76 81
            if area >= 0:
77
                cv2.drawContours(contourImg, [contour], -1, (0,0,0), -1)
78
                cv2.drawContours(contourImg, [contour], -1, (255,255,255), 1)
82
                cv2.drawContours(contourImg, [contour], -1, (0, 0, 0), -1)
83
                cv2.drawContours(contourImg, [contour], -1, (255, 255, 255), 1)
79 84
            else:
80
                cv2.drawContours(contourImg, [contour], -1, (255,255,255), -1)
81
                
85
                cv2.drawContours(contourImg, [contour], -1, (255, 255, 255), -1)
86

  
82 87
        path = os.path.join(project.getTempPath(), 'OCR_{}.png'.format(appDocData.imgName))
83 88
        cv2.imwrite(path, contourImg)
84 89

  
......
88 93
        configs = appDocData.getConfigs('Text Recognition', 'Shrink Size')
89 94
        shrinkSize = int(configs[0].value) if 1 == len(configs) else 0
90 95

  
91
        eroded = cv2.erode(contourImg, np.ones((expandSize,expandSize), np.uint8))
92
        #path = os.path.join(project.getTempPath(), 'ERODED_OCR_{}.png'.format(appDocData.imgName))
93
        #cv2.imwrite(path, eroded)
96
        eroded = cv2.erode(contourImg, np.ones((expandSize, expandSize), np.uint8))
97
        # path = os.path.join(project.getTempPath(), 'ERODED_OCR_{}.png'.format(appDocData.imgName))
98
        # cv2.imwrite(path, eroded)
94 99

  
95 100
        eroded = cv2.bitwise_not(eroded)
96
        #path = os.path.join(project.getTempPath(), 'bitwise_not_{}.png'.format(appDocData.imgName))
97
        #cv2.imwrite(path, eroded)
98
        
101
        # path = os.path.join(project.getTempPath(), 'bitwise_not_{}.png'.format(appDocData.imgName))
102
        # cv2.imwrite(path, eroded)
103

  
99 104
        contours, hierarchy = cv2.findContours(eroded, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
100 105
        for contour in contours:
101 106
            area = cv2.contourArea(contour, True)
102 107
            if area < 0:
103 108
                [x, y, w, h] = cv2.boundingRect(contour)
104
                
105
                img = contourImg[y:y+h, x:x+w]
109

  
110
                img = contourImg[y:y + h, x:x + w]
106 111
                img = cv2.bitwise_not(img)
107 112

  
108
                horizontal,max_width = 0,0
109
                vertical,max_height = 0,0
113
                horizontal, max_width = 0, 0
114
                vertical, max_height = 0, 0
110 115
                _contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
111 116
                for xx in _contours:
112 117
                    [_x, _y, _w, _h] = cv2.boundingRect(xx)
113
                    cv2.rectangle(img, (_x, _y), (_x+_w, _y+_h), 255, 1)
118
                    cv2.rectangle(img, (_x, _y), (_x + _w, _y + _h), 255, 1)
114 119

  
115 120
                    max_width = _x if _x > max_width else max_width
116 121
                    max_height = _y if _y > max_height else max_height
117 122

  
118
                    if (_w < _h) or (_w > maxTextSize and _h < maxTextSize): # width is greater than height
119
                        horizontal += 1 + (_w*_h)/(w*h)
123
                    if (_w < _h) or (_w > maxTextSize and _h < maxTextSize):  # width is greater than height
124
                        horizontal += 1 + (_w * _h) / (w * h)
120 125
                    else:
121
                        vertical += 1 + (_w*_h)/(w*h)
126
                        vertical += 1 + (_w * _h) / (w * h)
127

  
128
                if (w < 10 and h < 10) or (
129
                        max_width > maxTextSize and max_height > maxTextSize): continue;  # skip too small or big one
122 130

  
123
                if (w < 10 and h < 10) or (max_width > maxTextSize and max_height > maxTextSize): continue; # skip too small or big one
124
                
125 131
                """
126 132
                if w > maxTextSize:
127 133
                    horizontal = 1
......
158 164
        intersected = True
159 165
        while intersected:
160 166
            intersected = False
161
            for rect in rects[:]:   # clone rects
167
            for rect in rects[:]:  # clone rects
162 168
                if 0 == rect[0]:
163 169
                    rectExpand = rect[1].adjusted(-mergeSize, 0, mergeSize, 0)
164 170
                else:
......
177 183
        list = []
178 184
        for rect in rects:
179 185
            angle = rect[0]
180
            list.append(ti.TextInfo('', round(offsetX) + rect[1].x(), round(offsetY) + rect[1].y(), rect[1].width(), rect[1].height(), angle))
186
            list.append(ti.TextInfo('', round(offsetX) + rect[1].x(), round(offsetY) + rect[1].y(), rect[1].width(),
187
                                    rect[1].height(), angle))
181 188

  
182 189
            x = rect[1].x()
183 190
            y = rect[1].y()
184 191
            w = rect[1].width()
185 192
            h = rect[1].height()
186
            img = contourImg[y:y+h, x:x+w]
193
            img = contourImg[y:y + h, x:x + w]
187 194
            ## DEBUG
188
            #if angle == 0:
195
            # if angle == 0:
189 196
            #    filePath = os.path.join(project.getTempPath(), "Tile", "H-{}-{}-{}-{}.png".format(x,y,w,h))
190
            #else:
197
            # else:
191 198
            #    filePath = os.path.join(project.getTempPath(), "Tile", "V-{}-{}-{}-{}.png".format(x,y,w,h))
192
            #cv2.imwrite(filePath, img)
199
            # cv2.imwrite(filePath, img)
193 200
            ## up to here
194 201

  
195 202
        return list
......
201 208
        @history    change parameter updateProgressSignal to worker
202 209
                    2018.11.08 euisung     add white char list check process on db
203 210
    '''
211

  
204 212
    @staticmethod
205 213
    def recognizeTextFromImage(tInfos, imgOCR, offset, searchedSymbolList, worker, listWidget, maxProgressValue):
206 214
        import re
......
212 220
            for tInfo in tInfos:
213 221
                x = tInfo.getX() - round(offset[0])
214 222
                y = tInfo.getY() - round(offset[1])
215
                img = imgOCR[y:y+tInfo.getH(), x:x+tInfo.getW()]
223
                img = imgOCR[y:y + tInfo.getH(), x:x + tInfo.getW()]
216 224

  
217 225
                # set angle 0 if symbol contains the text area is instrumentation
218 226
                category = None
......
228 236
                if len(whiteCharList) is 0:
229 237
                    resultTextInfo = TOCR.getTextInfo(img, (x, y), tInfo.getAngle(), language=app_doc_data.OCRData)
230 238
                else:
231
                    resultTextInfo = TOCR.getTextInfo(img, (x, y), tInfo.getAngle(), language=app_doc_data.OCRData, conf=whiteCharList[0].value)
239
                    resultTextInfo = TOCR.getTextInfo(img, (x, y), tInfo.getAngle(), language=app_doc_data.OCRData,
240
                                                      conf=whiteCharList[0].value)
232 241

  
233 242
                if resultTextInfo is not None and len(resultTextInfo) > 0:
234 243
                    for result in resultTextInfo:
......
241 250
                    res.extend(resultTextInfo)
242 251

  
243 252
                    if listWidget is not None:
244
                        item = QListWidgetItem('{},{},{} is recognized'.format(resultTextInfo[0].getX(), resultTextInfo[0].getY(), resultTextInfo[0].getText()))
253
                        item = QListWidgetItem(
254
                            '{},{},{} is recognized'.format(resultTextInfo[0].getX(), resultTextInfo[0].getY(),
255
                                                            resultTextInfo[0].getText()))
245 256
                        listWidget.addItem(item)
246 257
                else:
247 258
                    pass
248 259

  
249 260
                if worker is not None:
250
                    worker.updateProgress.emit(maxProgressValue, resultTextInfo[0].getText() if resultTextInfo is not None and 1 == len(resultTextInfo) else None)
261
                    worker.updateProgress.emit(maxProgressValue,
262
                                               resultTextInfo[0].getText() if resultTextInfo is not None and 1 == len(
263
                                                   resultTextInfo) else None)
251 264
        except Exception as ex:
252
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
265
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
266
                                                           sys.exc_info()[-1].tb_lineno)
253 267
            if worker is not None:
254 268
                worker.displayLog.emit(MessageType.Error, message)
255 269

  
......
270 284
                    euisung  2018.11.08 add white char list check process on db
271 285
                    euisung  2018.11.12 add title block properties
272 286
    '''
273
    def recognizeText(self, imgSrc, offset, tInfoList, searchedSymbolList, worker, listWidget, maxProgressValue, onlyTextArea = False):
287

  
288
    def recognizeText(self, imgSrc, offset, tInfoList, searchedSymbolList, worker, listWidget, maxProgressValue,
289
                      onlyTextArea=False):
274 290
        import concurrent.futures as futures
275 291
        from multiprocessing import Process, Queue
276 292
        from Area import Area
......
279 295
            self.otherTextInfoList = []
280 296
            self.titleBlockTextInfoList = []
281 297
            self.textInfoList = []
282
            
298

  
283 299
            appDocData = AppDocData.instance()
284 300
            project = appDocData.getCurrentProject()
285 301

  
286 302
            path = os.path.join(project.getTempPath(), 'OCR_{}.png'.format(appDocData.imgName))
287 303
            if os.path.isfile(path):
288 304
                imgOCR = cv2.imread(path, 1)
289
                imgOCR = cv2.threshold(cv2.cvtColor(imgOCR, cv2.COLOR_BGR2GRAY), 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
305
                imgOCR = \
306
                cv2.threshold(cv2.cvtColor(imgOCR, cv2.COLOR_BGR2GRAY), 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
290 307

  
291 308
                text_info_array = np.array_split(tInfoList, THREAD_MAX_WORKER)
292 309
                pool = futures.ThreadPoolExecutor(max_workers=THREAD_MAX_WORKER)
......
315 332
                            if len(whiteCharList) is 0:
316 333
                                texts = TOCR.getTextInfo(area.img, (area.x, area.y), 0, language='eng')
317 334
                            else:
318
                                texts = TOCR.getTextInfo(area.img, (area.x, area.y), 0, language='eng', conf=whiteCharList[0].value)
335
                                texts = TOCR.getTextInfo(area.img, (area.x, area.y), 0, language='eng',
336
                                                         conf=whiteCharList[0].value)
319 337
                            self.otherTextInfoList.append([area.name, texts])
320 338
                    else:
321
                        img = imgSrc[round(area.y):round(area.y+area.height), round(area.x):round(area.x+area.width)]
339
                        img = imgSrc[round(area.y):round(area.y + area.height),
340
                              round(area.x):round(area.x + area.width)]
322 341
                        if len(whiteCharList) is 0:
323 342
                            texts = TOCR.getTextInfo(img, (area.x, area.y), 0, language='eng')
324 343
                        else:
325
                            texts = TOCR.getTextInfo(img, (area.x, area.y), 0, language='eng', conf = whiteCharList[0].value)
344
                            texts = TOCR.getTextInfo(img, (area.x, area.y), 0, language='eng',
345
                                                     conf=whiteCharList[0].value)
326 346
                        if texts is not None and len(texts) > 0:
327 347
                            if area.name == 'Unit':
328 348
                                appDocData.activeDrawing.setAttr('Unit', texts[0].getText())
329 349
                            self.otherTextInfoList.append([area.name, texts])
330 350

  
331 351
                titleBlockProps = appDocData.getTitleBlockProperties()
332
                for titleBlockProp in titleBlockProps:
333
                    area = Area(titleBlockProp[0])
334
                    area.parse(titleBlockProp[2])
335
                    if not (titleBlockProp[3] and titleBlockProp[3] != ''):
336
                        img = imgSrc[round(area.y):round(area.y+area.height), round(area.x):round(area.x+area.width)]
337
                        if len(whiteCharList) is 0:
338
                            texts = TOCR.getTextInfo(img, (area.x, area.y), 0, language=appDocData.OCRData)
352
                if titleBlockProps:
353
                    for titleBlockProp in titleBlockProps:
354
                        area = Area(titleBlockProp[0])
355
                        area.parse(titleBlockProp[2])
356
                        if not (titleBlockProp[3] and titleBlockProp[3] != ''):
357
                            img = imgSrc[round(area.y):round(area.y + area.height),
358
                                  round(area.x):round(area.x + area.width)]
359
                            if len(whiteCharList) is 0:
360
                                texts = TOCR.getTextInfo(img, (area.x, area.y), 0, language=appDocData.OCRData)
361
                            else:
362
                                texts = TOCR.getTextInfo(img, (area.x, area.y), 0, language='eng',
363
                                                         conf=whiteCharList[0].value)
364
                            texts = [ti.TextInfo('\n'.join([textInfo.getText() for textInfo in texts]), area.x, area.y,
365
                                                 area.width, area.height, 0)]
339 366
                        else:
340
                            texts = TOCR.getTextInfo(img, (area.x, area.y), 0, language='eng', conf=whiteCharList[0].value)
341
                        texts = [ti.TextInfo('\n'.join([textInfo.getText() for textInfo in texts]), area.x, area.y, area.width, area.height, 0)]
342
                    else:
343
                        texts = [ti.TextInfo(titleBlockProp[3], area.x, area.y, area.width, area.height, 0)]
344
                    self.titleBlockTextInfoList.append([area.name, texts])
367
                            texts = [ti.TextInfo(titleBlockProp[3], area.x, area.y, area.width, area.height, 0)]
368
                        self.titleBlockTextInfoList.append([area.name, texts])
345 369

  
346 370
                if worker is not None: worker.updateProgress.emit(maxProgressValue, None)
347 371
        except Exception as ex:
348
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
372
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
373
                                                           sys.exc_info()[-1].tb_lineno)
349 374
            worker.displayLog.emit(MessageType.Error, message)
350 375

  
351 376
    '''
......
353 378
        @author     humkyung
354 379
        @date       2018.07.24
355 380
    '''
381

  
356 382
    def removeTextFromImage(self, imgSrc, offset):
357 383
        appDocData = AppDocData.instance()
358 384
        project = appDocData.getCurrentProject()
......
360 386
        path = os.path.join(project.getTempPath(), 'OCR_{}.png'.format(appDocData.imgName))
361 387
        if os.path.isfile(path):
362 388
            imgOCR = cv2.imread(path)
363
            imgOCR = cv2.threshold(cv2.cvtColor(imgOCR, cv2.COLOR_BGR2GRAY), 127, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
389
            imgOCR = \
390
            cv2.threshold(cv2.cvtColor(imgOCR, cv2.COLOR_BGR2GRAY), 127, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
364 391

  
365 392
            # remove recognized text from image
366 393
            for text in self.textInfoList:
......
368 395
                y = round(text.getY() - offset[1])
369 396
                width = round(text.getW())
370 397
                height = round(text.getH())
371
                self.removeText(imgSrc, (round(text.getX()), round(text.getY())), imgOCR[y:y+height, x:x+width])
398
                self.removeText(imgSrc, (round(text.getX()), round(text.getY())), imgOCR[y:y + height, x:x + width])
372 399
            # up to here
373 400

  
374 401
    '''
375 402
        @brief  remove text from image by using ocr image
376 403
        @author
377 404
    '''
405

  
378 406
    def removeText(self, img, pt, imgOCR):
379 407
        try:
380 408
            x = round(pt[0])
381 409
            y = round(pt[1])
382 410
            width, height = imgOCR.shape[::-1]
383
            
384
            temp = img[y:y+height, x:x+width]
385
            imgOCR = cv2.erode(imgOCR, np.ones((3,3), np.uint8))
411

  
412
            temp = img[y:y + height, x:x + width]
413
            imgOCR = cv2.erode(imgOCR, np.ones((3, 3), np.uint8))
386 414
            mask = cv2.bitwise_or(temp, imgOCR)
387 415
            imgXOR = cv2.bitwise_xor(temp, mask)
388
            img[y:y+height, x:x+width] = cv2.bitwise_not(imgXOR)
416
            img[y:y + height, x:x + width] = cv2.bitwise_not(imgXOR)
389 417

  
390 418
        except Exception as ex:
391
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
419
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
420
                                                       sys.exc_info()[-1].tb_lineno))
392 421

  
393 422
        return img

내보내기 Unified diff

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