프로젝트

일반

사용자정보

개정판 e2ae85c2

IDe2ae85c2ae63ef5abe00bde640caf4adf0539a39
상위 f2d03118
하위 0b04ae07

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

issue #480: fixed an error to fail to detect line when symbol is flipped
- Ctrl + Arrow Key : 심볼 이동 빠르게

Change-Id: Ie4125ccb782c93f294d0b3cb9c0437f64f553412

차이점 보기:

DTI_PID/DTI_PID/AppDocData.py
3670 3670
        if type in self._symbolType:
3671 3671
            return self._symbolType[type]
3672 3672

  
3673
        conn = self.project.database.connect()
3674
        with conn:
3673
        with self.project.database.connect() as conn:
3675 3674
            try:
3676 3675
                cursor = conn.cursor()
3677 3676
                sql = self.project.database.to_sql('SELECT Category FROM SymbolType WHERE [Type] = ?')
DTI_PID/DTI_PID/Commands/CreateSymbolCommand.py
1 1
import os.path
2 2
import AbstractCommand
3

  
3 4
try:
4 5
    from PyQt5.QtCore import Qt, QRectF, pyqtSignal, QT_VERSION_STR
5 6
    from PyQt5.QtGui import QImage, QPixmap, QPainterPath, QCursor
......
14 15
from AppDocData import AppDocData
15 16
import cv2
16 17
import numpy as np
18

  
17 19
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
18 20
import SymbolEditorDialog
21

  
19 22
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + '\\Shapes')
20 23
from SymbolSvgItem import SymbolSvgItem
21 24

  
25

  
22 26
class CreateSymbolCommand(AbstractCommand.AbstractCommand):
23
    '''
24
        @history    2018.05.04  Jeongwoo    Add Parameter
25
    '''
27
    '''@history    2018.05.04  Jeongwoo    Add Parameter'''
28

  
26 29
    def __init__(self, imageViewer, resultTreeWidget, dirTreeWidget):
27 30
        super(CreateSymbolCommand, self).__init__(imageViewer)
28 31
        self.name = 'CreateSymbol'
29 32
        self.imageViewer.setCursor(QCursor(Qt.CrossCursor))
30 33
        self.resultTreeWidget = resultTreeWidget
31 34
        self.dirTreeWidget = dirTreeWidget
32
    
35

  
33 36
    '''
34 37
        @brief  crop image by rectangle selected by user
35 38
        @history    2018.05.02  Jeongwoo    Init self.offsetX and self.offsetY
......
38 41
                    2018.05.04  Jeongwoo    Add self.dirTreeWidget.initTreeWidget()
39 42
                    2018.06.08  Jeongwoo    Add Parameter on SymbolSvgItem.buildItem()
40 43
    '''
44

  
41 45
    def execute(self, param):
42 46
        event = param[1]
43 47
        scenePos = param[2]
......
48 52
        elif 'mouseReleaseEvent' == param[0] and event.button() == Qt.LeftButton:
49 53
            try:
50 54
                QGraphicsView.mouseReleaseEvent(self.imageViewer, event)
51
                viewBBox = self.imageViewer.zoomStack[-1] if len(self.imageViewer.zoomStack) else self.imageViewer.sceneRect()
55
                viewBBox = self.imageViewer.zoomStack[-1] if len(
56
                    self.imageViewer.zoomStack) else self.imageViewer.sceneRect()
52 57
                selectionBBox = self.imageViewer.scene.selectionArea().boundingRect().intersected(viewBBox)
53 58
                if selectionBBox.isValid():
54 59
                    croppedImage = self.imageViewer.image().copy(selectionBBox.toAlignedRect())
55
                    symbolEditorDialog = SymbolEditorDialog.QSymbolEditorDialog(self.imageViewer, croppedImage, AppDocData.instance().getCurrentProject())
60
                    symbolEditorDialog = SymbolEditorDialog.QSymbolEditorDialog(self.imageViewer, croppedImage,
61
                                                                                AppDocData.instance().getCurrentProject())
56 62
                    (isAccepted, isImmediateInsert, offsetX, offsetY, newSym) = symbolEditorDialog.showDialog()
57 63
                    self.dirTreeWidget.initDirTreeWidget()
58 64
                    if isAccepted:
......
65 71
                            else:
66 72
                                _chan, w, h = img.shape[::-1]
67 73
                            svg = SymbolSvgItem(svgPath)
68
                            svg.buildItem(newSym.getName(), newSym.getType(), 0, [selectionBBox.x()+offsetX, selectionBBox.y()+offsetY], [w, h], [float(x) for x in newSym.getOriginalPoint().split(',')], [(float(x.split(',')[0]), float(x.split(',')[1])) for x in newSym.getConnectionPoint().split('/')], newSym.getBaseSymbol(), newSym.getAdditionalSymbol())
74
                            svg.buildItem(newSym.getName(), newSym.getType(), 0,
75
                                          [selectionBBox.x() + offsetX, selectionBBox.y() + offsetY], [w, h],
76
                                          [float(x) for x in newSym.getOriginalPoint().split(',')],
77
                                          [(float(x.split(',')[0]), float(x.split(',')[1])) for x in
78
                                           newSym.getConnectionPoint().split('/')], newSym.getBaseSymbol(),
79
                                          newSym.getAdditionalSymbol())
69 80

  
70
                            #### lambda param=svg : bind 'svg' object to lambda('param')
71
                            #### If case of 'lambda svg=svg:', function uses the 'svg' value bound to lambda
72 81
                            svg.clicked.connect(lambda param=svg: self.resultTreeWidget.findItem(param))
73 82
                            svg.transfer.onRemoved.connect(self.resultTreeWidget.itemRemoved)
74 83
                            svg.addSvgItemToScene(self.imageViewer.scene)
......
85 94
        pass
86 95

  
87 96
    def redo(self):
88
        pass
97
        pass
DTI_PID/DTI_PID/LineDetector.py
174 174
        return -1 for thickness if fail to calculate thickness
175 175
        """
176 176
        from AppDocData import AppDocData
177
        docData = AppDocData.instance()
178
        windowSize = docData.getSlidingWindowSize()
177

  
178
        app_doc_data = AppDocData.instance()
179
        windowSize = app_doc_data.getSlidingWindowSize()
179 180

  
180 181
        try:
181 182
            white = 255
182 183
            black = 0
183 184

  
184 185
            norm = [-dir[1], dir[0]]
185
            if black == self._image[pt[1] + round(dir[1] * windowSize[1]), pt[0] + round(dir[0] * windowSize[1])]:
186
            if white != self._image[pt[1] + round(dir[1] * windowSize[1]), pt[0] + round(dir[0] * windowSize[1])]:
186 187
                _pt = [pt[0] + round(dir[0] * windowSize[1]), pt[1] + round(dir[1] * windowSize[1])]
187 188
            else:
188 189
                found = False
189 190
                for step in [1, 2, -1, -2]:
190
                    if black == self._image[pt[1] + round(dir[1] * windowSize[1] + norm[1] * step),
191
                    if white != self._image[pt[1] + round(dir[1] * windowSize[1] + norm[1] * step),
191 192
                                            pt[0] + round(dir[0] * windowSize[1] + norm[0] * step)]:
192 193
                        _pt = [pt[0] + round(dir[0] * windowSize[1] + norm[0] * step),
193 194
                               pt[1] + round(dir[1] * windowSize[1] + norm[1] * step)]
......
250 251
                    # get direction of connector
251 252
                    direction = connector.dir()
252 253
                    if direction is None:
254
                        # calculate direction of connector
253 255
                        dx = connector.sceneConnectPoint[0] - symbol.origin[0]
254 256
                        dy = connector.sceneConnectPoint[1] - symbol.origin[1]
255 257
                    else:
......
268 270
                            pt, thickness = self.adjust_start_point(pt, dir)
269 271
                            if thickness != -1:
270 272
                                pool.append([dir, pt, thickness, True if not pool else False])
271
                            # print("v")
272 273
                        elif abs(dy) < 0.1:  # horizontal line
273 274
                            dir = [1 if dx > 0 else -1, 0]
274 275
                            pt = [round(connector.sceneConnectPoint[0] - offsetX),
......
508 509
        """detect a line along given direction"""
509 510
        from AppDocData import AppDocData
510 511

  
511
        lineLengthConfigs = AppDocData.instance().getConfigs('Small Line Minimum Length', 'Min Length')
512
        app_doc_data = AppDocData.instance()
513
        lineLengthConfigs = app_doc_data.getConfigs('Small Line Minimum Length', 'Min Length')
512 514
        lineMinLength = int(lineLengthConfigs[0].value) if 1 == len(lineLengthConfigs) else 10
513 515
        try:
514 516
            white = [255]
515
            windowSize = AppDocData.instance().getSlidingWindowSize()
517
            windowSize = app_doc_data.getSlidingWindowSize()
516 518
            xHalf = round(windowSize[0] * 0.5)
517 519
            yHalf = round(windowSize[1] * 0.5)
518 520

  
DTI_PID/DTI_PID/MainWindow.py
166 166
        self.verticalLayout.addWidget(self.graphicsView)
167 167

  
168 168
        # Add Custom TreeWidget
169
        self.dirTreeWidget = SymbolTreeWidget.QSymbolTreeWidget()
170
        self.dirTreeWidget.header().hide()
171
        self.symbolTabVerticalLayout.addWidget(self.dirTreeWidget)
169
        self.symbolTreeWidget = SymbolTreeWidget.QSymbolTreeWidget()
170
        self.symbolTreeWidget.header().hide()
171
        self.symbolTabVerticalLayout.addWidget(self.symbolTreeWidget)
172 172

  
173 173
        # Add Custom Property TableWidget
174 174
        self.propertyTableWidget = SymbolPropertyTableWidget.QSymbolPropertyTableWidget()
175 175
        self.symbolTabVerticalLayout.addWidget(self.propertyTableWidget)
176
        self.dirTreeWidget.singleClicked.connect(self.propertyTableWidget.getClickedSymbol)
176
        self.symbolTreeWidget.singleClicked.connect(self.propertyTableWidget.getClickedSymbol)
177 177
        # add splitter widget
178 178
        splitter = QSplitter(Qt.Vertical)
179
        splitter.addWidget(self.dirTreeWidget)
179
        splitter.addWidget(self.symbolTreeWidget)
180 180
        splitter.addWidget(self.propertyTableWidget)
181 181
        self.symbolTabVerticalLayout.addWidget(splitter)
182 182
        # up to here
......
907 907
        self.setWindowTitle(title if title[-1] == '*' else title + '*')
908 908

  
909 909
    def onConvertPDFToImage(self):
910
        """
911
        @brief      convert to selected pdf to image
912
        @author     humkyung 
913
        @date       2018.07.09
914
        @history    Euisung 2018.10.11 hide shell
915
        """
910
        """convert to selected pdf to image"""
911
        import os
912

  
916 913
        try:
917
            filePath = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'bin64', 'PDF_TO_IMAGE.exe')
918
            subprocess.call(filePath, shell=False)
914
            file_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'bin64', 'PDF_TO_IMAGE.exe')
915
            os.startfile(file_path)
919 916
        except Exception as ex:
920 917
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
921 918
                                                           sys.exc_info()[-1].tb_lineno)
......
958 955

  
959 956
    def onSelectionChanged(self):
960 957
        """selection changed"""
961
        items = [item for item in self.graphicsView.scene.selectedItems() if issubclass(type(item), SymbolSvgItem) or \
962
                 type(item) is QEngineeringLineItem or issubclass(type(item), QEngineeringTextItem) or type(
963
            item) is QEngineeringUnknownItem or type(item) is QEngineeringVendorItem]
958
        items = [item for item in self.graphicsView.scene.selectedItems() if issubclass(type(item), SymbolSvgItem) or
959
                 type(item) is QEngineeringLineItem or issubclass(type(item), QEngineeringTextItem) or
960
                 type(item) is QEngineeringUnknownItem or type(item) is QEngineeringVendorItem]
964 961
        if items:
965 962
            item = items[-1]
966 963
            self.itemTreeWidget.findItem(item)
......
970 967
                    if self.tableWidgetInconsistency.item(index, 1).tag is item:
971 968
                        self.tableWidgetInconsistency.selectRow(index)
972 969
                        break
970
            if issubclass(type(item), SymbolSvgItem):
971
                self.symbolTreeWidget.select_symbol(item)
973 972
        else:
974 973
            self.resultPropertyTableWidget.show_item_property(None)
975 974

  
......
1063 1062
            return
1064 1063
        if self.actionEquipment.isChecked():
1065 1064
            self.graphicsView.command = CreateSymbolCommand.CreateSymbolCommand(self.graphicsView, self.itemTreeWidget,
1066
                                                                                self.dirTreeWidget)
1065
                                                                                self.symbolTreeWidget)
1067 1066
        else:
1068 1067
            self.graphicsView.useDefaultCommand()
1069 1068

  
......
1081 1080
            return
1082 1081
        if self.actionNozzle.isChecked():
1083 1082
            self.graphicsView.command = CreateSymbolCommand.CreateSymbolCommand(self.graphicsView, self.itemTreeWidget,
1084
                                                                                self.dirTreeWidget)
1083
                                                                                self.symbolTreeWidget)
1085 1084
        else:
1086 1085
            self.graphicsView.useDefaultCommand()
1087 1086

  
......
1565 1564
                symbolEditorDialog = SymbolEditorDialog.QSymbolEditorDialog(self, image.copy(x, y, width, height),
1566 1565
                                                                            AppDocData.instance().getCurrentProject())
1567 1566
                (isAccepted, isImmediateInsert, offsetX, offsetY, newSym) = symbolEditorDialog.showDialog()
1568
                self.dirTreeWidget.initDirTreeWidget()
1567
                self.symbolTreeWidget.initDirTreeWidget()
1569 1568
                if isAccepted:
1570 1569
                    if isImmediateInsert:
1571 1570
                        svgPath = newSym.getSvgFileFullPath()
......
1833 1832
                    dlg.show()
1834 1833
            elif event.key() == Qt.Key_I:
1835 1834
                # insert symbol item that is selected symbol in tree to main window if symbol already selected on main window, replace
1836
                items = self.dirTreeWidget.selectedItems()
1835
                items = self.symbolTreeWidget.selectedItems()
1837 1836
                if items and hasattr(items[0], 'svgFilePath'):
1838
                    symData = items[0].data(0, self.dirTreeWidget.TREE_DATA_ROLE)
1837
                    symData = items[0].data(0, self.symbolTreeWidget.TREE_DATA_ROLE)
1839 1838
                    symName = symData.getName()
1840 1839
                else:
1841 1840
                    return
......
1855 1854

  
1856 1855
                if old_symbol:
1857 1856
                    return
1857
            elif event.key() == Qt.Key_X:
1858
                items = self.graphicsView.scene.selectedItems()
1859
                if items:
1860
                    item = self.symbolTreeWidget.currentItem()
1861
                    if item:
1862
                        self.symbolTreeWidget.showSymbolEditorDialog(item, 0)
1858 1863

  
1859 1864
            QMainWindow.keyPressEvent(self, event)
1860 1865
        except Exception as ex:
......
1958 1963
            self.dlg = QRecognitionDialog(self, drawingList, False)
1959 1964
            self.dlg.exec_()
1960 1965

  
1961
            if appDocData.needReOpening == True:
1966
            if appDocData.needReOpening:
1962 1967
                self.itemTreeWidget.setCurrentPID(appDocData.activeDrawing.name)
1963 1968
                self.drawDetectedItemsToScene()
1964 1969

  
DTI_PID/DTI_PID/RecognitionDialog.py
124 124
            configs = app_doc_data.getConfigs('Small Object Size', 'Max Area')
125 125
            maxArea = int(configs[0].value) if 1 == len(configs) else 50
126 126

  
127
            # try to convert grayscale to binary
128
            image = cv2.threshold(image, 200, 255, cv2.THRESH_BINARY)[1]
129

  
127 130
            contours, _ = cv2.findContours(image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
128 131
            selectedContours = []
129 132
            for contour in contours:
......
219 222
                    euisung  2018.11.12 add title block properties
220 223
        """
221 224
        import re
225
        import timeit
222 226
        from TextDetector import TextDetector
223 227
        from Drawing import Drawing
224 228

  
......
236 240

  
237 241
            # remove already existing symbol and text
238 242
            if not batch:
243
                listWidget.addItem('Deleting existing items...')
239 244
                items = [item for item in worker.graphicsView.scene.items() if
240 245
                         type(item) is QEngineeringUnknownItem or type(item) is QEngineeringEndBreakItem or
241
                         type(item) is QEngineeringErrorItem]
246
                         type(item) is QEngineeringErrorItem or type(item) is QGraphicsBoundingBoxItem]
247

  
242 248
                if worker.isSymbolChecked:
243 249
                    items.extend(
244 250
                        [item for item in worker.graphicsView.scene.items() if issubclass(type(item), SymbolSvgItem)])
......
247 253
                                  issubclass(type(item), QEngineeringTextItem)])
248 254
                for item in items:
249 255
                    item.transfer.onRemoved.emit(item)
250
                    # worker.graphicsView.scene.removeItem(item)
251
                for item in [item for item in worker.graphicsView.scene.items() if
252
                             type(item) is QGraphicsBoundingBoxItem]:
253
                    item.transfer.onRemoved.emit(item)
254 256
            # up to here
255 257

  
256 258
            srcList = path
......
312 314
                    area.contours, area.hierachy = cv2.findContours(area.not_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
313 315

  
314 316
                maxProgressValue = 0
315
                listWidget.addItem("Start recognition : " + mainRes)
317
                start_time = timeit.default_timer()
318
                listWidget.addItem(f"Start recognition{str(start_time)} : {mainRes}")
316 319
                threadLock.acquire()
317 320

  
318 321
                worker.updateBatchProgress.emit(len(srcList), 1)
......
564 567
                    for symbol in app_doc_data.symbols:
565 568
                        matches = [it for it in app_doc_data.symbols if
566 569
                                   it is not symbol and symbol.is_connectable(it, toler=toler)]
567
                        # print(str(symbol))
568
                        # print(matches)
569 570
                        for match in matches:
570 571
                            symbol.connect_if_possible(match)
571 572
                except Exception as ex:
......
669 670
                items = [item for item in worker.graphicsView.scene.items() if (type(item) is QEngineeringLineItem)]
670 671
                for item in items:
671 672
                    item.transfer.onRemoved.emit(item)
672
                    # worker.graphicsView.scene.removeItem(item)
673 673
            # up to here
674 674

  
675 675
            # detect line
......
736 736
        targetSymbolList.append(nozzles)
737 737
        targetSymbolList.append([item for item in symbolList if item not in equipments and item not in nozzles])
738 738

  
739
        # for i in range(len(targetSymbolList[0])):
740
        #    print(targetSymbolList[0][i].getName())
741
        # for i in range(len(targetSymbolList[1])):
742
        #    print(targetSymbolList[1][i].getName())
743
        # for i in range(len(targetSymbolList[2])):
744
        #    print(targetSymbolList[2][i].getName())
745

  
746 739
        return targetSymbolList
747 740

  
748 741
    '''
......
848 841
            roiItemSp = (0, 0)
849 842
            roiItemEp = (srcWidth, srcHeight)
850 843

  
851
            # For OPC
844
            # when text is located inside of symbol
852 845
            if area is not None and hasInstrumentLabel:
853 846
                # remove objects smaller than symbol
854 847
                selected_contours = []
......
867 860
                # draw contour with white color
868 861
                roiItem = cv2.drawContours(roiItem, selected_contours, -1, (255, 255, 255), -1)
869 862

  
870
            for index in range(2):
871
                if index is 0:
872
                    # continue
873
                    pass
874
                elif detectFlip is not 1 and index is 1:
875
                    continue
876
                else:
863
            # try to recognize symbol twice(first one is normal, second on is flipped)
864
            steps = [False, True] if detectFlip else [False]
865
            for flipped in steps:
866
                if flipped:
877 867
                    symGray = symGrayOri
878 868
                    symGray = cv2.flip(symGray, 1)
879
                    # cv2.imwrite('out.png', symGray)
880
                    opx = sow - float(symbolOriginalPoint.split(',')[0])
881
                    opy = float(symbolOriginalPoint.split(',')[1])
882
                    symbolOriginalPoint = str(opx) + ',' + str(opy)
883

  
884
                    symbolConnectionPoint = symbolConnectionPoint.split("/")
885
                    symbolConnectionPointStr = ''
886
                    for strConnPt in symbolConnectionPoint:
887
                        if strConnPt == '': continue
888
                        tokens = strConnPt.split(',')
889

  
890
                        direction = 'AUTO'
891
                        symbol_idx = '0'
892
                        if len(tokens) == 2:
893
                            cpx = sow - float(tokens[0])
894
                            cpy = float(tokens[1])
895
                            cflip = direction + ',' + str(cpx) + ',' + str(cpy)
896
                        elif len(tokens) == 3:
897
                            direction = tokens[0]
898
                            cpx = sow - float(tokens[1])
899
                            cpy = float(tokens[2])
900
                            cflip = direction + ',' + str(cpx) + ',' + str(cpy)
901
                        elif len(tokens) >= 4:
902
                            direction = tokens[0]
903
                            cpx = sow - float(tokens[1])
904
                            cpy = float(tokens[2])
905
                            symbol_idx = tokens[3]
906
                            cflip = direction + ',' + str(cpx) + ',' + str(cpy) + ',' + str(symbol_idx)
907

  
908
                        if symbolConnectionPointStr == '':
909
                            symbolConnectionPointStr = cflip
910
                        else:
911
                            symbolConnectionPointStr = symbolConnectionPointStr + '/' + cflip
912
                    symbolConnectionPoint = symbolConnectionPointStr
913 869

  
914
                # print(symbolOriginalPoint)
915
                # print(symbolConnectionPoint)
916 870
                symbolRotatedAngle = 0
917
                for rc in range(symbolRotateCount + 1):  # Rotation Count를 사용자 기준으로 받아서 1을 더한 후 사용
871
                for rc in range(symbolRotateCount + 1):  # Rotation count를 사용자 기준으로 받아서 1을 더한 후 사용
918 872
                    sw, sh = symGray.shape[::-1]
919 873
                    roiw = (roiItemEp[0] - roiItemSp[0])
920 874
                    roih = (roiItemEp[1] - roiItemSp[1])
......
930 884

  
931 885
                    # get Rotated Original Point
932 886
                    originalPoint = Worker.getCalculatedOriginalPoint(additionalSymbol, symbolOriginalPoint,
933
                                                                      symbolRotatedAngle, sw, sh, sow, soh)
887
                                                                      symbolRotatedAngle, sw, sh, sow, soh, flipped)
934 888
                    connectionPoint = Worker.getCalculatedConnectionPoint(symbolConnectionPoint, symbolRotatedAngle, sw,
935
                                                                          sh, sow, soh)
889
                                                                          sh, sow, soh, flipped)
936 890

  
937 891
                    # For OPC
938 892
                    drawing_area = app_doc_data.getArea('Drawing')
......
987 941
                                                     isDetectOnOrigin, symbolRotateCount, symbolOcrOption,
988 942
                                                     isContainChild,
989 943
                                                     originalPoint, connectionPoint, baseSymbol, additionalSymbol,
990
                                                     isExceptDetect, detectFlip=1 if index is 1 else 0,
944
                                                     isExceptDetect,
945
                                                     detectFlip=1 if flipped else 0,
991 946
                                                     hasInstrumentLabel=hasInstrumentLabel)
992 947
                            threadLock.release()
993 948
                        else:  # 겹치는 영역이 기준값보다 클 경우
......
1016 971
                                                                                                 connectionPoint),
1017 972
                                                                                        baseSymbol, additionalSymbol,
1018 973
                                                                                        isExceptDetect,
1019
                                                                                        detectFlip=1 if index is 1 else 0,
974
                                                                                        detectFlip=1 if flipped else 0,
1020 975
                                                                                        hasInstrumentLabel=hasInstrumentLabel)
1021 976
                                        threadLock.release()
1022 977
                                # 현재 심볼과 검출된 심볼이 같지 않을 경우 (포함)
......
1031 986
                                                                 isContainChild,
1032 987
                                                                 originalPoint, connectionPoint, baseSymbol,
1033 988
                                                                 additionalSymbol, isExceptDetect,
1034
                                                                 detectFlip=1 if index is 1 else 0,
989
                                                                 detectFlip=1 if flipped else 0,
1035 990
                                                                 hasInstrumentLabel=hasInstrumentLabel)
1036 991
                                        threadLock.release()
1037 992
                                # 현재 심볼과 검출된 심볼이 같지 않을 경우 (교체)
......
1057 1012
                                                                                                 connectionPoint),
1058 1013
                                                                                        baseSymbol, additionalSymbol,
1059 1014
                                                                                        isExceptDetect,
1060
                                                                                        detectFlip=1 if index is 1 else 0,
1015
                                                                                        detectFlip=1 if flipped else 0,
1061 1016
                                                                                        hasInstrumentLabel=hasInstrumentLabel)
1062 1017
                                        threadLock.release()
1063 1018
                                # 학습용 데이터 생성을 위해 교체하지 않고 추가함
......
1071 1026
                                                             isContainChild,
1072 1027
                                                             originalPoint, connectionPoint, baseSymbol,
1073 1028
                                                             additionalSymbol, isExceptDetect,
1074
                                                             detectFlip=1 if index is 1 else 0,
1029
                                                             detectFlip=1 if flipped else 0,
1075 1030
                                                             hasInstrumentLabel=hasInstrumentLabel)
1076 1031
                                    threadLock.release()
1077 1032

  
......
1198 1153
            roiItem = img
1199 1154

  
1200 1155
            symbolAngle = 0
1201
            for rc in range(symbolRotateCount + 1):  ## Rotation Count를 사용자 기준으로 받아서 1을 더한 후 사용
1156
            for rc in range(symbolRotateCount + 1):  # Rotation Count를 사용자 기준으로 받아서 1을 더한 후 사용
1202 1157
                sw, sh = symGray.shape[::-1]
1203 1158
                roiw = (roiItemEp[0] - roiItemSp[0])
1204 1159
                roih = (roiItemEp[1] - roiItemSp[1])
1205 1160

  
1206
                ## get Rotated Original Point
1161
                # get Rotated Original Point
1207 1162
                originalPoint = Worker.getCalculatedOriginalPoint(additionalSymbol, symbolOriginalPoint, symbolAngle,
1208 1163
                                                                  sw, sh, sow, soh)
1209 1164
                connectionPoint = Worker.getCalculatedConnectionPoint(symbolConnectionPoint, symbolAngle, sw, sh, sow,
......
1211 1166
                dx = connectionPoint[0][0] - originalPoint[0]
1212 1167
                dy = connectionPoint[0][1] - originalPoint[1]
1213 1168

  
1214
                ## Template Matching
1169
                # Template Matching
1215 1170
                tmRes = cv2.matchTemplate(roiItem, symGray, cv2.TM_CCOEFF_NORMED)
1216 1171
                loc = np.where(tmRes >= symbolThreshold)
1217 1172

  
......
1339 1294

  
1340 1295
    @staticmethod
1341 1296
    def getCalculatedOriginalPoint(additionalSymbol, symbolOriginalPoint, symbolRotatedAngle, rotateSymbolWidth,
1342
                                   rotateSymbolHeight, originalSymbolWidth, originalSymbolHeight):
1297
                                   rotateSymbolHeight, originalSymbolWidth, originalSymbolHeight, flipped=False):
1343 1298
        res = []
1344 1299

  
1345 1300
        if additionalSymbol is None and symbolOriginalPoint is None:
1346 1301
            res.append(rotateSymbolWidth // 2)
1347 1302
            res.append(rotateSymbolHeight // 2)
1348 1303
        else:
1349
            opx = float(symbolOriginalPoint.split(',')[0])
1350
            opy = float(symbolOriginalPoint.split(',')[1])
1304
            if flipped:
1305
                opx = originalSymbolWidth - float(symbolOriginalPoint.split(',')[0])
1306
                opy = float(symbolOriginalPoint.split(',')[1])
1307
            else:
1308
                opx = float(symbolOriginalPoint.split(',')[0])
1309
                opy = float(symbolOriginalPoint.split(',')[1])
1310

  
1351 1311
            rPt = Worker.getCoordOnRotatedImage(symbolRotatedAngle, ('AUTO', opx, opy, '0'), originalSymbolWidth,
1352 1312
                                                originalSymbolHeight)
1353 1313

  
......
1364 1324

  
1365 1325
    @staticmethod
1366 1326
    def getCalculatedConnectionPoint(symbolConnectionPointStr, symbolRotatedAngle, rotateSymbolWidth,
1367
                                     rotateSymbolHeight, originalSymbolWidth, originalSymbolHeight):
1327
                                     rotateSymbolHeight, originalSymbolWidth, originalSymbolHeight, flipped=0):
1368 1328
        res = []
1369 1329

  
1370 1330
        if symbolConnectionPointStr is not None and symbolConnectionPointStr != '':
......
1374 1334

  
1375 1335
                direction = 'AUTO'
1376 1336
                symbol_idx = '0'
1377
                if len(tokens) == 2:
1378
                    cpx = float(tokens[0])
1379
                    cpy = float(tokens[1])
1380
                elif len(tokens) == 3:
1381
                    direction = tokens[0]
1382
                    cpx = float(tokens[1])
1383
                    cpy = float(tokens[2])
1384
                elif len(tokens) >= 4:
1385
                    direction = tokens[0]
1386
                    cpx = float(tokens[1])
1387
                    cpy = float(tokens[2])
1388
                    symbol_idx = tokens[3]
1337
                if flipped:
1338
                    converted = {'AUTO': 'AUTO', 'LEFT': 'RIGHT', 'RIGHT': 'LEFT', 'UP': 'UP', 'DOWN': 'DOWN'}
1339

  
1340
                    if len(tokens) == 2:
1341
                        cpx = originalSymbolWidth - float(tokens[0])
1342
                        cpy = float(tokens[1])
1343
                    elif len(tokens) == 3:
1344
                        direction = converted[tokens[0]]
1345
                        cpx = originalSymbolWidth - float(tokens[1])
1346
                        cpy = float(tokens[2])
1347
                    elif len(tokens) >= 4:
1348
                        direction = converted[tokens[0]]
1349
                        cpx = originalSymbolWidth - float(tokens[1])
1350
                        cpy = float(tokens[2])
1351
                        symbol_idx = tokens[3]
1352
                else:
1353
                    if len(tokens) == 2:
1354
                        cpx = float(tokens[0])
1355
                        cpy = float(tokens[1])
1356
                    elif len(tokens) == 3:
1357
                        direction = tokens[0]
1358
                        cpx = float(tokens[1])
1359
                        cpy = float(tokens[2])
1360
                    elif len(tokens) >= 4:
1361
                        direction = tokens[0]
1362
                        cpx = float(tokens[1])
1363
                        cpy = float(tokens[2])
1364
                        symbol_idx = tokens[3]
1389 1365

  
1390 1366
                res.append(Worker.getCoordOnRotatedImage(symbolRotatedAngle, (direction, cpx, cpy, symbol_idx),
1391 1367
                                                         originalSymbolWidth, originalSymbolHeight))
......
1402 1378
    '''
1403 1379

  
1404 1380
    @staticmethod
1405
    def getCoordOnRotatedImage(rAngle, connPt, originImageWidth, originImageHeight):
1381
    def getCoordOnRotatedImage(angle, connPt, originImageWidth, originImageHeight):
1406 1382
        rx = None
1407 1383
        ry = None
1408 1384

  
1409
        ## calculate rotated direction
1385
        # calculate rotated direction
1410 1386
        direction = connPt[0]
1411 1387
        if direction == 'LEFT':
1412
            direction = 'DOWN' if rAngle == 90 else 'RIGHT' if rAngle == 180 else 'UP' if rAngle == 270 else direction
1388
            direction = 'DOWN' if angle == 90 else 'RIGHT' if angle == 180 else 'UP' if angle == 270 else direction
1413 1389
        elif direction == 'RIGHT':
1414
            direction = 'UP' if rAngle == 90 else 'LEFT' if rAngle == 180 else 'DOWN' if rAngle == 270 else direction
1390
            direction = 'UP' if angle == 90 else 'LEFT' if angle == 180 else 'DOWN' if angle == 270 else direction
1415 1391
        elif direction == 'UP':
1416
            direction = 'LEFT' if rAngle == 90 else 'DOWN' if rAngle == 180 else 'RIGHT' if rAngle == 270 else direction
1392
            direction = 'LEFT' if angle == 90 else 'DOWN' if angle == 180 else 'RIGHT' if angle == 270 else direction
1417 1393
        elif direction == 'DOWN':
1418
            direction = 'RIGHT' if rAngle == 90 else 'UP' if rAngle == 180 else 'LEFT' if rAngle == 270 else direction
1419
        ## up to here
1394
            direction = 'RIGHT' if angle == 90 else 'UP' if angle == 180 else 'LEFT' if angle == 270 else direction
1395
        # up to here
1420 1396

  
1421 1397
        transform = QTransform()
1422
        if rAngle == 90 or rAngle == 270:
1398
        if angle == 90 or angle == 270:
1423 1399
            transform.translate(originImageHeight * 0.5, originImageWidth * 0.5)
1424
        elif rAngle == 0 or rAngle == 180:
1400
        elif angle == 0 or angle == 180:
1425 1401
            transform.translate(originImageWidth * 0.5, originImageHeight * 0.5)
1426
        transform.rotate(-abs(rAngle))
1402
        transform.rotate(-abs(angle))
1427 1403
        transform.translate(-originImageWidth * 0.5, -originImageHeight * 0.5)
1428 1404
        point = QPoint(connPt[1], connPt[2])
1429 1405
        point = transform.map(point)
......
1446 1422
    def addSearchedSymbol(sName, sType
1447 1423
                          , sp, w, h, threshold, minMatchCount, hitRate, rotatedAngle
1448 1424
                          , isDetectOnOrigin, rotateCount, ocrOption, isContainChild
1449
                          , originalPoint, connectionPoint, baseSymbol, additionalSymbol, isExceptDetect, detectFlip,
1450
                          hasInstrumentLabel):
1425
                          , originalPoint, connectionPoint, baseSymbol, additionalSymbol, isExceptDetect, detectFlip
1426
                          , hasInstrumentLabel):
1451 1427
        global searchedSymbolList
1452 1428

  
1453 1429
        newSym = None
......
1458 1434
                                   ','.join(str(x) for x in originalPoint),
1459 1435
                                   '/'.join('{},{},{},{}'.format(param[0], param[1], param[2], param[3]) for param in
1460 1436
                                            connectionPoint),
1461
                                   baseSymbol, additionalSymbol, isExceptDetect, detectFlip=detectFlip,
1437
                                   baseSymbol, additionalSymbol, isExceptDetect, detectFlip=1 if detectFlip else 0,
1462 1438
                                   hasInstrumentLabel=hasInstrumentLabel)
1463 1439

  
1464 1440
            searchedSymbolList.append(newSym)
DTI_PID/DTI_PID/Shapes/SymbolSvgItem.py
397 397
        return errors
398 398

  
399 399
    def includes(self, pt, margin=0):
400
        """
401
        return True if symbol contains given point else return False
402
        """
400
        """return True if symbol contains given point else return False"""
403 401
        rect = self.sceneBoundingRect()
404 402
        allowed_error = 0.1
405 403

  
......
621 619
                    x = float(tokens[0])
622 620
                    y = float(tokens[1])
623 621
                elif len(tokens) >= 3:
624
                    direction = tokens[0]
622
                    direction = connPts[index][0]
625 623
                    x = float(tokens[1])
626 624
                    y = float(tokens[2])
627 625
                if len(tokens) >= 4:
......
641 639
                self.connectors[index].symbol_idx = symbol_idx
642 640
                self.connectors[index].setPos((x, y))
643 641
                self.connectors[index].connectPoint = (x, y)
644
                self.connectors[index].sceneConnectPoint = (connPts[index][0], connPts[index][1]) if len(
645
                    connPts[index]) == 2 else \
646
                    (connPts[index][1], connPts[index][2]) if len(connPts[index]) == 3 else \
647
                        (connPts[index][1], connPts[index][2]) if len(connPts[index]) == 4 else None
642
                self.connectors[index].sceneConnectPoint = (connPts[index][0], connPts[index][1]) if \
643
                    len(connPts[index]) == 2 else (connPts[index][1], connPts[index][2]) if \
644
                    len(connPts[index]) == 3 else (connPts[index][1], connPts[index][2]) if \
645
                    len(connPts[index]) == 4 else None
648 646
            self.parentSymbol = parentSymbol
649 647
            self.childSymbol = childSymbol
650 648
            self.hasInstrumentLabel = hasInstrumentLabel
......
1014 1012
            self.rotateSymbol()
1015 1013
        elif event.key() == Qt.Key_O and type(self) is not QEngineeringErrorItem:
1016 1014
            pass
1017
            #self.changeStandardPoint()
1018 1015
        elif event.key() == Qt.Key_C and type(self) is not QEngineeringErrorItem:
1019 1016
            self.changeConnPoint()
1020 1017
        elif event.key() == Qt.Key_F and type(self) is not QEngineeringErrorItem:
1021 1018
            self.flipSymbol()
1022
        elif event.key() == Qt.Key_X:
1019
        elif event.key() == Qt.Key_Return:
1023 1020
            dialog = QRotateSymbolDialog(None, self.angle, self.origin, self.zValue())
1024 1021
            (isAccept, angle, x, y, z) = dialog.showDialog()
1025 1022

  
......
1027 1024
                self.angle = angle
1028 1025
                self.loc = [x - self.symbolOrigin[0], y - self.symbolOrigin[1]]
1029 1026
                self.origin = [x, y]
1030
                # scene = self.scene()
1031
                # scene.removeItem(self)
1032
                # self.addSvgItemToScene(scene)
1033 1027
                self.rotate(self.getCurrentPoint(), self.angle)
1034 1028
                self.setZValue(z)
1035 1029
        elif event.key() == Qt.Key_Escape:
......
1043 1037
                self.setTransform(transform)
1044 1038

  
1045 1039
                del self._rotating
1046
        elif event.key() == Qt.Key_Up:  ### translate up/down/left/right symbol
1047
            self.loc[1] = self.loc[1] - 1
1048
            self.origin[1] = self.origin[1] - 1
1040
        elif event.key() == Qt.Key_Up:  # translate up/down/left/right symbol
1041
            modifiers = QApplication.keyboardModifiers()
1042
            delta = 5 if modifiers == Qt.ControlModifier else 1
1043

  
1044
            self.loc[1] = self.loc[1] - delta
1045
            self.origin[1] = self.origin[1] - delta
1049 1046
            self.rotate(self.getCurrentPoint(), self.angle)
1050 1047
        elif event.key() == Qt.Key_Down:
1051
            self.loc[1] = self.loc[1] + 1
1052
            self.origin[1] = self.origin[1] + 1
1048
            modifiers = QApplication.keyboardModifiers()
1049
            delta = 5 if modifiers == Qt.ControlModifier else 1
1050

  
1051
            self.loc[1] = self.loc[1] + delta
1052
            self.origin[1] = self.origin[1] + delta
1053 1053
            self.rotate(self.getCurrentPoint(), self.angle)
1054 1054
        elif event.key() == Qt.Key_Left:
1055
            self.loc[0] = self.loc[0] - 1
1056
            self.origin[0] = self.origin[0] - 1
1055
            modifiers = QApplication.keyboardModifiers()
1056
            delta = 5 if modifiers == Qt.ControlModifier else 1
1057

  
1058
            self.loc[0] = self.loc[0] - delta
1059
            self.origin[0] = self.origin[0] - delta
1057 1060
            self.rotate(self.getCurrentPoint(), self.angle)
1058 1061
        elif event.key() == Qt.Key_Right:
1059
            self.loc[0] = self.loc[0] + 1
1060
            self.origin[0] = self.origin[0] + 1
1062
            modifiers = QApplication.keyboardModifiers()
1063
            delta = 5 if modifiers == Qt.ControlModifier else 1
1064

  
1065
            self.loc[0] = self.loc[0] + delta
1066
            self.origin[0] = self.origin[0] + delta
1061 1067
            self.rotate(self.getCurrentPoint(), self.angle)
1062
        elif event.key() == Qt.Key_I:
1068
        elif event.key() == Qt.Key_I or event.key() == Qt.Key_X:
1063 1069
            from App import App 
1064 1070
            App.mainWnd().keyPressEvent(event)
1065 1071

  
......
1383 1389
            if component['ConnectionPoint']:
1384 1390
                for conn_pt in component['ConnectionPoint'].split('/'):
1385 1391
                    tokens = conn_pt.split(',')
1386
                    connPts.append(('AUTO', float(tokens[0]), float(tokens[1]), '0') if len(tokens) == 2 else \
1387
                                       (tokens[0], float(tokens[1]), float(tokens[2]), '0') if len(tokens) == 3 else \
1388
                                           (tokens[0], float(tokens[1]), float(tokens[2]), tokens[3]))
1392
                    connPts.append(('AUTO', float(tokens[0]), float(tokens[1]), '0') if len(tokens) == 2 else
1393
                                   (tokens[0], float(tokens[1]), float(tokens[2]), '0') if len(tokens) == 3 else
1394
                                   (tokens[0], float(tokens[1]), float(tokens[2]), tokens[3]))
1389 1395

  
1390 1396
            baseSymbol = dbData.baseSymbol
1391 1397

  
......
1394 1400

  
1395 1401
            owner = component['Owner'] if component['Owner'] is not None and component['Owner'] != 'None' else None
1396 1402

  
1397
            #hasInstrumentLabelNode = component['HasInstrumentLabel']
1398 1403
            hasInstrumentLabel = dbData.hasInstrumentLabel
1399 1404

  
1400 1405
            flipLabelNode = component['Flip']
DTI_PID/DTI_PID/SymbolTreeWidget.py
257 257
            os.makedirs(tempDir)
258 258

  
259 259
    def showSymbolEditorDialog(self, item, columnNo, display=False):
260
        """pop up symbol editor dialog"""
261

  
260 262
        try:
261 263
            sym = self.getSymbolByItemName(item, columnNo)
262 264
            if sym and display:
......
292 294
                                                           sys.exc_info()[-1].tb_lineno)
293 295
            App.mainWnd().addMessage.emit(MessageType.Error, message)
294 296

  
297
    def select_symbol(self, symbol):
298
        """select a tree with given symbol"""
299

  
300
        founds = self.findItems(symbol.name, Qt.MatchExactly | Qt.MatchRecursive, 0)
301
        if founds:
302
            self.setCurrentItem(founds[0])
303

  
295 304
    def itemDoubleClickEvent(self, item, columnNo):
296 305
        self.isDoubleClicked = True
297 306
        sym = self.getSymbolByItemName(item, columnNo)
DTI_PID/DTI_PID/potrace.py
14 14
from LineDetector import LineDetector
15 15

  
16 16
# potrace command
17
POTRACE = os.path.dirname(os.path.realpath(__file__)) + '\\potrace.exe'
17
POTRACE = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'potrace.exe')
18 18
ADJUST = 10
19 19

  
20
def convertImageToSvg(imgFilePath, destFilePath, normalColor, hoverColor):
21
    thresh = 127
20
def convertImageToSvg(imgFilePath, destFilePath, normalColor, hoverColor, threshold=200):
21
    """convert image to svg file by using potrace"""
22 22

  
23
    image  = cv2.imread(imgFilePath, cv2.IMREAD_GRAYSCALE)
24
    threshold = cv2.threshold(image, thresh, 255, cv2.THRESH_BINARY)[1]
23
    image = cv2.imread(imgFilePath, cv2.IMREAD_GRAYSCALE)
24
    threshold = cv2.threshold(image, threshold, 255, cv2.THRESH_BINARY)[1]
25 25

  
26 26
    # convert to bmp binary so that potrace can handle it
27 27
    retval, buf = cv2.imencode('.bmp', threshold)
28
    if retval == False:
28
    if not retval:
29 29
        raise ValueError('Failed to convert into BMP binary data')
30 30
    # convert buf from numpy.ndarray to bytes
31 31
    binbmp = buf.tobytes()
DTI_PID/DTI_PID/symbol.py
12 12
class Symbol(SymbolBase):
13 13
    def __init__(self, sName, sType, sp, width, height, threshold, minMatchCount, hitRate, rotatedAngle
14 14
                 , isDetectOnOrigin, rotationCount, ocrOption, isContainChild = 0
15
                 , originalPoint = None, connectionPoint = None, baseSymbol = None, additionalSymbol = None, isExceptDetect = 0, hasInstrumentLabel = 0, uid = None, detectFlip = None):
15
                 , originalPoint = None, connectionPoint = None, baseSymbol = None, additionalSymbol = None
16
                 , isExceptDetect = 0, hasInstrumentLabel = 0, uid = None, detectFlip = None):
16 17
        SymbolBase.__init__(self, sName, sType, threshold, minMatchCount
17 18
                            , isDetectOnOrigin, rotationCount, ocrOption, isContainChild
18
                            , originalPoint, connectionPoint, baseSymbol, additionalSymbol, isExceptDetect, hasInstrumentLabel, uid, detectFlip=detectFlip)
19
                            , originalPoint, connectionPoint, baseSymbol, additionalSymbol, isExceptDetect
20
                            , hasInstrumentLabel, uid, detectFlip=detectFlip)
19 21
        self.sp = sp
20 22
        self.width = width
21 23
        self.height = height

내보내기 Unified diff

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