프로젝트

일반

사용자정보

개정판 43fa2b90

ID43fa2b90b08947af3e02b67d7713b49c59b569a9
상위 19bf2737
하위 b480798e

humkyung 이(가) 6년 이상 전에 추가함

fixed issue #480: Line 인식

차이점 보기:

DTI_PID/DTI_PID/AppDocData.py
151 151
        self._colors = value
152 152

  
153 153
    def setCurrentPidSource(self, image):
154
        self.imgWidth, self.imgHeight = image.size
155

  
154 156
        self.currentPidSource = Source(image)
155 157

  
156 158
    def getCurrentPidSource(self):
DTI_PID/DTI_PID/LineDetector.py
461 461
            xHalf = round(windowSize[0]*0.5)
462 462
            yHalf = round(windowSize[1]*0.5)
463 463

  
464
            print('type({}) is {}'.format(pt, type(pt)))
465

  
466 464
            if ([1,0] == dir):
467 465
                image = self._image[(pt[1]-yHalf):(pt[1]+yHalf), pt[0]:self.width]
468 466
                imgWidth, imgHeight = image.shape[::-1]
DTI_PID/DTI_PID/MainWindow.py
305 305
            if os.path.isfile(self.path):
306 306
                self.graphicsView.useDefaultCommand()
307 307

  
308
                baseName = os.path.basename(self.path)
309 308
                docData = AppDocData.instance()
309
                docData.imgName = os.path.splitext(os.path.basename(self.path))[0]
310 310
                docData.setCurrentPidSource(Image.open(self.path))
311
                self.resultTreeWidget.setCurrentPID(baseName)
311
                self.resultTreeWidget.setCurrentPID(docData.imgName)
312 312

  
313 313
                ''' TEST CODE '''
314 314
                area = docData.getArea('Drawing')
315 315
                area.img = cv2.imread(self.path, 1)
316 316

  
317 317
                ## Load data on xml
318
                path = os.path.join(AppDocData.instance().getCurrentProject().getTempPath(), os.path.splitext(baseName)[0] + '.xml')
318
                path = os.path.join(AppDocData.instance().getCurrentProject().getTempPath(), docData.imgName + '.xml')
319 319
                if os.path.isfile(path): self.loadRecognitionResultFromXml(path)
320

  
321
                # DEBUG
322
                '''
323
                if __debug__:
324
                    from LineDetector import LineDetector
325
                    from LineNoTracer import LineNoTracer
326
                    self.loadRecognitionResultFromXml('d:/Projects/DTIPID/DTI_PID/DTI_PID/SG_TEST/output/UY1-K-2005G_P1_300dpi_black.xml')
327

  
328
                    # detect line
329
                    connectedLines = []
330

  
331
                    img = cv2.cvtColor(cv2.imread(self.path), cv2.COLOR_BGR2GRAY)
332
                    detector = LineDetector(img)
333
                    symbols = []
334
                    for item in self.graphicsView.scene.items():
335
                        if type(item) is SymbolSvgItem:
336
                            symbols.append(item)
337
                            color = QColor(random.randrange(0,255), random.randrange(0,255), random.randrange(0,255))
338
                            res = detector.detectConnectedLine(item, 0, 0)
339
                            if res is not None:
340
                                for line in res: connectedLines.append(line)
341

  
342
                    texts = []
343
                    for item in self.graphicsView.scene.items():
344
                        if (type(item) is QEngineeringTextItem): texts.append(item)
345

  
346
                    if len(connectedLines) > 1:
347
                        detector.mergeLines(connectedLines, toler=20)
348
                        # connect line to symbol
349
                        try:
350
                            for line in connectedLines:
351
                                matches = [symbol for symbol in symbols if symbol.isConnectable(line, (0,0), toler=40)]
352
                                for symbol in matches:
353
                                    detector.connectLineToSymbol(line, (0,0), symbol)
354
                        except Exception as ex:
355
                            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
356
                        # up to here
357

  
358
                        # connect line to line
359
                        try:
360
                            for line in connectedLines[:]:
361
                                matches = [it for it in connectedLines if (line != it) and (not detector.isParallel(line, it))]
362
                                for match in matches:
363
                                    detector.connectLineToLine(match, line)
364
                        except Exception as ex:
365
                            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
366
                        # up to here
367

  
368
                    lines = []
369
                    for pts in connectedLines:
370
                        processLine = QEngineeringLineItem()
371
                        lines.append(processLine)
372
                        for pt in pts:
373
                            processLine._pol.append(QPointF(pt[0], pt[1]))
374
                        processLine._path.addPolygon(processLine._pol)
375
                        processLine.setPath(processLine._path)
376
                        processLine.setPen(QPen(color, 5, Qt.SolidLine))
377
                        self.graphicsView.scene.addItem(processLine)
378
                    detector.saveImage()
379

  
380
                    # trace line no
381
                    tracer = LineNoTracer(symbols, lines, texts)
382
                    tracer.execute()
383
                    # up to here
384

  
385
                    # construct line no item
386
                    docData = AppDocData.instance()
387
                    for text in docData.lineNos:
388
                        item = self.resultTreeWidget.addTreeItem(self.resultTreeWidget.root, text)
389

  
390
                        if 1 == len(text.conns):
391
                            # iterate connected items
392
                            pool = []
393
                            visited = []
394
                            pool.append(text.conns[0])
395
                            while len(pool) > 0:
396
                                it = pool.pop()
397
                                if type(it) is SymbolSvgItem: self.resultTreeWidget.addTreeItem(item, it)
398
                                visited.append(it)
399
                                for conn in it.conns:
400
                                    if (conn is not None) and (conn not in visited): pool.append(conn)
401
                            # up to here
402
                                
403
                    # up to here
404
                # up to here
405
                '''
406 320
        except Exception as ex:
407 321
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
408 322

  
DTI_PID/DTI_PID/Shapes/QEngineeringLineItem.py
260 260
        @history    Jeongwoo 18.05.15 Add check pt's type
261 261
                    Jeongwoo 18.05.16 Add length == 0 check
262 262
    '''
263
    def isConnectable(self, line):
263
    def isConnectable(self, line, toler=20):
264 264
        import math
265 265

  
266 266
        startPt = line.startPoint()
......
273 273
            return False
274 274
        dx /= length
275 275
        dy /= length
276
        extendedLine = [(startPt[0] - dx*20, startPt[1] - dy*20), (endPt[0] + dx*20, endPt[1] + dy*20)]
276
        extendedLine = [(startPt[0] - dx*toler, startPt[1] - dy*toler), (endPt[0] + dx*toler, endPt[1] + dy*toler)]
277 277
        pt = self.intersection(extendedLine)
278 278

  
279 279
        return (pt is not None) and (type(pt) == shapely.geometry.point.Point)
280 280

  
281 281
    '''
282
        @brief  check if two lines are jointable
283
        @author humkyung
284
        @date   2018.06.26
285
    '''
286
    def isJointable(self, line, toler=5):
287
        import math
288

  
289
        lhs = [self.startPoint(), self.endPoint()]
290
        rhs = [line.startPoint(), line.endPoint()]
291

  
292
        for pt in lhs:
293
            for _pt in rhs:
294
                dx = _pt[0] - pt[0]
295
                dy = _pt[1] - pt[1]
296
                if math.sqrt(dx*dx + dy*dy) < toler:
297
                    return True
298
        
299
        return False
300

  
301
    '''
282 302
        @brief  check if two lines are extendable
283 303
        @author humkyung
284 304
        @date   2018.06.25
DTI_PID/DTI_PID/Shapes/QEngineeringRunItem.py
111 111
            while len(connectedLines) > 0:
112 112
                line = connectedLines.pop()
113 113
                flag = (line.conns[0] is not None and issubclass(type(line.conns[0]),SymbolSvgItem)) or (line.conns[1] is not None and issubclass(type(line.conns[1]),SymbolSvgItem))
114
                if flag:
115
                    if line.isHorizontal():
116
                        groupItems = [item for item in connectedLines if line.isExtendable(item)]
117
                    elif line.isVertical():
118
                        groupItems = [item for item in connectedLines if line.isExtendable(item)]
119
                else:
120
                    groupItems = []
114
                groupItems = [item for item in connectedLines if line.isExtendable(item)] if flag else []
121 115

  
122 116
                pts = []
123 117
                pts.append(line.startPoint())
......
125 119
                for item in groupItems:
126 120
                    pts.append(item.startPoint())
127 121
                    pts.append(item.endPoint())
122

  
128 123
                longestPoints = self.getLongestTwoPoints(pts)
129 124
                if 2 == len(longestPoints):
130 125
                    tmp = QEngineeringLineItem()
131 126
                    if line.isHorizontal():
132
                        adjustY = (longestPoints[0][1] + longestPoints[1][1]) * 0.5
133
                        tmp._pol.append(QPointF(longestPoints[0][0], adjustY))
134
                        tmp._pol.append(QPointF(longestPoints[1][0], adjustY))
127
                        y = (longestPoints[0][1] + longestPoints[1][1]) * 0.5
128
                        tmp._pol.append(QPointF(longestPoints[0][0], y))
129
                        tmp._pol.append(QPointF(longestPoints[1][0], y))
135 130
                    elif line.isVertical():
136
                        adjustX = (longestPoints[0][0] + longestPoints[1][0]) * 0.5 
137
                        tmp._pol.append(QPointF(adjustX, longestPoints[0][1]))
138
                        tmp._pol.append(QPointF(adjustX, longestPoints[1][1]))
131
                        x = (longestPoints[0][0] + longestPoints[1][0]) * 0.5 
132
                        tmp._pol.append(QPointF(x, longestPoints[0][1]))
133
                        tmp._pol.append(QPointF(x, longestPoints[1][1]))
139 134
                    mergedLines.append(tmp)
140 135

  
141 136
                for item in groupItems: connectedLines.remove(item)
......
143 138
            mergedLines.extend(connectedLines)
144 139

  
145 140
            head = None
146
            for item in mergedLines:
141
            for line in mergedLines:
147 142
                count = 0
148 143
                for other in mergedLines:
149
                    if item is other: continue
150
                    if item.isConnectable(other): count += 1
144
                    if line is other: continue
145
                    if line.isJointable(other):
146
                        count += 1
147

  
151 148
                if 1 == count:
152
                    head = item
149
                    head = line
153 150
                    break
154

  
151
            
152
            docData = AppDocData.instance()
155 153
            if head:
156
                docData = AppDocData.instance()
157

  
158 154
                visited = [head]
159 155
                pool = [head]
160 156
                while len(pool) > 0:
161
                    item = pool.pop()
162
                    connected = [param for param in mergedLines if param not in visited and param.isConnectable(item)]
157
                    line = pool.pop()
158
                    connected = [param for param in mergedLines if param not in visited and param.isJointable(line)]
163 159
                    pool.extend(connected)
164 160
                    visited.extend(connected)
165
                    node.append(item.toXml())
166
                    cv2.line(docData.imgOutput, (round(item.startPoint()[0]), round(item.startPoint()[1])), (round(item.endPoint()[0]), round(item.endPoint()[1])), 0, 1)
161
                    if line.length() > 20:
162
                        node.append(line.toXml())
163
                        cv2.line(docData.imgOutput, (round(line.startPoint()[0]), round(line.startPoint()[1])), (round(line.endPoint()[0]), round(line.endPoint()[1])), 0, 1)
164

  
165
                    for param in connected:
166
                        mergedLines.remove(param)
167
                    
168
                for line in mergedLines:
169
                    if line.length() > 20:
170
                        node.append(line.toXml())
171
                        cv2.line(docData.imgOutput, (round(line.startPoint()[0]), round(line.startPoint()[1])), (round(line.endPoint()[0]), round(line.endPoint()[1])), 0, 1)
172
            else:
173
                pass
167 174
            # up to here
168 175

  
169 176
            connectedSymbols = [item for item in self.items if issubclass(type(item), SymbolSvgItem)]
DTI_PID/DTI_PID/XmlGenerator.py
91 91
    @date   2018.04.23
92 92
'''
93 93
def writeOutputXml(pidName, pidWidth, pidHeight):
94
    path = os.path.join(AppDocData.instance().getCurrentProject().getOutputPath(), pidName + '.xml')
95 94
    try:
95
        path = os.path.join(AppDocData.instance().getCurrentProject().getOutputPath(), pidName + '.xml')
96

  
96 97
        xmlData = generateOutputXml(pidName, pidWidth, pidHeight)
97 98
        ElementTree(xmlData).write(path)
98 99
    except Exception as ex:

내보내기 Unified diff

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