프로젝트

일반

사용자정보

개정판 e4b3e191

IDe4b3e1915d37b5a8b247a5fb46974d44696386b3
상위 dcdd75a6
하위 a372ce6a

humkyung 이(가) 약 7년 전에 추가함

fixed issue #480: 라인 인식

차이점 보기:

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

  
3
import sys
4
import os
5
import cv2
6

  
7
from PyQt5.QtCore import *
8
from PyQt5.QtGui import *
9
from PyQt5.QtWidgets import *
10
from PyQt5.QtSvg import *
11

  
12
import DTI_PID_UI
13
import QtImageViewer
14

  
15
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Commands')
16
import CreateCommand
17
import CropCommand
18

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

  
25
class Worker(QObject):
26
    from PyQt5.QtCore import QThread
27
    from PyQt5.QtWidgets import QApplication, QLabel, QWidget, QGridLayout
28
    import sys
29
    from DTI_PID import executeRecognition
30

  
31
    finished = pyqtSignal()
32
    intReady = pyqtSignal(int)
33

  
34
    #pyqtSlot()
35
    def procCounter(self): # A slot takes no params
36
        from DTI_PID import executeRecognition
37

  
38
        try:
39
            self.xmlPath = executeRecognition(self.path, self.listWidget)
40
            self.finished.emit()
41
        except Exception as ex:
42
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
43

  
44
class SingletonInstane:
45
    __instance = None
46

  
47
    @classmethod
48
    def __getInstance(cls):
49
        return cls.__instance
50

  
51
    @classmethod
52
    def instance(cls, *args, **kargs):
53
        cls.__instance = cls(*args, **kargs)
54
        cls.instance = cls.__getInstance
55
        return cls.__instance
56

  
57
class ExampleApp(QMainWindow, DTI_PID_UI.Ui_MainWindow, SingletonInstane):
58
    def __init__(self):
59
        super(self.__class__, self).__init__()
60
        self.setupUi(self)
61
        self.lineComboBox = QComboBox(self.toolBar)
62
        self.lineComboBox.addItem('Primary Line')
63
        self.lineComboBox.addItem('Secondary Line')
64
        self.lineComboBox.addItem('Utility Line')
65
        self.toolBar.insertWidget(self.actionValidate, self.lineComboBox)
66
        self.toolBar.insertSeparator(self.actionValidate)
67
        self.graphicsView = QtImageViewer.QtImageViewer()
68
        self.graphicsView.setParent(self.centralwidget)
69
        self.verticalLayout.addWidget(self.graphicsView)
70

  
71
        # connect signals and slots
72
        self.actionClose.triggered.connect(self.close)
73
        self.actionOpen.triggered.connect(self.openImageDrawing)
74
        self.actionEqpNozzle.triggered.connect(self.connectEqpNozzle)
75
        self.actionLine.triggered.connect(self.createLine)
76
        self.actionRecognition.triggered.connect(self.recognize)
77
        self.actionConfiguration.triggered.connect(self.configuration)
78
    
79
    '''
80
        @brief  configuration
81
    '''
82
    def configuration(self):
83
        from QConfigurationDialog import QConfigurationDialog
84

  
85
        self.dlgConfiguration = QConfigurationDialog(self)
86
        self.dlgConfiguration.show()
87
        self.dlgConfiguration.exec_()
88
        
89
    '''
90
        @brief Open image drawing file and then display it
91
    '''
92
    def openImageDrawing(self, MainWindow):
93
        self.path = self.graphicsView.loadImageFromFile()
94

  
95
        svg = SymbolSvg()
96
        svg.setPos(100,100) 
97
        self.graphicsView.scene.addItem(svg)
98

  
99
        # DEBUG
100
        '''
101
        from LineDetector import LineDetector
102
        self.loadRecognitionResult('d:\\Projects\\DTIPID\\DTI_PID\\DTI_PID\\res\\Result\\UY1-K-2007_P1_300dpi_black.xml')
103

  
104
        # detect line
105
        img = cv2.imread(self.path)
106
        detector = LineDetector(img)
107
        for item in self.graphicsView.scene.items():
108
            if type(item) is QGraphicsBoundingBoxItem:
109
                res = detector.Detect(item)
110
                for pts in res:
111
                    line = QEngineeringLineItem()
112
                    line._vertices.append(QPointF(pts[0][0], pts[0][1]))
113
                    line._vertices.append(QPointF(pts[1][0], pts[1][1]))
114
                    self.graphicsView.scene.addItem(line)
115

  
116
        detector.save()
117
        '''
118
        # up to here
119

  
120
        return self.path
121

  
122
    '''
123
        @brief  connect equipment and nozzle
124
    '''
125
    def connectEqpNozzle(self):
126
        self.graphicsView.command = None
127

  
128
    '''
129
        @brief  create a line
130
    '''
131
    def createLine(self):
132
        # set imageviewer's command
133
        self.graphicsView.command = CreateCommand.CreateCommand(self.graphicsView, QEngineeringLineItem())
134
        # up to here
135

  
136
    '''
137
        @brief recognize symbol and text
138
    '''
139
    def recognize(self, MainWindow):
140
        from QRecognitionDialog import QRecognitionDialog
141
        from LineDetector import LineDetector
142

  
143
        try:
144
            self.dlg = QRecognitionDialog(self)
145
            self.startThread()
146
            self.dlg.show()
147
            self.dlg.exec_()
148

  
149
            if self.dlg.isAccepted == True:
150
                self.loadRecognitionResult(self.xmlPath[0])
151

  
152
                # detect line
153
                img = cv2.imread(self.path)
154
                detector = LineDetector(img)
155
                for item in self.graphicsView.scene.items():
156
                    if (type(item) is QGraphicsBoundingBoxItem) and item.isSymbol:
157
                        res = detector.Detect(item)
158
                        for pts in res:
159
                            line = QEngineeringLineItem()
160
                            line._vertices.append(QPointF(pts[0][0], pts[0][1]))
161
                            line._vertices.append(QPointF(pts[1][0], pts[1][1]))
162
                            self.graphicsView.scene.addItem(line)
163
                # up to here
164
        except Exception as ex:
165
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
166

  
167
    '''
168
        @brief load recognition result
169
    '''
170
    def loadRecognitionResult(self, xmlPath):
171
        from xml.etree.ElementTree import Element, SubElement, dump, ElementTree, parse
172

  
173
        try:
174
            xml = parse(xmlPath)
175
            root = xml.getroot();
176
            for symbol in root.iter('SYMBOL'):
177
                pt = symbol.find('STARTPOINT').text.split(',')
178
                size = symbol.find('SIZE').text.split(',')
179
                item = QGraphicsBoundingBoxItem(float(pt[0]), float(pt[1]), float(size[0]), float(size[1]))
180
                item.isSymbol = True
181
                item.angle = float(symbol.find('ANGLE').text)
182
                item.setPen(QPen(Qt.red, 20, Qt.SolidLine))
183
                self.graphicsView.scene.addItem(item)
184
            '''
185
            for text in root.iter('TEXTINFO'):
186
                x = float(text.find('X').text)
187
                y = float(text.find('Y').text)
188
                width = float(text.find('WIDTH').text)
189
                height = float(text.find('HEIGHT').text)
190
                item = QGraphicsBoundingBoxItem(x, y, width, height)
191
                item.setPen(QPen(Qt.blue, 20, Qt.SolidLine))
192
                self.graphicsView.scene.addItem(item)
193
            '''
194
        except Exception as ex:
195
            print('error occured {} as at {0}'.format(ex, sys.exc_info()[-1].tb_lineno))
196

  
197
    '''
198
        @brief start thread
199
    '''
200
    def startThread(self):
201
        self.dlg.ui.buttonBox.setDisabled(True)
202

  
203
        # 1 - create Worker and Thread inside the Form
204
        self.obj = Worker()  # no parent!
205
        self.obj.path = self.path
206
        self.obj.listWidget = self.dlg.ui.listWidget
207
        self.thread = QThread()  # no parent!
208

  
209
        # 2 - Connect Worker`s Signals to Form method slots to post data.
210
        #self.obj.intReady.connect(self.onIntReady)
211

  
212
        # 3 - Move the Worker object to the Thread object
213
        self.obj.moveToThread(self.thread)
214

  
215
        # 4 - Connect Worker Signals to the Thread slots
216
        self.obj.finished.connect(self.thread.quit)
217

  
218
        # 5 - Connect Thread started signal to Worker operational slot method
219
        self.thread.started.connect(self.obj.procCounter)
220

  
221
        # * - Thread finished signal will close the app if you want!
222
        self.thread.finished.connect(self.dlgExit)
223

  
224
        # 6 - Start the thread
225
        self.thread.start()
226

  
227
    '''
228
        @brief set buttonbox's enabled flag
229
    '''
230
    def dlgExit(self):
231
        self.xmlPath = self.obj.xmlPath
232
        self.dlg.ui.buttonBox.setEnabled(True)
233

  
234
if __name__ == '__main__':
235
    import DTI_PID_UI
236
    from ProjectDialog import Ui_Dialog
237

  
238
    app = QApplication(sys.argv)
239

  
240
    try:
241
        dlg = Ui_Dialog()
242
        dlg.show()
243
        dlg.exec_()
244
        if dlg.selectedProject is not None:
245
            form = ExampleApp.instance()
246
            form.show()
247
    except Exception as ex:
248
        print('에러가 발생했습니다.\n', ex)
249

  
250
    sys.exit(app.exec_())
DTI_PID/DTI_PID/AppDocData.py
1
# coding: utf-8
2

  
3
import os
4
import sqlite3
5
from SingletonInstance import SingletonInstane
6

  
7
DB_NAME = os.path.dirname(os.path.realpath(__file__)) + "\\db\\DTI_PID.db"
8

  
9
class AppDocData(SingletonInstane):
10
    '''
11
        @brief  get sliding window size
12
    '''
13
    def getSlidingWindowSize(self):
14
        res = [10,10]
15
        try:
16
            # Creates or opens a file called mydb with a SQLite3 DB
17
            db = sqlite3.connect(DB_NAME)
18
            # Get a cursor object
19
            cursor = db.cursor()
20

  
21
            sql = "select * from configuration where section='Sliding Window'"
22
            cursor.execute(sql)
23
            rows = cursor.fetchall()
24
            for row in rows:
25
                if row[1] == 'Width':
26
                    res[0] = int(row[2])
27
                elif row[1] == 'Height':
28
                    res[1] = int(row[2])
29
        # Catch the exception
30
        except Exception as e:
31
            # Roll back any change if something goes wrong
32
            db.rollback()
33
            raise e
34
        finally:
35
            # Close the db connection
36
            db.close()
37
        
38
        return res
39

  
40
    pass
DTI_PID/DTI_PID/DTI_PID.py
719 719

  
720 720

  
721 721
#Main function
722
def main(path, listWidget):
722
def executeRecognition(path, listWidget):
723 723
    global src
724 724
    global srcGray
725 725
    global ocrCompletedSrc
......
818 818
    
819 819
    return res
820 820
    
821
class Worker(QObject):
822
    from PyQt5.QtCore import QThread
823
    from PyQt5.QtWidgets import QApplication, QLabel, QWidget, QGridLayout
824
    import sys
825

  
826
    finished = pyqtSignal()
827
    intReady = pyqtSignal(int)
828

  
829
    #pyqtSlot()
830
    def procCounter(self): # A slot takes no params
831
        self.xmlPath = main(self.path, self.listWidget)
832
        self.finished.emit()
833

  
834
class ExampleApp(QMainWindow, DTI_PID_UI.Ui_MainWindow):
835
    def __init__(self):
836
        super(self.__class__, self).__init__()
837
        self.setupUi(self)
838
        self.lineComboBox = QComboBox(self.toolBar)
839
        self.lineComboBox.addItem('Primary Line')
840
        self.lineComboBox.addItem('Secondary Line')
841
        self.lineComboBox.addItem('Utility Line')
842
        self.toolBar.insertWidget(self.actionValidate, self.lineComboBox)
843
        self.toolBar.insertSeparator(self.actionValidate)
844
        self.graphicsView = QtImageViewer.QtImageViewer()
845
        self.graphicsView.setParent(self.centralwidget)
846
        self.verticalLayout.addWidget(self.graphicsView)
847

  
848
        # connect signals and slots
849
        self.actionClose.triggered.connect(self.close)
850
        self.actionOpen.triggered.connect(self.openImageDrawing)
851
        self.actionEqpNozzle.triggered.connect(self.connectEqpNozzle)
852
        self.actionLine.triggered.connect(self.createLine)
853
        self.actionRecognition.triggered.connect(self.recognize)
854
        self.actionConfiguration.triggered.connect(self.configuration)
855
    
856
    '''
857
        @brief  configuration
858
    '''
859
    def configuration(self):
860
        from QConfigurationDialog import QConfigurationDialog
861

  
862
        self.dlgConfiguration = QConfigurationDialog(self)
863
        self.dlgConfiguration.show()
864
        self.dlgConfiguration.exec_()
865
        
866
    '''
867
        @brief Open image drawing file and then display it
868
    '''
869
    def openImageDrawing(self, MainWindow):
870
        self.path = self.graphicsView.loadImageFromFile()
871

  
872
        svg = SymbolSvg()
873
        svg.setPos(100,100) 
874
        self.graphicsView.scene.addItem(svg)
875

  
876
        # DEBUG
877
        '''
878
        from LineDetector import LineDetector
879
        self.loadRecognitionResult('d:\\Projects\\DTIPID\\DTI_PID\\DTI_PID\\res\\Result\\UY1-K-2007_P1_300dpi_black.xml')
880

  
881
        # detect line
882
        img = cv2.imread(self.path)
883
        detector = LineDetector(img)
884
        for item in self.graphicsView.scene.items():
885
            if type(item) is QGraphicsBoundingBoxItem:
886
                res = detector.Detect(item)
887
                for pts in res:
888
                    line = QEngineeringLineItem()
889
                    line._vertices.append(QPointF(pts[0][0], pts[0][1]))
890
                    line._vertices.append(QPointF(pts[1][0], pts[1][1]))
891
                    self.graphicsView.scene.addItem(line)
892

  
893
        detector.save()
894
        '''
895
        # up to here
896

  
897
        return self.path
898

  
899
    '''
900
        @brief  connect equipment and nozzle
901
    '''
902
    def connectEqpNozzle(self):
903
        self.graphicsView.command = None
904

  
905
    '''
906
        @brief  create a line
907
    '''
908
    def createLine(self):
909
        # set imageviewer's command
910
        self.graphicsView.command = CreateCommand.CreateCommand(self.graphicsView, QEngineeringLineItem())
911
        # up to here
912

  
913
    '''
914
        @brief recognize symbol and text
915
    '''
916
    def recognize(self, MainWindow):
917
        from QRecognitionDialog import QRecognitionDialog
918
        from LineDetector import LineDetector
919

  
920
        try:
921
            self.dlg = QRecognitionDialog(self)
922
            self.startThread()
923
            self.dlg.show()
924
            self.dlg.exec_()
925

  
926
            if self.dlg.isAccepted == True:
927
                self.loadRecognitionResult(self.xmlPath[0])
928

  
929
                # detect line
930
                img = cv2.imread(self.path)
931
                detector = LineDetector(img)
932
                for item in self.graphicsView.scene.items():
933
                    if (type(item) is QGraphicsBoundingBoxItem) and item.isSymbol:
934
                        res = detector.Detect(item)
935
                        for pts in res:
936
                            line = QEngineeringLineItem()
937
                            line._vertices.append(QPointF(pts[0][0], pts[0][1]))
938
                            line._vertices.append(QPointF(pts[1][0], pts[1][1]))
939
                            self.graphicsView.scene.addItem(line)
940
                # up to here
941
        except Exception as ex:
942
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
943

  
944
    '''
945
        @brief load recognition result
946
    '''
947
    def loadRecognitionResult(self, xmlPath):
948
        from xml.etree.ElementTree import Element, SubElement, dump, ElementTree, parse
949

  
950
        try:
951
            xml = parse(xmlPath)
952
            root = xml.getroot();
953
            for symbol in root.iter('SYMBOL'):
954
                pt = symbol.find('STARTPOINT').text.split(',')
955
                size = symbol.find('SIZE').text.split(',')
956
                item = QGraphicsBoundingBoxItem(float(pt[0]), float(pt[1]), float(size[0]), float(size[1]))
957
                item.isSymbol = True
958
                item.angle = float(symbol.find('ANGLE').text)
959
                item.setPen(QPen(Qt.red, 20, Qt.SolidLine))
960
                self.graphicsView.scene.addItem(item)
961
            '''
962
            for text in root.iter('TEXTINFO'):
963
                x = float(text.find('X').text)
964
                y = float(text.find('Y').text)
965
                width = float(text.find('WIDTH').text)
966
                height = float(text.find('HEIGHT').text)
967
                item = QGraphicsBoundingBoxItem(x, y, width, height)
968
                item.setPen(QPen(Qt.blue, 20, Qt.SolidLine))
969
                self.graphicsView.scene.addItem(item)
970
            '''
971
        except Exception as ex:
972
            print('error occured {} as at {0}'.format(ex, sys.exc_info()[-1].tb_lineno))
973

  
974
    '''
975
        @brief start thread
976
    '''
977
    def startThread(self):
978
        self.dlg.ui.buttonBox.setDisabled(True)
979

  
980
        # 1 - create Worker and Thread inside the Form
981
        self.obj = Worker()  # no parent!
982
        self.obj.path = self.path
983
        self.obj.listWidget = self.dlg.ui.listWidget
984
        self.thread = QThread()  # no parent!
985

  
986
        # 2 - Connect Worker`s Signals to Form method slots to post data.
987
        #self.obj.intReady.connect(self.onIntReady)
988

  
989
        # 3 - Move the Worker object to the Thread object
990
        self.obj.moveToThread(self.thread)
991

  
992
        # 4 - Connect Worker Signals to the Thread slots
993
        self.obj.finished.connect(self.thread.quit)
994

  
995
        # 5 - Connect Thread started signal to Worker operational slot method
996
        self.thread.started.connect(self.obj.procCounter)
997

  
998
        # * - Thread finished signal will close the app if you want!
999
        self.thread.finished.connect(self.dlgExit)
1000

  
1001
        # 6 - Start the thread
1002
        self.thread.start()
1003

  
1004
    '''
1005
        @brief set buttonbox's enabled flag
1006
    '''
1007
    def dlgExit(self):
1008
        self.xmlPath = self.obj.xmlPath
1009
        self.dlg.ui.buttonBox.setEnabled(True)
1010

  
1011 821
if __name__ == '__main__':
1012 822
    import DTI_PID_UI
1013 823
    from ProjectDialog import Ui_Dialog
DTI_PID/DTI_PID/LineDetector.py
143 143
    '''
144 144
    def Detect(self, symbol):
145 145
        res = []
146
        #white = [255,255,255]
147 146

  
148 147
        try:
149 148
            pool = []
......
186 185
        @brief  detect a line along given direction
187 186
    '''
188 187
    def detectLine(self, pt, dir):
188
        from AppDocData import AppDocData
189

  
189 190
        white = [255,255,255]
190
        windowSize = [20,10]
191
        windowSize = AppDocData.instance().getSlidingWindowSize()
191 192
        xHalf = int(windowSize[0]*0.5)
192 193
        yHalf = int(windowSize[1]*0.5)
193 194

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

  
3
class SingletonInstane:
4
    __instance = None
5

  
6
    @classmethod
7
    def __getInstance(cls):
8
        return cls.__instance
9

  
10
    @classmethod
11
    def instance(cls, *args, **kargs):
12
        cls.__instance = cls(*args, **kargs)
13
        cls.instance = cls.__getInstance
14
        return cls.__instance

내보내기 Unified diff

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