프로젝트

일반

사용자정보

개정판 ea56968c

IDea56968c08547b5f5e1e72eba93d87611ef481bc
상위 8a5dd90b
하위 5fd8cd99, e2ef91ae

김정우 이(가) 약 7년 전에 추가함

복합 심볼 정보를 xml에 기재 방식 변경/ DecoDirection->ChildInfo / 심볼제작툴 작업시작

차이점 보기:

DTI_PID/DTI_PID/DTI_PID.py
112 112
        ry = originImageWidth - x
113 113
    return (rx, ry)
114 114

  
115
def getRotatedChildInfo(symbolChildInfo):
116
    childList = symbolChildInfo.split("/")
117
    tempChildInfo = ""
118
    for index in range(len(childList)):
119
        child = childList[index]
120
        direction = int(child.split(",")[0])
121
        childName = child.split(",")[1]
122
        direction = (direction - 1) if direction > 0 else 3
123
        if index != 0:
124
            tempChildInfo = tempChildInfo + "/"
125
        tempChildInfo = tempChildInfo + str(direction) + "," + childName
126
    return tempChildInfo
127

  
115 128

  
116 129
#Check object contains pt
117 130
#obj is item in searchedSymbolList
......
146 159
            splitRoiList.append((roiSp, roiEp, srcPid[roiSp[1]:roiEp[1], roiSp[0]:roiEp[0]]))
147 160
    return splitRoiList
148 161

  
149
def getCalculatedOriginalPoint(symbolDecoDirection, symbolOriginalPoint, symbolRotatedAngle, rotateSymbolWidth, rotateSymbolHeight, originalSymbolWidth, originalSymbolHeight):
162
def getCalculatedOriginalPoint(symbolChildInfo, symbolOriginalPoint, symbolRotatedAngle, rotateSymbolWidth, rotateSymbolHeight, originalSymbolWidth, originalSymbolHeight):
150 163
    originalPoint = ''
151
    if symbolDecoDirection == -1 and symbolOriginalPoint is None:
164
    if symbolChildInfo is None and symbolOriginalPoint is None:
152 165
        originalPoint = str(rotateSymbolWidth//2)+','+str(rotateSymbolHeight//2)
153 166
    else:
154 167
        opx = int(symbolOriginalPoint.split(',')[0])
......
163 176
def addSearchedSymbol(id, sCategory, sClass, sType, sItem, symbolPath
164 177
                      , pt, w, h, threshold, minMatchCount, mpCount, rotatedAngle
165 178
                      , isDetectOnOrigin, rotateCount, ocrOption, isContainChild
166
                      , decoDirection, originalPoint, connectionPoint):
179
                      , childInfo, originalPoint, connectionPoint):
167 180
    global searchedSymbolList
168 181
    newSym = symbol.Symbol(id, sCategory, sClass, sType, sItem, symbolPath
169 182
                           , pt, w, h, threshold, minMatchCount, mpCount, rotatedAngle
170 183
                           , isDetectOnOrigin, rotateCount, ocrOption, isContainChild
171
                           , decoDirection, originalPoint, connectionPoint)
184
                           , childInfo, originalPoint, connectionPoint)
172 185
    searchedSymbolList.append(newSym)
173 186

  
174 187

  
......
238 251
    symbolRotateCount = targetSymbol.getRotationCount()
239 252
    symbolOcrOption = targetSymbol.getOcrOption()
240 253
    isContainChild = targetSymbol.getIsContainChild()
241
    symbolDecoDirection = targetSymbol.getDecoDirection()
254
    symbolChildInfo = targetSymbol.getChildInfo()
242 255
    symbolOriginalPoint = targetSymbol.getOriginalPoint()
243 256
    symbolConnectionPoint = targetSymbol.getConnectionPoint()
244 257

  
......
289 302
                if roiw < sw or roih < sh:
290 303
                    symGray = cv2.rotate(symGray, cv2.ROTATE_90_COUNTERCLOCKWISE)
291 304
                    symbolRotatedAngle = symbolRotatedAngle + 90
292
                    if symbolDecoDirection > 0:
293
                        symbolDecoDirection = (symbolDecoDirection + 1) % 4
305

  
306
                    if symbolChildInfo is not None:
307
                        symbolChildInfo = getRotatedChildInfo(symbolChildInfo)
294 308
                    continue
295 309
                
296 310
                ## get Rotated Original Point
297
                originalPoint = getCalculatedOriginalPoint(symbolDecoDirection, symbolOriginalPoint, symbolRotatedAngle, sw, sh, sow, soh)
311
                originalPoint = getCalculatedOriginalPoint(symbolChildInfo, symbolOriginalPoint, symbolRotatedAngle, sw, sh, sow, soh)
298 312

  
299 313

  
300 314
                ## Template Matching
......
330 344
                            addSearchedSymbol(symId, symbolName, symbolClass, symbolType, symbolItem
331 345
                                              , symbolPath, searchedItemSp, sw, sh, symbolThreshold, symbolMinMatchCount
332 346
                                              , mpCount, symbolRotatedAngle, isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild
333
                                              , symbolDecoDirection, originalPoint, symbolConnectionPoint)
347
                                              , symbolChildInfo, originalPoint, symbolConnectionPoint)
334 348
                            threadLock.release()
335 349
                    ## 겹치는 영역이 기준값보다 클 경우
336 350
                    else:
......
345 359
                                    searchedSymbolList[symbolIndex] = symbol.Symbol(symId, symbolName, symbolClass, symbolType, symbolItem
346 360
                                                                                    , symbolPath, searchedItemSp, sw, sh, symbolThreshold, symbolMinMatchCount
347 361
                                                                                    , mpCount, symbolRotatedAngle, isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild
348
                                                                                    , symbolDecoDirection, originalPoint, symbolConnectionPoint)
362
                                                                                    , symbolChildInfo, originalPoint, symbolConnectionPoint)
349 363
                                    threadLock.release()
350 364
                            ## 현재 심볼과 검출된 심볼이 같지 않을 경우 (포함)
351 365
                            else:
......
362 376
                                            searchedSymbolList[searchedSymbolList.index(s)] = symbol.Symbol(symId, symbolName, symbolClass, symbolType, symbolItem
363 377
                                                                                            , symbolPath, searchedItemSp, sw, sh, symbolThreshold, symbolMinMatchCount
364 378
                                                                                            , mpCount, symbolRotatedAngle, isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild
365
                                                                                            , symbolDecoDirection, originalPoint, symbolConnectionPoint)
379
                                                                                            , symbolChildInfo, originalPoint, symbolConnectionPoint)
366 380
                                            threadLock.release()
367 381
                                else:
368 382
                                    if mpCount >= symbolMinMatchCount:
......
377 391
                                                addSearchedSymbol(symId, symbolName, symbolClass, symbolType, symbolItem
378 392
                                                                  , symbolPath, searchedItemSp, sw, sh, symbolThreshold, symbolMinMatchCount
379 393
                                                                  , mpCount, symbolRotatedAngle, isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild
380
                                                                  , symbolDecoDirection, originalPoint, symbolConnectionPoint)
394
                                                                  , symbolChildInfo, originalPoint, symbolConnectionPoint)
381 395
                                                threadLock.release()
382 396
                                
383 397
                ## Rotate Symbol
384 398
                symGray = cv2.rotate(symGray, cv2.ROTATE_90_COUNTERCLOCKWISE)
385 399
                symbolRotatedAngle = symbolRotatedAngle + 90
386
                if symbolDecoDirection >= 0:
387
                    symbolDecoDirection = (symbolDecoDirection + 1) % 4
400

  
401
                if symbolChildInfo is not None:
402
                    symbolChildInfo = getRotatedChildInfo(symbolChildInfo)
388 403

  
389 404
        splitCount = splitCount // 2
390 405

  
......
616 631
        if connectionPointList is not None and len(connectionPointList) > 0:
617 632
            symOpStr = sym.getOriginalPoint()
618 633
            symOp = (int(symOpStr.split(',')[0]), int(symOpStr.split(',')[1]))
619
            #symOp = getCoordOnRotatedImage(rotatedAngle, symOp[0], symOp[1], sow, soh)
634

  
620 635
            blank = np.zeros((symWidth, symHeight, 3), np.uint8)
621 636
            blank[::] = (255, 255, 255)
622 637
            blank = cvtGrayImage(blank)
623 638
            bw, bh = blank.shape[::-1]
624 639
            srcGray[symSp[1]:symSp[1]+bh, symSp[0]:symSp[0]+bw] = blank
625
            #getCoordOnRotatedImage(rotatedAngle, opx, opy, sow, soh)
640

  
626 641
            for cp in connectionPointList:
627 642
                pt = cp.split(",")
628 643
                cpx = int(pt[0])
......
681 696
        srcGray = cvtGrayImage(src)
682 697
    else:
683 698
        srcGray = src.copy()
684
    #srcGray = src
699

  
685 700
    (ocrCompletedSrc, textInfoList) = OCR.removeTextFromNpArray(srcGray)
686 701
    for textInfo in textInfoList:
687 702
        removeText(ocrCompletedSrc, textInfo.getText(), textInfo.getX(), textInfo.getY(), textInfo.getW(), textInfo.getH())
688
    #ocrCompletedSrc = srcGray.copy()
689
    #ocrCompletedSrc = TOCR.removeTextFromNpArray(srcGray, TOCR.FLAG_IMAGE_TO_DATA)
690 703

  
691 704

  
692 705
#Main function
DTI_PID/DTI_PID/DTI_PID.pyproj
39 39
    </Compile>
40 40
    <Compile Include="DTI_PID.py" />
41 41
    <Compile Include="potrace.py" />
42
    <Compile Include="QcImageViewer.py">
43
      <SubType>Code</SubType>
44
    </Compile>
45
    <Compile Include="QtImageViewer.py">
46
      <SubType>Code</SubType>
47
    </Compile>
42 48
    <Compile Include="symbol.py">
43 49
      <SubType>Code</SubType>
44 50
    </Compile>
45 51
    <Compile Include="SymbolBase.py">
46 52
      <SubType>Code</SubType>
47 53
    </Compile>
54
    <Compile Include="SymbolGenerator.py">
55
      <SubType>Code</SubType>
56
    </Compile>
48 57
    <Compile Include="tesseract_ocr_module.py">
49 58
      <SubType>Code</SubType>
50 59
    </Compile>
DTI_PID/DTI_PID/QcImageViewer.py
1
import sys
2
from PyQt5.QtCore import Qt
3
from PyQt5.QtWidgets import QWidget, QApplication, QGridLayout, QLabel
4
from PyQt5 import QtCore, QtGui, QtWidgets
5
from PyQt5.QtWidgets import *
6
from PyQt5.QtGui import *
7

  
8
CROP_AREA_MIN_SIZE = 10
9

  
10
class QcImageViewer(QGraphicsView):
11
    def __init__(self, filePath, imgW, imgH):
12
        super().__init__()
13
        print("__init__")
14
        self.filePath = filePath
15
        self.selectedArea = [(0, 0),(imgW, imgH)]
16
        self.imgW = imgW
17
        self.imgH = imgH
18
        self.zoom = 1.0
19
        self.isPressCtrl = False
20
        #PyQt5.QtCore.QRectF(3740.953125, 1164.765625, 1479.9375, 1891.03125)
21
        self.initImage()
22
        self.setMouseTracking(True)
23
        #self.mousePressEvent = self.mousePressEvent
24
        #self.mouseReleaseEvent = self.mouseReleaseEvent
25
        #self.mouseDoubleClickEvent = self.mouseDoubleClickEvent
26
        #self.wheelEvent = self.wheelEvent
27
        #self.keyPressEvent = self.keyPressEvent
28
        #self.keyReleaseEvent = self.keyReleaseEvent
29

  
30
    def mousePressEvent(self, event):
31
        if event.button() == QtCore.Qt.LeftButton:
32
            print("Pressed : " + str(event.x()) + ", " + str(event.y()))
33
            self.originPoint = event.pos()
34
            self.currentRect = QtCore.QRect()
35
            self.currentRect.setTopLeft(QtCore.QPoint(event.x(), event.y()))
36

  
37
    def mouseReleaseEvent(self, event):
38
        if event.button() == QtCore.Qt.LeftButton:
39
            print("Released : " + str(event.x()) + ", " + str(event.y()))
40
            self.currentRect.setBottomRight(QtCore.QPoint(event.x(), event.y()))
41

  
42
            if self.currentRect.width() > CROP_AREA_MIN_SIZE and self.currentRect.height() > CROP_AREA_MIN_SIZE:
43
                pixmap = self.pixmap().copy(self.currentRect)
44
                pixmap.scaled(self.currentRect.width(), self.currentRect.height())
45
                print("New Size : " + str(self.currentRect.width()) + "/" + str(self.currentRect.height()))
46
                self.setPixmap(pixmap)
47
                self.resize(self.currentRect.width(), self.currentRect.height())
48
                self.parentWidget().resize(self.currentRect.width(), self.currentRect.height())
49

  
50
    def mouseDoubleClickEvent(self, event):
51
        if event.button() == QtCore.Qt.RightButton:
52
            self.initImage()
53

  
54
    def keyPressEvent(self, event):
55
        if event.key() == QtCore.Qt.Key_Control:
56
            self.isPressCtrl = True
57
            print("Pressed Ctrl")
58

  
59
    def keyReleaseEvent(self, event):
60
        if event.key() == QtCore.Qt.Key_Control:
61
            self.isPressCtrl = False
62
            print("Released Ctrl")
63

  
64
    def wheelEvent(self, event):
65
        if self.isPressCtrl == True:
66
            event.modifiers()
67
            print("Pressed Ctrl and Mouse Wheel")
68

  
69
    def initImage(self):
70
        self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
71
        self.setScaledContents(True)
72
        pixmap = QPixmap(self.filePath)
73
        pixmap = pixmap.scaled(self.imgW, self.imgH, QtCore.Qt.KeepAspectRatioByExpanding)
74
        self.setPixmap(pixmap)
75
        self.resize(self.imgW, self.imgH)
76
        if self.parentWidget() is not None:
77
            self.parentWidget().resize(self.imgW, self.imgH)
DTI_PID/DTI_PID/QtImageViewer.py
1
import os.path
2
try:
3
    from PyQt5.QtCore import Qt, QRectF, pyqtSignal, QT_VERSION_STR
4
    from PyQt5.QtGui import QImage, QPixmap, QPainterPath
5
    from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QFileDialog
6
except ImportError:
7
    try:
8
        from PyQt4.QtCore import Qt, QRectF, pyqtSignal, QT_VERSION_STR
9
        from PyQt4.QtGui import QGraphicsView, QGraphicsScene, QImage, QPixmap, QPainterPath, QFileDialog
10
    except ImportError:
11
        raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.")
12

  
13

  
14
__author__ = "Marcel Goldschen-Ohm <marcel.goldschen@gmail.com>"
15
__version__ = '0.9.0'
16

  
17

  
18
class QtImageViewer(QGraphicsView):
19
    """ PyQt image viewer widget for a QPixmap in a QGraphicsView scene with mouse zooming and panning.
20
    Displays a QImage or QPixmap (QImage is internally converted to a QPixmap).
21
    To display any other image format, you must first convert it to a QImage or QPixmap.
22
    Some useful image format conversion utilities:
23
        qimage2ndarray: NumPy ndarray <==> QImage    (https://github.com/hmeine/qimage2ndarray)
24
        ImageQt: PIL Image <==> QImage  (https://github.com/python-pillow/Pillow/blob/master/PIL/ImageQt.py)
25
    Mouse interaction:
26
        Left mouse button drag: Pan image.
27
        Right mouse button drag: Zoom box.
28
        Right mouse button doubleclick: Zoom to show entire image.
29
    """
30
    
31
    MENU_HAND_TOOL = 0
32
    MENU_CROP_TOOL = 1
33
    MENU_ERASER_TOOL = 2
34
    MENU_PEN_TOOL = 3
35

  
36
    # Mouse button signals emit image scene (x, y) coordinates.
37
    # !!! For image (row, column) matrix indexing, row = y and column = x.
38
    leftMouseButtonPressed = pyqtSignal(float, float)
39
    rightMouseButtonPressed = pyqtSignal(float, float)
40
    leftMouseButtonReleased = pyqtSignal(float, float)
41
    rightMouseButtonReleased = pyqtSignal(float, float)
42
    leftMouseButtonDoubleClicked = pyqtSignal(float, float)
43
    rightMouseButtonDoubleClicked = pyqtSignal(float, float)
44

  
45
    def __init__(self):
46
        QGraphicsView.__init__(self)
47

  
48
        # Image is displayed as a QPixmap in a QGraphicsScene attached to this QGraphicsView.
49
        self.scene = QGraphicsScene()
50
        self.setScene(self.scene)
51
        self.scene.setBackgroundBrush(Qt.gray)
52

  
53
        self.isPressCtrl = False
54
        self.factor = 1.0
55
        self.numScheduledScalings = 0
56
        self.currentMenuTool = self.MENU_HAND_TOOL
57

  
58
        # Store a local handle to the scene's current image pixmap.
59
        self._pixmapHandle = None
60

  
61
        # Image aspect ratio mode.
62
        # !!! ONLY applies to full image. Aspect ratio is always ignored when zooming.
63
        #   Qt.IgnoreAspectRatio: Scale image to fit viewport.
64
        #   Qt.KeepAspectRatio: Scale image to fit inside viewport, preserving aspect ratio.
65
        #   Qt.KeepAspectRatioByExpanding: Scale image to fill the viewport, preserving aspect ratio.
66
        self.aspectRatioMode = Qt.KeepAspectRatio
67

  
68
        # Scroll bar behaviour.
69
        #   Qt.ScrollBarAlwaysOff: Never shows a scroll bar.
70
        #   Qt.ScrollBarAlwaysOn: Always shows a scroll bar.
71
        #   Qt.ScrollBarAsNeeded: Shows a scroll bar only when zoomed.
72
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
73
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
74

  
75
        # Stack of QRectF zoom boxes in scene coordinates.
76
        self.zoomStack = []
77

  
78
        # Flags for enabling/disabling mouse interaction.
79
        self.canZoom = True
80
        self.canPan = True
81

  
82
    def hasImage(self):
83
        """ Returns whether or not the scene contains an image pixmap.
84
        """
85
        return self._pixmapHandle is not None
86

  
87
    def clearImage(self):
88
        """ Removes the current image pixmap from the scene if it exists.
89
        """
90
        if self.hasImage():
91
            self.scene.removeItem(self._pixmapHandle)
92
            self._pixmapHandle = None
93

  
94
    def pixmap(self):
95
        """ Returns the scene's current image pixmap as a QPixmap, or else None if no image exists.
96
        :rtype: QPixmap | None
97
        """
98
        if self.hasImage():
99
            return self._pixmapHandle.pixmap()
100
        return None
101

  
102
    def image(self):
103
        """ Returns the scene's current image pixmap as a QImage, or else None if no image exists.
104
        :rtype: QImage | None
105
        """
106
        if self.hasImage():
107
            return self._pixmapHandle.pixmap().toImage()
108
        return None
109

  
110
    def setImage(self, image):
111
        """ Set the scene's current image pixmap to the input QImage or QPixmap.
112
        Raises a RuntimeError if the input image has type other than QImage or QPixmap.
113
        :type image: QImage | QPixmap
114
        """
115
        if type(image) is QPixmap:
116
            pixmap = image
117
        elif type(image) is QImage:
118
            pixmap = QPixmap.fromImage(image)
119
        else:
120
            raise RuntimeError("ImageViewer.setImage: Argument must be a QImage or QPixmap.")
121
        if self.hasImage():
122
            self._pixmapHandle.setPixmap(pixmap)
123
        else:
124
            self._pixmapHandle = self.scene.addPixmap(pixmap)
125

  
126
        self.setSceneRect(QRectF(pixmap.rect()))  # Set scene size to image size.
127
        self.updateViewer()
128

  
129
    def loadImageFromFile(self, fileName=""):
130
        """ Load an image from file.
131
        Without any arguments, loadImageFromFile() will popup a file dialog to choose the image file.
132
        With a fileName argument, loadImageFromFile(fileName) will attempt to load the specified image file directly.
133
        """
134
        if len(fileName) == 0:
135
            if QT_VERSION_STR[0] == '4':
136
                fileName = QFileDialog.getOpenFileName(self, "Open image file.")
137
            elif QT_VERSION_STR[0] == '5':
138
                fileName, dummy = QFileDialog.getOpenFileName(self, "Open image file.")
139
        if len(fileName) and os.path.isfile(fileName):
140
            image = QImage(fileName)
141
            self.setImage(image)
142

  
143
    def updateViewer(self):
144
        """ Show current zoom (if showing entire image, apply current aspect ratio mode).
145
        """
146
        if not self.hasImage():
147
            return
148
        if len(self.zoomStack) and self.sceneRect().contains(self.zoomStack[-1]):
149
            self.fitInView(self.zoomStack[-1], Qt.KeepAspectRatioByExpanding)  # Show zoomed rect (ignore aspect ratio).
150
        else:
151
            self.zoomStack = []  # Clear the zoom stack (in case we got here because of an invalid zoom).
152
            self.fitInView(self.sceneRect(), self.aspectRatioMode)  # Show entire image (use current aspect ratio mode).
153
        #self.setFocusPolicy(Qt.StrongFocus)
154
        #self.setFocus(True)
155

  
156
    def resizeEvent(self, event):
157
        """ Maintain current zoom on resize.
158
        """
159
        self.updateViewer()
160

  
161
    def mousePressEvent(self, event):
162
        """ Start mouse pan or zoom mode.
163
        """
164
        scenePos = self.mapToScene(event.pos())
165
        if event.button() == Qt.LeftButton:
166
            if self.canPan and self.currentMenuTool == self.MENU_HAND_TOOL:
167
                self.setDragMode(QGraphicsView.ScrollHandDrag)
168
            elif self.currentMenuTool == self.MENU_CROP_TOOL:
169
                self.setDragMode(QGraphicsView.RubberBandDrag)
170
            self.leftMouseButtonPressed.emit(scenePos.x(), scenePos.y())
171
        elif event.button() == Qt.RightButton:
172
            if self.canZoom:
173
                self.setDragMode(QGraphicsView.RubberBandDrag)
174
            self.rightMouseButtonPressed.emit(scenePos.x(), scenePos.y())
175
        QGraphicsView.mousePressEvent(self, event)
176

  
177
    def mouseReleaseEvent(self, event):
178
        """ Stop mouse pan or zoom mode (apply zoom if valid).
179
        """
180
        QGraphicsView.mouseReleaseEvent(self, event)
181
        scenePos = self.mapToScene(event.pos())
182
        if event.button() == Qt.LeftButton:
183
            if self.currentMenuTool == self.MENU_CROP_TOOL:
184
                viewBBox = self.zoomStack[-1] if len(self.zoomStack) else self.sceneRect()
185
                selectionBBox = self.scene.selectionArea().boundingRect().intersected(viewBBox)
186

  
187
                croppedImage = self.image().copy(selectionBBox.toAlignedRect())
188
                self.setImage(croppedImage)
189
            self.setDragMode(QGraphicsView.NoDrag)
190
            self.leftMouseButtonReleased.emit(scenePos.x(), scenePos.y())
191
        elif event.button() == Qt.RightButton:
192
            if self.canZoom:
193
                viewBBox = self.zoomStack[-1] if len(self.zoomStack) else self.sceneRect()
194
                selectionBBox = self.scene.selectionArea().boundingRect().intersected(viewBBox)
195
                self.scene.setSelectionArea(QPainterPath())  # Clear current selection area.
196
                if selectionBBox.isValid() and (selectionBBox != viewBBox):
197
                    self.zoomStack.append(selectionBBox)
198
                    self.updateViewer()
199
            self.setDragMode(QGraphicsView.NoDrag)
200
            self.rightMouseButtonReleased.emit(scenePos.x(), scenePos.y())
201

  
202
    def mouseDoubleClickEvent(self, event):
203
        """ Show entire image.
204
        """
205
        scenePos = self.mapToScene(event.pos())
206
        if event.button() == Qt.LeftButton:
207
            self.leftMouseButtonDoubleClicked.emit(scenePos.x(), scenePos.y())
208
        elif event.button() == Qt.RightButton:
209
            if self.canZoom:
210
                self.zoomStack = []  # Clear zoom stack.
211
                self.updateViewer()
212
            self.rightMouseButtonDoubleClicked.emit(scenePos.x(), scenePos.y())
213
        QGraphicsView.mouseDoubleClickEvent(self, event)
214

  
215
    def keyPressEvent(self, event):
216
        if event.key() == Qt.Key_Control:
217
            self.isPressCtrl = True
218
            print("Pressed Ctrl")
219

  
220
    def keyReleaseEvent(self, event):
221
        if event.key() == Qt.Key_Control:
222
            self.isPressCtrl = False
223
            print("Released Ctrl")
224

  
225
    def wheelEvent(self, event):
226
        if self.isPressCtrl == True:
227
            print("Pressed Ctrl and Mouse Wheel")
228
            if self.canZoom:
229
                print("Zoomable")
230
                numDegrees = event.angleDelta().y() // 8
231
                numSteps = numDegrees // 15
232
                self.numScheduledScalings = self.numScheduledScalings + numSteps
233
                if self.numScheduledScalings * numSteps < 0:
234
                    self.numScheduledScalings = numSteps
235
                self.factor = 1.0 + (self.numScheduledScalings / 300.0)
236
                print("Factor : " + str(self.factor))
237
                self.scale(self.factor, self.factor)
238

  
239
                #viewBBox = self.zoomStack[-1] if len(self.zoomStack) else self.sceneRect()
240
                #selectionBBox = self.scene.selectionArea().boundingRect().intersected(viewBBox)
241
                #self.scene.setSelectionArea(QPainterPath())  # Clear current selection area.
242
                #if selectionBBox.isValid() and (selectionBBox != viewBBox):
243
                #    self.zoomStack.append(selectionBBox)
244
                #    self.updateViewer()
245
        else:
246
            super().wheelEvent(event)
247

  
248

  
249

  
250
if __name__ == '__main__':
251
    import sys
252
    try:
253
        from PyQt5.QtWidgets import QApplication
254
    except ImportError:
255
        try:
256
            from PyQt4.QtGui import QApplication
257
        except ImportError:
258
            raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.")
259
    print('Using Qt ' + QT_VERSION_STR)
260

  
261
    def handleLeftClick(x, y):
262
        row = int(y)
263
        column = int(x)
264
        print("Clicked on image pixel (row="+str(row)+", column="+str(column)+")")
265

  
266
    # Create the application.
267
    app = QApplication(sys.argv)
268

  
269
    # Create image viewer and load an image file to display.
270
    viewer = QtImageViewer()
271
    viewer.loadImageFromFile()  # Pops up file dialog.
272

  
273
    # Handle left mouse clicks with custom slot.
274
    viewer.leftMouseButtonPressed.connect(handleLeftClick)
275

  
276
    # Show viewer and run application.
277
    viewer.show()
278
    sys.exit(app.exec_())
DTI_PID/DTI_PID/SymbolBase.py
4 4
class SymbolBase():
5 5
    def __init__(self, id, sName, sClass, sType, sItem, path = None, threshold = None, minMatchCount = 0
6 6
                 , isDetectOnOrigin = False, rotationCount = 4, ocrOption = OCR_OPTION_NOT_EXEC, isContainChild = 0
7
                 , decoDirection = -1, originalPoint = None, connectionPoint = None):
7
                 , childInfo = None, originalPoint = None, connectionPoint = None):
8 8
        self.id = id
9 9
        self.sName = sName
10 10
        self.sClass = sClass
......
17 17
        self.rotationCount = rotationCount
18 18
        self.ocrOption = ocrOption
19 19
        self.isContainChild = isContainChild
20
        self.decoDirection = decoDirection
20
        self.childInfo = childInfo
21 21
        self.originalPoint = originalPoint
22 22
        self.connectionPoint = connectionPoint
23 23

  
......
93 93
    def getIsContainChild(self):
94 94
        return self.isContainChild
95 95

  
96
    def setDecoDirection(self, decoDirection):
97
        self.decoDirection = decoDirection
96
    def setChildInfo(self, childInfo):
97
        self.childInfo = childInfo
98 98

  
99
    def getDecoDirection(self):
100
        return self.decoDirection
99
    def getChildInfo(self):
100
        return self.childInfo
101 101

  
102 102
    def setOriginalPoint(self, originalPoint):
103 103
        self.originalPoint = originalPoint
DTI_PID/DTI_PID/SymbolGenerator.py
1
# -*- coding: utf-8 -*-
2

  
3
# Form implementation generated from reading ui file 'D:\Anaconda3\output\SymbolGenerator.ui'
4
#
5
# Created by: PyQt5 UI code generator 5.6
6
#
7
# WARNING! All changes made in this file will be lost!
8

  
9
from PyQt5 import QtCore, QtGui, QtWidgets
10
from PyQt5.QtWidgets import *
11
from PyQt5.QtGui import *
12
from QcImageViewer import QcImageViewer
13
import cv2
14
from QtImageViewer import QtImageViewer
15

  
16
class Ui_MainWindow(object):
17
    def setupUi(self, MainWindow):
18
        defaultFilePath = "D:\\Visual Studio Project\\DTIPID\\DTIPID\\DTI_PID\\DTI_PID\\res\\UY1-K-2000_P1_300dpi.png"
19
        defaultImg = cv2.imread("D:\\Visual Studio Project\\DTIPID\\DTIPID\\DTI_PID\\DTI_PID\\res\\UY1-K-2000_P1_300dpi.png", 1)
20
        _chan, imgW, imgH = defaultImg.shape[::-1]
21

  
22
        MainWindow.setObjectName("MainWindow")
23
        MainWindow.showFullScreen()
24
        
25
        mainWindowWidth = MainWindow.frameGeometry().width()
26
        mainWindowHeight = MainWindow.frameGeometry().height()
27
        
28
        self.centralwidget = QtWidgets.QWidget(MainWindow)
29
        self.centralwidget.setObjectName("centralwidget")
30
        self.centralwidget.setGeometry(QtCore.QRect(0, 0, mainWindowWidth, mainWindowHeight - 50))
31
        
32
        centralWidth = self.centralwidget.frameGeometry().width()
33
        centralHeight = self.centralwidget.frameGeometry().height()
34

  
35
        self.topWidget = QtWidgets.QWidget(self.centralwidget)
36
        self.topWidget.setObjectName("topWidget")
37
        self.topWidget.setGeometry(QtCore.QRect(0, 0, mainWindowWidth, 40))
38
        self.topWidget.setLayout(QHBoxLayout())
39
        self.initToolMenu(self.topWidget)
40

  
41
        self.imageWidget = QtWidgets.QWidget(self.centralwidget)
42
        self.imageWidget.setObjectName("imageWidget")
43
        self.imageWidget.setGeometry(QtCore.QRect(0, self.topWidget.y()+self.topWidget.height(), mainWindowWidth, centralHeight - 40))
44

  
45
        #self.scrollArea = QtWidgets.QScrollArea(self.centralwidget)
46
        #self.scrollArea.setGeometry(QtCore.QRect(0, 0, centralWidth, centralHeight))
47
        #self.scrollArea.setWidgetResizable(False)
48
        #self.scrollArea.setObjectName("scrollArea")
49
        #self.scrollArea.horizontalScrollBar().setEnabled(True)
50
        #self.scrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
51
        #self.scrollArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
52
        #self.scrollAreaWidgetContents = QtWidgets.QWidget()
53
        #self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, imgW, imgH))
54
        #self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
55

  
56
        centralWidth = self.centralwidget.frameGeometry().width()
57
        centralHeight = self.centralwidget.frameGeometry().height()
58
        
59
        #self.mainView = QcImageViewer(defaultFilePath, imgW, imgH)
60
        #self.mainView.setParent(self.scrollAreaWidgetContents)
61
        #self.mainView.setFocusPolicy(QtCore.Qt.StrongFocus)
62
        #self.centralwidget.setFocusProxy(self.mainView)
63
        #self.mainView.setFocus(True)
64

  
65
        self.mainView = QtImageViewer()
66
        #self.mainView.resize(imgW, imgH)
67
        self.mainView.resize(centralWidth, centralHeight)
68
        self.mainView.aspectRatioMode = QtCore.Qt.KeepAspectRatio
69
        self.mainView.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
70
        self.mainView.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
71
        self.mainView.canZoom = True
72
        self.mainView.canPan = True
73

  
74
        image = QImage(defaultFilePath)
75
        image = image.scaled(imgW, imgH)
76
        self.mainView.setImage(image)
77
        self.mainView.setParent(self.imageWidget)
78

  
79
        #self.imageWidget.setParent(self.centralwidget)
80
        #self.topWidget.setParent(self.centralwidget)
81
        
82

  
83
        #self.scrollArea.setWidget(self.scrollAreaWidgetContents)
84
        MainWindow.setCentralWidget(self.centralwidget)
85

  
86

  
87
        self.menubar = QtWidgets.QMenuBar(MainWindow)
88
        self.menubar.setGeometry(QtCore.QRect(0, 0, mainWindowWidth, 21))
89
        self.menubar.setObjectName("menubar")
90
        self.menuFile = QtWidgets.QMenu(self.menubar)
91
        self.menuFile.setObjectName("menuFile")
92
        MainWindow.setMenuBar(self.menubar)
93
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
94
        self.statusbar.setObjectName("statusbar")
95
        MainWindow.setStatusBar(self.statusbar)
96
        self.actionOpen = QtWidgets.QAction(MainWindow)
97
        self.actionOpen.setObjectName("actionOpen")
98
        self.actionSave = QtWidgets.QAction(MainWindow)
99
        self.actionSave.setObjectName("actionSave")
100
        self.actionExit = QtWidgets.QAction(MainWindow)
101
        self.actionExit.setObjectName("actionExit")
102
        self.menuFile.addAction(self.actionOpen)
103
        self.menuFile.addAction(self.actionSave)
104
        self.menuFile.addAction(self.actionExit)
105
        self.menubar.addAction(self.menuFile.menuAction())
106

  
107
        self.retranslateUi(MainWindow)
108
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
109

  
110
        #self.centralwidget.setFocus(True)
111
        #self.centralwidget.setFocusPolicy(QtCore.Qt.StrongFocus)
112

  
113
        #self.centralwidget.keyPressEvent = self.centralKeyPressEvent
114

  
115
    def retranslateUi(self, MainWindow):
116
        _translate = QtCore.QCoreApplication.translate
117
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
118
        self.menuFile.setTitle(_translate("MainWindow", "File"))
119
        self.actionOpen.setText(_translate("MainWindow", "Open"))
120
        self.actionSave.setText(_translate("MainWindow", "Save"))
121
        self.actionExit.setText(_translate("MainWindow", "Exit"))
122

  
123
    #def centralKeyPressEvent(self, event):
124
    #    print("Central Widget Key Pressed")
125

  
126
    def initToolMenu(self, topWidget):
127
        layout = topWidget.layout()
128
        saveTool = QPushButton()
129
        saveTool.setText("Save Tool")
130
        saveTool.mousePressEvent = self.saveToolClickEvent
131
        layout.addWidget(saveTool)
132

  
133
        layout = topWidget.layout()
134
        handTool = QPushButton()
135
        handTool.setText("Hand Tool")
136
        handTool.mousePressEvent = self.handToolClickEvent
137
        layout.addWidget(handTool)
138

  
139
        cropTool = QPushButton()
140
        cropTool.setText("Crop Tool")
141
        cropTool.mousePressEvent = self.cropToolClickEvent
142
        layout.addWidget(cropTool)
143

  
144
        eraserTool = QPushButton()
145
        eraserTool.setText("Eraser Tool")
146
        eraserTool.mousePressEvent = self.eraserToolClickEvent
147
        layout.addWidget(eraserTool)
148

  
149
        penTool = QPushButton()
150
        penTool.setText("Pen Tool")
151
        penTool.mousePressEvent = self.penToolClickEvent
152
        layout.addWidget(penTool)
153

  
154
    def handToolClickEvent(self, event):
155
        print("hand tool clicked")
156
        self.mainView.currentMenuTool = QtImageViewer.MENU_HAND_TOOL
157

  
158
    def cropToolClickEvent(self, event):
159
        print("crop tool clicked")
160
        self.mainView.currentMenuTool = QtImageViewer.MENU_CROP_TOOL
161

  
162
    def eraserToolClickEvent(self, event):
163
        print("eraser tool clicked")
164
        self.mainView.currentMenuTool = QtImageViewer.MENU_ERASER_TOOL
165

  
166
    def penToolClickEvent(self, event):
167
        print("pen tool clicked")
168
        self.mainView.currentMenuTool = QtImageViewer.MENU_PEN_TOOL
169

  
170

  
171
if __name__ == "__main__":
172
    import sys
173
    app = QtWidgets.QApplication(sys.argv)
174
    MainWindow = QtWidgets.QMainWindow()
175
    ui = Ui_MainWindow()
176
    ui.setupUi(MainWindow)
177
    MainWindow.show()
178
    sys.exit(app.exec_())
179

  
DTI_PID/DTI_PID/XmlGenerator.py
26 26

  
27 27
SSUB_TEXT = "TEXT"
28 28
SSUB_ORIGINAL_POINT = "ORIGINALPOINT"
29
SSUB_DECO_DIRECTION = "DECODIRECTION"
29
SSUB_CHILD = "CHILD"
30 30
SSUB_ANGLE = "ANGLE"
31 31
SSUB_START_POINT = "STARTPOINT"
32 32
SSUB_SIZE = "SIZE"
......
80 80

  
81 81
    return xml
82 82

  
83
def getDirection(decoDirection):
83
def getConvertedChildInfo(childInfo):
84 84
    ret = ''
85
    if decoDirection == 0:
86
        ret = "UP"
87
    elif decoDirection == 1:
88
        ret = "RIGHT"
89
    elif decoDirection == 2:
90
        ret = "DOWN"
85
    childList = childInfo.split("/")
86
    for index in range(len(childList)):
87
        child = childList[index]
88
        direction = int(child.split(",")[0])
89
        childName = child.split(",")[1]
90
        if index != 0:
91
            ret = ret + "/"
92
        directionCode = getDirectionCode(direction)
93
        ret = ret + directionCode + "," + childName
94
    return ret
95

  
96
def getDirectionCode(direction):
97
    ret = ""
98
    if direction == 0:
99
        ret = "U"
100
    elif direction == 1:
101
        ret = "R"
102
    elif direction == 2:
103
        ret = "D"
91 104
    else :
92
        ret = "LEFT"
105
        ret = "L"
93 106
    return ret
94 107

  
95 108
def getSymbolInfoNode(symbol):
......
102 115
    sAngle = symbol.getRotatedAngle()
103 116
    sText = symbol.getText()
104 117
    sOriginalPoint = symbol.getOriginalPoint()
105
    sDecoDirection = symbol.getDecoDirection()
118
    sChildInfo = symbol.getChildInfo()
106 119
    sWidth = symbol.getWidth()
107 120
    sHeight = symbol.getHeight()
108 121

  
......
134 147
    sOpY = sSp[1] + int(sOriginalPoint.split(',')[1])
135 148
    sOriginalPointNode.text = str(sOpX) + "," + str(sOpY)
136 149

  
137
    if sDecoDirection >= 0:
138
        sDecoDirectionNode = Element(SSUB_DECO_DIRECTION)
139
        sDecoDirectionNode.text = getDirection(sDecoDirection)
140
        sCategoryNode.append(sDecoDirectionNode)
150
    if sChildInfo is not None:
151
        sChildInfoNode = Element(SSUB_CHILD)
152
        sChildInfoNode.text = getConvertedChildInfo(sChildInfo)
153
        sCategoryNode.append(sChildInfoNode)
141 154

  
142 155
    sAngleNode = Element(SSUB_ANGLE)
143 156
    sAngleNode.text = str(round(math.radians(sAngle), 2))
DTI_PID/DTI_PID/symbol.py
3 3
class Symbol(SymbolBase):
4 4
    def __init__(self, id, sName, sClass, sType, sItem, path, sp, width, height, threshold, minMatchCount, mpCount, rotatedAngle
5 5
                 , isDetectOnOrigin, rotationCount, ocrOption, isContainChild = 0
6
                 , decoDirection = -1, originalPoint = None, connectionPoint = None):
6
                 , childInfo = None, originalPoint = None, connectionPoint = None):
7 7
        SymbolBase.__init__(self, id, sName, sClass, sType, sItem, path, threshold, minMatchCount
8 8
                            , isDetectOnOrigin, rotationCount, ocrOption, isContainChild
9
                            , decoDirection, originalPoint, connectionPoint)
9
                            , childInfo, originalPoint, connectionPoint)
10 10
        self.sp = sp
11 11
        self.width = width
12 12
        self.height = height

내보내기 Unified diff

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