개정판 66ddb055
add instrumentlabel
DTI_PID/DTI_PID/DTI_PID.py | ||
---|---|---|
40 | 40 |
#endregion |
41 | 41 | |
42 | 42 |
## Tesseract path |
43 |
pytesseract.pytesseract.tesseract_cmd = os.path.join(os.environ['TESSERACT_HOME'], 'tesseract.exe')
|
|
44 |
tesseract_cmd = os.path.join(os.environ['TESSERACT_HOME'], 'tesseract.exe')
|
|
43 |
pytesseract.pytesseract.tesseract_cmd = os.environ['TESSERACT_HOME'] + '\\tesseract.exe'
|
|
44 |
tesseract_cmd = os.environ['TESSERACT_HOME'] + '\\tesseract.exe'
|
|
45 | 45 | |
46 | 46 |
#region Symbol Image path List for test |
47 | 47 |
targetSymbolList = [] |
... | ... | |
197 | 197 | |
198 | 198 |
return float((w * h)) / float((tw * th)) * 100 |
199 | 199 | |
200 |
def getSplitSrcList(srcPid, splitCount, splitWidth, splitHeight): |
|
201 |
splitRoiList = [] |
|
202 |
for hi in range(splitCount): |
|
203 |
for wi in range(splitCount): |
|
204 |
roiSp = (splitWidth*wi, splitHeight*hi) |
|
205 |
roiEp = (splitWidth*(wi+1), splitHeight*(hi+1)) |
|
206 |
splitRoiList.append((roiSp, roiEp, srcPid[roiSp[1]:roiEp[1], roiSp[0]:roiEp[0]])) |
|
207 |
return splitRoiList |
|
208 | ||
200 | 209 |
''' |
201 | 210 |
@history 2018.06.12 Jeongwoo Type changed (int → float) |
202 |
humkyung 2018.07.07 change return type as like [x,y] |
|
203 | 211 |
''' |
204 | 212 |
def getCalculatedOriginalPoint(additionalSymbol, symbolOriginalPoint, symbolRotatedAngle, rotateSymbolWidth, rotateSymbolHeight, originalSymbolWidth, originalSymbolHeight): |
205 |
res = [] |
|
206 | ||
213 |
originalPoint = '' |
|
207 | 214 |
if additionalSymbol is None and symbolOriginalPoint is None: |
208 |
res.append(rotateSymbolWidth//2) |
|
209 |
res.append(rotateSymbolHeight//2) |
|
215 |
originalPoint = str(rotateSymbolWidth//2)+','+str(rotateSymbolHeight//2) |
|
210 | 216 |
else: |
211 | 217 |
opx = float(symbolOriginalPoint.split(',')[0]) |
212 | 218 |
opy = float(symbolOriginalPoint.split(',')[1]) |
213 | 219 |
rPt = getCoordOnRotatedImage(symbolRotatedAngle, opx, opy, originalSymbolWidth, originalSymbolHeight) |
214 |
res.append(float(rPt[0])) |
|
215 |
res.append(float(rPt[1])) |
|
216 | ||
217 |
return res |
|
220 |
originalPoint = str(float(rPt[0])) + ',' + str(float(rPt[1])) |
|
221 |
return originalPoint |
|
218 | 222 | |
219 | 223 |
''' |
220 | 224 |
@history 2018.06.12 Jeongwoo Type changed (int → float) |
221 |
humkyung 2018.07.07 change return type as like [[x,y],...] |
|
222 | 225 |
''' |
223 | 226 |
def getCalculatedConnectionPoint(symbolConnectionPointStr, symbolRotatedAngle, rotateSymbolWidth, rotateSymbolHeight, originalSymbolWidth, originalSymbolHeight): |
224 |
res = []
|
|
227 |
convertedConnectionPoint = ""
|
|
225 | 228 |
if symbolConnectionPointStr is not None: |
226 | 229 |
splitConnectionPointStr = symbolConnectionPointStr.split("/") |
227 | 230 |
for index in range(len(splitConnectionPointStr)): |
231 |
if index != 0: |
|
232 |
convertedConnectionPoint = convertedConnectionPoint + "/" |
|
228 | 233 |
item = splitConnectionPointStr[index] |
229 | 234 |
cpx = float(item.split(',')[0]) |
230 | 235 |
cpy = float(item.split(',')[1]) |
231 | 236 |
rPt = getCoordOnRotatedImage(symbolRotatedAngle, cpx, cpy, originalSymbolWidth, originalSymbolHeight) |
232 |
res.append([float(rPt[0]), float(rPt[1])])
|
|
233 | ||
234 |
return res
|
|
237 |
temp = str(float(rPt[0])) + ',' + str(float(rPt[1]))
|
|
238 |
convertedConnectionPoint = convertedConnectionPoint + temp |
|
239 |
return convertedConnectionPoint
|
|
235 | 240 |
|
236 | 241 |
''' |
237 |
@brief Add symbols
|
|
238 |
@author jwkim
|
|
242 |
@brief Add symbols |
|
243 |
@author jwkim |
|
239 | 244 |
@date |
240 | 245 |
@history Change parameter (mpCount → hitRate) |
241 |
Yecheol 2018.07.04 Delete Symbol Id |
|
246 |
''' |
|
247 | ||
248 |
''' |
|
249 |
@Auther Yecheol |
|
250 |
@Date 2018.07.04 |
|
251 |
@History Delete Symbol Id |
|
242 | 252 |
''' |
243 | 253 |
def addSearchedSymbol(sName, sType |
244 | 254 |
, sp, w, h, threshold, minMatchCount, hitRate, rotatedAngle |
245 | 255 |
, isDetectOnOrigin, rotateCount, ocrOption, isContainChild |
246 |
, originalPoint, connectionPoint, baseSymbol, additionalSymbol, isExceptDetect): |
|
256 |
, originalPoint, connectionPoint, baseSymbol, additionalSymbol, isExceptDetect, hasInstrumentLabel):
|
|
247 | 257 |
global searchedSymbolList |
248 | 258 |
newSym = symbol.Symbol(sName, sType |
249 | 259 |
, sp, w, h, threshold, minMatchCount, hitRate, rotatedAngle |
250 | 260 |
, isDetectOnOrigin, rotateCount, ocrOption, isContainChild |
251 |
, ','.join(str(x) for x in originalPoint), '/'.join('{},{}'.format(x[0],x[1]) for x in connectionPoint), baseSymbol, additionalSymbol, isExceptDetect)
|
|
261 |
, originalPoint, connectionPoint, baseSymbol, additionalSymbol, isExceptDetect, hasInstrumentLabel)
|
|
252 | 262 | |
253 | 263 |
searchedSymbolList.append(newSym) |
254 | 264 | |
255 |
return newSym |
|
256 | 265 | |
257 | 266 |
#Calculate count of keypoint match result |
258 | 267 |
def getMatchPointCount(src, cmp): |
... | ... | |
309 | 318 |
Change parameter on add symbol part (mpCount → hitRate) |
310 | 319 |
Remove unusing calculation (avg) |
311 | 320 |
Jeongwoo 2018.06.27 Remove part to split P&ID image and for loop |
312 |
humkyung 2018.07.07 return searched symbols |
|
313 | 321 |
''' |
314 | 322 |
def detectSymbolOnPid(mainRes, targetSymbol, listWidget, updateProgressSignal): |
315 | 323 |
global src |
... | ... | |
321 | 329 |
global maxProgressValue |
322 | 330 |
|
323 | 331 |
try: |
332 |
#symId = targetSymbol.getId() |
|
324 | 333 |
symbolName = targetSymbol.getName() |
325 | 334 |
symbolType = targetSymbol.getType() |
326 | 335 |
symbolPath = targetSymbol.getPath() |
... | ... | |
335 | 344 |
baseSymbol = targetSymbol.getBaseSymbol() |
336 | 345 |
additionalSymbol = targetSymbol.getAdditionalSymbol() |
337 | 346 |
isExceptDetect = targetSymbol.getIsExceptDetect() |
347 |
hasInstrumentLabel = targetSymbol.getHasInstrumentLabel() |
|
338 | 348 | |
339 | 349 |
# check if symbol file is target or not |
340 | 350 |
if isExceptDetect == 1: |
... | ... | |
362 | 372 |
sow, soh = symGray.shape[::-1] # symbol original w, h |
363 | 373 | |
364 | 374 |
offsetDrawingArea=[] |
365 |
appDocData = AppDocData.instance()
|
|
366 |
area = appDocData.getArea('Drawing')
|
|
375 |
docData = AppDocData.instance()
|
|
376 |
area = docData.getArea('Drawing')
|
|
367 | 377 |
if area is not None: |
368 | 378 |
copiedBasePid = area.img.copy() |
369 | 379 |
offsetDrawingArea.append(area.x) |
... | ... | |
419 | 429 |
searchedItemSp = (roiItemSp[0]+pt[0] + round(offsetDrawingArea[0]), roiItemSp[1]+pt[1] + round(offsetDrawingArea[1])) |
420 | 430 | |
421 | 431 |
for i in range(len(searchedSymbolList)): |
422 |
_pt = searchedSymbolList[i].getSp() |
|
423 |
rect = QRectF(_pt[0], _pt[1], searchedSymbolList[i].getWidth(), searchedSymbolList[i].getHeight()) |
|
424 |
_rect = QRectF(searchedItemSp[0], searchedItemSp[1], sw, sh) |
|
425 |
if rect.intersects(_rect): |
|
426 |
intersect = rect.intersected(_rect) |
|
427 |
overlapArea = intersect.width()*intersect.height() |
|
428 |
if overlapArea > ACCEPT_OVERLAY_AREA: |
|
429 |
symbolIndex = i |
|
430 |
break |
|
431 | ||
432 |
''' |
|
433 | 432 |
overlapArea = contains(searchedSymbolList[i], searchedItemSp, sw, sh) |
434 | 433 |
if overlapArea > ACCEPT_OVERLAY_AREA: |
435 | 434 |
symbolIndex = i |
436 | 435 |
break |
437 |
''' |
|
438 | 436 |
|
439 | 437 |
hitRate = tmRes[pt[1], pt[0]] |
440 | 438 |
## DEBUG |
... | ... | |
446 | 444 |
threadLock.acquire() |
447 | 445 |
foundSymbolCount = foundSymbolCount + 1 |
448 | 446 |
addSearchedSymbol(symbolName, symbolType |
449 |
, searchedItemSp, sw, sh, symbolThreshold, symbolMinMatchCount, hitRate, symbolRotatedAngle |
|
450 |
, isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild |
|
451 |
, originalPoint, connectionPoint, baseSymbol, additionalSymbol,isExceptDetect)
|
|
447 |
, searchedItemSp, sw, sh, symbolThreshold, symbolMinMatchCount, hitRate, symbolRotatedAngle
|
|
448 |
, isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild
|
|
449 |
, originalPoint, connectionPoint, baseSymbol, additionalSymbol,isExceptDetect, hasInstrumentLabel)
|
|
452 | 450 |
threadLock.release() |
453 | 451 |
## 겹치는 영역이 기준값보다 클 경우 |
454 | 452 |
else: |
... | ... | |
462 | 460 |
searchedSymbolList[symbolIndex] = symbol.Symbol(symbolName, symbolType |
463 | 461 |
, searchedItemSp, sw, sh, symbolThreshold, symbolMinMatchCount, hitRate, symbolRotatedAngle |
464 | 462 |
, isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild |
465 |
, ','.join(str(x) for x in originalPoint), '/'.join('{},{}'.format(x[0],x[1]) for x in connectionPoint), baseSymbol, additionalSymbol,isExceptDetect)
|
|
463 |
, originalPoint, connectionPoint, baseSymbol, additionalSymbol,isExceptDetect, hasInstrumentLabel)
|
|
466 | 464 |
## DEBUG |
467 | 465 |
#print('//// {}:{}-{} ////'.format(symbolName, searchedItemSp, hitRate)) |
468 | 466 |
## up to here |
469 | 467 | |
470 | 468 |
threadLock.release() |
471 | 469 |
## 현재 심볼과 검출된 심볼이 같지 않을 경우 (포함) |
472 |
elif appDocData.isEquipmentType(searchedSymbol.getType()):
|
|
470 |
elif docData.isEquipmentType(searchedSymbol.getType()):
|
|
473 | 471 |
## DEBUG |
474 | 472 |
print('{}->{}:{}-{}'.format(searchedSymbol.getName(), symbolName, searchedItemSp, hitRate)) |
475 | 473 |
## up to here |
... | ... | |
477 | 475 |
threadLock.acquire() |
478 | 476 |
foundSymbolCount = foundSymbolCount + 1 |
479 | 477 |
addSearchedSymbol(symbolName, symbolType |
480 |
, searchedItemSp, sw, sh, symbolThreshold, hitRate, hitRate, symbolRotatedAngle |
|
481 |
, isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild |
|
482 |
, originalPoint, connectionPoint, baseSymbol, additionalSymbol,isExceptDetect)
|
|
478 |
, searchedItemSp, sw, sh, symbolThreshold, hitRate, hitRate, symbolRotatedAngle
|
|
479 |
, isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild
|
|
480 |
, originalPoint, connectionPoint, baseSymbol, additionalSymbol,isExceptDetect, hasInstrumentLabel)
|
|
483 | 481 |
threadLock.release() |
484 | 482 |
|
485 | 483 |
## Rotate Symbol |
... | ... | |
494 | 492 |
threadLock.release() |
495 | 493 | |
496 | 494 |
updateProgressSignal.emit(maxProgressValue) |
497 | ||
498 |
return [symbol for symbol in searchedSymbolList if symbol.getName() == symbolName] |
|
499 |
except Exception as ex: |
|
500 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
501 |
|
|
502 |
return [] |
|
503 | ||
504 |
''' |
|
505 |
@brief detect nozzle |
|
506 |
@author humkyung |
|
507 |
@date 2018.07.07 |
|
508 |
''' |
|
509 |
def detectNozzleOnPid(img, offset, eqpSize, nozzle, listWidget, updateProgressSignal): |
|
510 |
global src |
|
511 |
global srcGray |
|
512 |
global threadLock |
|
513 |
global searchedSymbolList |
|
514 |
global maxProgressValue |
|
515 |
|
|
516 |
try: |
|
517 |
symbolName = nozzle.getName() |
|
518 |
symbolType = nozzle.getType() |
|
519 |
symbolPath = nozzle.getPath() |
|
520 |
symbolThreshold = nozzle.getThreshold() |
|
521 |
symbolMinMatchCount = nozzle.getMinMatchCount() |
|
522 |
isDetectOnOrigin = nozzle.getIsDetectOnOrigin() |
|
523 |
symbolRotateCount = nozzle.getRotationCount() |
|
524 |
symbolOcrOption = nozzle.getOcrOption() |
|
525 |
isContainChild = nozzle.getIsContainChild() |
|
526 |
symbolOriginalPoint = nozzle.getOriginalPoint() |
|
527 |
symbolConnectionPoint = nozzle.getConnectionPoint() |
|
528 |
baseSymbol = nozzle.getBaseSymbol() |
|
529 |
additionalSymbol = nozzle.getAdditionalSymbol() |
|
530 |
isExceptDetect = nozzle.getIsExceptDetect() |
|
531 | ||
532 |
foundSymbolCount = 0 |
|
533 | ||
534 |
# check if symbol file exists |
|
535 |
if not os.path.isfile(symbolPath): |
|
536 |
item = QListWidgetItem('{} file not found'.format(os.path.split(os.path.basename(symbolPath))[0])) |
|
537 |
item.setBackground(QColor('red')) |
|
538 |
listWidget.addItem(item) |
|
539 |
return |
|
540 |
# up to here |
|
541 | ||
542 |
sym = cv2.imread(symbolPath, 1) |
|
543 |
symGray = cvtGrayImage(sym) |
|
544 |
sow, soh = symGray.shape[::-1] # symbol original w, h |
|
545 | ||
546 |
appDocData = AppDocData.instance() |
|
547 |
srcWidth, srcHeight = img.shape[::-1] |
|
548 | ||
549 |
roiItemSp = (0,0) |
|
550 |
roiItemEp = (srcWidth, srcHeight) |
|
551 |
roiItem = img |
|
552 | ||
553 |
symbolAngle = 0 |
|
554 |
for rc in range(symbolRotateCount + 1): ## Rotation Count를 사용자 기준으로 받아서 1을 더한 후 사용 |
|
555 |
sw, sh = symGray.shape[::-1] |
|
556 |
roiw = (roiItemEp[0] - roiItemSp[0]) |
|
557 |
roih = (roiItemEp[1] - roiItemSp[1]) |
|
558 | ||
559 |
## get Rotated Original Point |
|
560 |
originalPoint = getCalculatedOriginalPoint(additionalSymbol, symbolOriginalPoint, symbolAngle, sw, sh, sow, soh) |
|
561 |
connectionPoint = getCalculatedConnectionPoint(symbolConnectionPoint, symbolAngle, sw, sh, sow, soh) |
|
562 |
dx = connectionPoint[0][0] - originalPoint[0] |
|
563 |
dy = connectionPoint[0][1] - originalPoint[1] |
|
564 | ||
565 |
## Template Matching |
|
566 |
tmRes = cv2.matchTemplate(roiItem, symGray, cv2.TM_CCOEFF_NORMED) |
|
567 |
loc = np.where(tmRes >= symbolThreshold) |
|
568 | ||
569 |
for pt in zip(*loc[::-1]): |
|
570 |
mpCount = 0 # Match Point Count |
|
571 |
symbolIndex = -1 |
|
572 | ||
573 |
roi = roiItem[pt[1]:pt[1]+sh, pt[0]:pt[0]+sw] |
|
574 | ||
575 |
if symbolMinMatchCount > 0: |
|
576 |
mpCount = getMatchPointCount(roi, symGray) |
|
577 |
if not (mpCount >= symbolMinMatchCount): |
|
578 |
continue |
|
579 |
|
|
580 |
mid = (offset[0] + pt[0] + (originalPoint[0] + connectionPoint[0][0])*0.5, offset[1] + pt[1] + (originalPoint[1] + connectionPoint[0][1])*0.5) |
|
581 |
searchedItemSp = (roiItemSp[0]+pt[0]+offset[0], roiItemSp[1]+pt[1]+offset[1]) |
|
582 |
print('---{}---{}---{}---'.format(eqpSize,searchedItemSp,mid)) |
|
583 |
# check searched nozzle location |
|
584 |
if abs(dx) > abs(dy): |
|
585 |
if dx > 0: |
|
586 |
if mid[0] < eqpSize[0] + eqpSize[2]*0.5: continue |
|
587 |
else: |
|
588 |
if mid[0] > eqpSize[0] + eqpSize[2]*0.5: continue |
|
589 |
else: |
|
590 |
if dy > 0: |
|
591 |
if mid[1] < eqpSize[1] + eqpSize[3]*0.5: continue |
|
592 |
else: |
|
593 |
if mid[1] > eqpSize[1] + eqpSize[3]*0.5: continue |
|
594 |
# up to here |
|
595 | ||
596 |
overlapArea = 0 |
|
597 |
nozzles = [symbol for symbol in searchedSymbolList if symbol.getType() == 'Nozzles'] |
|
598 |
for i in range(len(nozzles)): |
|
599 |
_pt = nozzles[i].getSp() |
|
600 |
rect = QRectF(_pt[0], _pt[1], nozzles[i].getWidth(), nozzles[i].getHeight()) |
|
601 |
_rect = QRectF(searchedItemSp[0], searchedItemSp[1], sw, sh) |
|
602 |
if rect.intersects(_rect): |
|
603 |
intersect = rect.intersected(_rect) |
|
604 |
overlapArea = intersect.width()*intersect.height() |
|
605 |
if overlapArea > ACCEPT_OVERLAY_AREA: |
|
606 |
symbolIndex = i |
|
607 |
break |
|
608 |
|
|
609 |
hitRate = tmRes[pt[1], pt[0]] |
|
610 | ||
611 |
## 겹치는 영역이 기준값보다 작을 경우 |
|
612 |
if overlapArea <= ACCEPT_OVERLAY_AREA: |
|
613 |
threadLock.acquire() |
|
614 |
foundSymbolCount = foundSymbolCount + 1 |
|
615 |
addSearchedSymbol(symbolName, symbolType |
|
616 |
, searchedItemSp, sw, sh, symbolThreshold, symbolMinMatchCount, hitRate, symbolAngle |
|
617 |
, isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild |
|
618 |
, originalPoint, connectionPoint, baseSymbol, additionalSymbol,isExceptDetect) |
|
619 |
threadLock.release() |
|
620 |
## 겹치는 영역이 기준값보다 클 경우 |
|
621 |
else: |
|
622 |
if symbolIndex != -1 and symbolIndex < len(nozzles): |
|
623 |
searchedSymbol = nozzles[symbolIndex] |
|
624 |
## 현재 심볼과 검출된 심볼이 같을 경우 Match Point가 더 높은 정보로 교체 |
|
625 |
if symbolName == searchedSymbol.getName(): |
|
626 |
symbolHitRate = searchedSymbol.getHitRate() |
|
627 |
if symbolHitRate < hitRate: |
|
628 |
threadLock.acquire() |
|
629 |
nozzles[symbolIndex] = symbol.Symbol(symbolName, symbolType |
|
630 |
, searchedItemSp, sw, sh, symbolThreshold, symbolMinMatchCount, hitRate, symbolAngle |
|
631 |
, isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild |
|
632 |
, ','.join(str(x) for x in originalPoint), '/'.join('{},{}'.format(x[0],x[1]) for x in connectionPoint), baseSymbol, additionalSymbol,isExceptDetect) |
|
633 |
threadLock.release() |
|
634 |
## 현재 심볼과 검출된 심볼이 같지 않을 경우 (포함) |
|
635 |
elif appDocData.isEquipmentType(searchedSymbol.getType()): |
|
636 |
threadLock.acquire() |
|
637 |
foundSymbolCount = foundSymbolCount + 1 |
|
638 |
addSearchedSymbol(symbolName, symbolType |
|
639 |
, searchedItemSp, sw, sh, symbolThreshold, hitRate, hitRate, symbolAngle |
|
640 |
, isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild |
|
641 |
, originalPoint, connectionPoint, baseSymbol, additionalSymbol,isExceptDetect) |
|
642 |
threadLock.release() |
|
643 |
|
|
644 |
## Rotate Symbol |
|
645 |
symGray = cv2.rotate(symGray, cv2.ROTATE_90_COUNTERCLOCKWISE) |
|
646 |
symbolAngle = symbolAngle + 90 |
|
647 | ||
648 |
if additionalSymbol is not None: |
|
649 |
additionalSymbol = getRotatedChildInfo(additionalSymbol) |
|
650 | ||
651 |
threadLock.acquire() |
|
652 |
listWidget.addItem('Found Symbol : ' + os.path.splitext(os.path.basename(symbolPath))[0] + ' - (' + str(foundSymbolCount) + ')') |
|
653 |
threadLock.release() |
|
654 | ||
655 |
updateProgressSignal.emit(maxProgressValue) |
|
656 | ||
657 |
return [symbol for symbol in searchedSymbolList if symbol.getName() == symbolName] |
|
658 | 495 |
except Exception as ex: |
659 | 496 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
660 | 497 | |
661 |
return [] |
|
662 | ||
663 |
''' |
|
664 |
@brief detect equipment |
|
665 |
@author humkyung |
|
666 |
@date 2018.07.07 |
|
667 |
''' |
|
668 |
def detectEquipmentOnPid(mainRes, targetSymbol, listWidget, updateProgressSignal): |
|
669 |
global srcGray |
|
670 | ||
671 |
equipments = detectSymbolOnPid(mainRes, targetSymbol, listWidget, updateProgressSignal) |
|
672 |
for equipment in equipments: |
|
673 |
# detect nozzles around equimpent |
|
674 |
for nozzle in targetSymbolList[1]: |
|
675 |
print('EQUIPMENT({})-NOZZLE({})'.format(equipment.getName(), nozzle.getName())) |
|
676 |
pt = equipment.getSp() |
|
677 |
sx = round(pt[0]) - 100 |
|
678 |
sy = round(pt[1]) - 100 |
|
679 |
ex = round(pt[0] + equipment.getWidth()) + 100 |
|
680 |
ey = round(pt[1] + equipment.getHeight()) + 100 |
|
681 |
img = srcGray[sy:ey, sx:ex] |
|
682 |
detectNozzleOnPid(img, (sx,sy), (pt[0], pt[1], equipment.getWidth(), equipment.getHeight()), nozzle, listWidget, updateProgressSignal) |
|
683 |
# up to here |
|
684 |
|
|
685 | 498 |
''' |
686 | 499 |
@history 2018.05.17 Jeongwoo Bitwise_not target changed (Original Image → Symbol Image) |
687 | 500 |
''' |
... | ... | |
771 | 584 |
canvas[::] = (255, 255, 255) |
772 | 585 | |
773 | 586 |
try: |
774 |
appDocData = AppDocData.instance()
|
|
775 |
project = appDocData.getCurrentProject()
|
|
587 |
docData = AppDocData.instance()
|
|
588 |
project = docData.getCurrentProject()
|
|
776 | 589 | |
777 | 590 |
for symbol in searchedSymbolList: |
778 | 591 |
drawFoundSymbols(symbol, listWidget) |
... | ... | |
794 | 607 |
''' |
795 | 608 |
@history 2018.04.24 Jeongwoo Add isExceptDetect Field |
796 | 609 |
2018.05.09 Jeongwoo Add targetSymbolList clear |
797 |
humkyung 2018.07.07 store symbols to list as like [equipments],[nozzles],[symbols] |
|
798 | 610 |
''' |
799 | 611 |
def initTargetSymbolDataList(): |
612 |
############ region SQLite |
|
800 | 613 |
global targetSymbolList |
801 | 614 | |
802 | 615 |
targetSymbolList.clear() |
803 |
appDocData = AppDocData.instance() |
|
804 |
symbolList = appDocData.getTargetSymbolList() |
|
805 |
equipments = [item for item in symbolList if appDocData.getSymbolCategoryByType(item.getType()) == 'Equipment'] |
|
806 |
nozzles = [item for item in symbolList if item.getType() == 'Nozzles'] |
|
807 |
# [[equipments],[nozzles],[symbols]] |
|
808 |
targetSymbolList.append(equipments) |
|
809 |
targetSymbolList.append(nozzles) |
|
810 |
targetSymbolList.append([item for item in symbolList if item not in equipments and item not in nozzles]) |
|
616 |
dict = {} |
|
617 |
symbolList = AppDocData.instance().getTargetSymbolList() |
|
618 |
targetSymbolList.extend(symbolList) |
|
619 | ||
620 |
## Init Symbol Data from SQLite |
|
621 |
''' |
|
622 |
for target in tempTargetList: |
|
623 |
symId = target.getId() // 100 # symId |
|
624 |
if symId in dict: |
|
625 |
dict[symId].append(target) |
|
626 |
else: |
|
627 |
symGroup = [] |
|
628 |
symGroup.append(target) |
|
629 |
dict[symId] = symGroup |
|
630 | ||
631 |
## Sort each symbol list by symbol id |
|
632 |
for k, v in dict.items(): |
|
633 |
dict[k] = sorted(v, key=lambda symbol:symbol.id) |
|
634 | ||
635 |
## Insert each symbol list into targetSymbolList |
|
636 |
for sym in list(dict.values()): |
|
637 |
targetSymbolList.append(sym) |
|
638 |
############ endregion SQLite |
|
639 |
''' |
|
811 | 640 | |
812 | 641 |
return targetSymbolList |
813 | 642 | |
... | ... | |
846 | 675 |
Jeongwoo 2018.06.08 Add angle Parameter on TOCR.getTextInfo |
847 | 676 |
humkyung 2018.06.16 update proessbar while recognizing text |
848 | 677 |
humkyung 2018.07.03 remove white space and replace given oldStr with newStr |
849 |
humkyung 2018.07.07 change method name to recognizeText
|
|
678 |
humkyung 2018.07.04 set
|
|
850 | 679 |
''' |
851 |
def recognizeText(mainRes, tInfoList, searchedSymbolList, updateProgressSignal, listWidget): |
|
852 |
import re |
|
853 | ||
680 |
def initMainSrc(mainRes, tInfoList, searchedSymbolList, updateProgressSignal, listWidget): |
|
854 | 681 |
global srcGray |
855 | 682 |
global ocrCompletedSrc |
856 | 683 |
global textInfoList |
... | ... | |
858 | 685 |
global maxProgressValue |
859 | 686 | |
860 | 687 |
try: |
861 |
appDocData = AppDocData.instance()
|
|
862 |
project = appDocData.getCurrentProject()
|
|
688 |
docData = AppDocData.instance()
|
|
689 |
project = docData.getCurrentProject()
|
|
863 | 690 | |
864 | 691 |
path = os.path.join(project.getTempPath(), 'OCR_' + os.path.basename(mainRes)) |
865 | 692 |
if os.path.isfile(path): |
866 |
configs = appDocData.getConfigs('Text Recognition', 'Remove White Space')
|
|
693 |
configs = docData.getConfigs('Text Recognition', 'Remove White Space')
|
|
867 | 694 |
removeWhiteSpace = 'True' == configs[0].value if len(configs) == 1 else False |
868 |
configs = appDocData.getConfigs('Text Recognition', 'OldStr')
|
|
695 |
configs = docData.getConfigs('Text Recognition', 'OldStr')
|
|
869 | 696 |
oldStr = configs[0].value if len(configs) == 1 else '' |
870 |
configs = appDocData.getConfigs('Text Recognition', 'NewStr')
|
|
697 |
configs = docData.getConfigs('Text Recognition', 'NewStr')
|
|
871 | 698 |
newStr = configs[0].value if len(configs) == 1 else '' |
872 | 699 | |
873 | 700 |
ocrCompletedSrc = srcGray.copy() |
... | ... | |
876 | 703 |
imgOCR = cv2.imread(path, 1) |
877 | 704 |
imgOCR = cv2.threshold(cvtGrayImage(imgOCR), 127, 255, cv2.THRESH_BINARY)[1] |
878 | 705 | |
879 |
# get unit no. |
|
880 |
area = appDocData.getArea('Unit') |
|
881 |
if area is not None: |
|
882 |
img = srcGray[round(area.y):round(area.y+area.height), round(area.x):round(area.x+area.width)] |
|
883 |
text = TOCR.getTextInfo(img, (area.x, area.y), 0) |
|
884 |
if text is not None: |
|
885 |
appDocData.activeDrawing.setAttr('Unit', text[0].getText()) |
|
886 |
# up to here |
|
887 | ||
888 | 706 |
global MIN_TEXT_SIZE |
889 |
area = appDocData.getArea('Drawing')
|
|
707 |
area = AppDocData.instance().getArea('Drawing')
|
|
890 | 708 |
for tInfo in tInfoList: |
891 | 709 |
if tInfo.getW() >= MIN_TEXT_SIZE or tInfo.getH() >= MIN_TEXT_SIZE: |
892 | 710 |
x = tInfo.getX() - round(area.x) |
... | ... | |
894 | 712 |
img = imgOCR[y:y+tInfo.getH(), x:x+tInfo.getW()] |
895 | 713 | |
896 | 714 |
# set angle 0 if symbol contains the text area is instrumentation |
897 |
category = None |
|
898 | 715 |
contains = [symbol for symbol in searchedSymbolList if symbol.contains(tInfo)] |
899 | 716 |
if contains: |
900 | 717 |
_type = contains[0].getType() |
901 |
category = appDocData.getSymbolCategoryByType(_type)
|
|
718 |
category = docData.getSymbolCategoryByType(_type)
|
|
902 | 719 |
if 'Instrumentation' == category: tInfo.setAngle(0) |
903 | 720 |
# up to here |
904 | 721 | |
... | ... | |
909 | 726 |
result.setY(result.getY() + round(area.y)) |
910 | 727 |
if removeWhiteSpace: result.setText(result.getText().replace(' ', '')) # remove white space - 2018.07.03 added by humkyung |
911 | 728 |
if oldStr != '': result.setText(result.getText().replace(oldStr, newStr)) # replace oldStr with newStr - 2018.07.03 added by humkyung |
912 |
if 'Instrumentation' == category: |
|
913 |
text = re.sub('[^a-zA-Z0-9]+', '', result.getText()) |
|
914 |
result.setText(text) |
|
915 | 729 |
textInfoList.extend(resultTextInfo) |
916 | 730 |
ocrCompletedSrc = removeText(ocrCompletedSrc, (tInfo.getX(), tInfo.getY()), img) |
917 | 731 |
|
... | ... | |
925 | 739 |
cv2.imwrite(os.path.join(project.getTempPath(), "XOCR_" + os.path.basename(mainRes)), ocrCompletedSrc) |
926 | 740 | |
927 | 741 |
# parse Note |
928 |
noteArea = appDocData.getArea('Note')
|
|
742 |
noteArea = AppDocData.instance().getArea('Note')
|
|
929 | 743 |
if noteArea is not None: |
930 | 744 |
noteArea.img = srcGray[round(noteArea.y-1):round(noteArea.y+noteArea.height-1), round(noteArea.x-1):round(noteArea.x+noteArea.width-1)] |
931 | 745 |
noteTextInfoList = TOCR.getTextInfo(noteArea.img, (noteArea.x, noteArea.y)) |
... | ... | |
941 | 755 |
''' |
942 | 756 |
def removeSmallObjects(image): |
943 | 757 |
try: |
944 |
appDocData = AppDocData.instance()
|
|
945 |
configs = appDocData.getConfigs('Small Object Size', 'Min Area')
|
|
758 |
docData = AppDocData.instance()
|
|
759 |
configs = docData.getConfigs('Small Object Size', 'Min Area')
|
|
946 | 760 |
minArea = int(configs[0].value) if 1 == len(configs) else 20 |
947 |
configs = appDocData.getConfigs('Small Object Size', 'Max Area')
|
|
761 |
configs = docData.getConfigs('Small Object Size', 'Max Area')
|
|
948 | 762 |
maxArea = int(configs[0].value) if 1 == len(configs) else 50 |
949 | 763 | |
950 | 764 |
_,contours,_ = cv2.findContours(image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE); |
... | ... | |
1129 | 943 |
global maxProgressValue |
1130 | 944 |
|
1131 | 945 |
try: |
1132 |
appDocData = AppDocData.instance()
|
|
1133 |
project = appDocData.getCurrentProject()
|
|
946 |
docData = AppDocData.instance()
|
|
947 |
project = docData.getCurrentProject()
|
|
1134 | 948 | |
1135 | 949 |
srcList = [] |
1136 | 950 |
srcList.append(path) |
... | ... | |
1162 | 976 |
srcGray = cv2.threshold(srcGray, 127, 255, cv2.THRESH_BINARY)[1] |
1163 | 977 |
|
1164 | 978 |
# remove equipment desc. area |
1165 |
configs = appDocData.getConfigs('{} Equipment Desc Area'.format(appDocData.imgName))
|
|
979 |
configs = docData.getConfigs('{} Equipment Desc Area'.format(docData.imgName))
|
|
1166 | 980 |
for config in configs: |
1167 | 981 |
found = re.findall('\d+', config.value) |
1168 | 982 |
if len(found) == 4: |
1169 | 983 |
cv2.rectangle(srcGray, (int(found[0]), int(found[1])), (int(found[0])+int(found[2]), int(found[1])+int(found[3])), 255, -1) |
1170 | 984 |
# up to here |
1171 | 985 |
|
1172 |
area = appDocData.getArea('Drawing')
|
|
986 |
area = docData.getArea('Drawing')
|
|
1173 | 987 |
if area is not None: |
1174 | 988 |
area.img = srcGray[round(area.y):round(area.y+area.height), round(area.x):round(area.x+area.width)] |
1175 | 989 | |
... | ... | |
1188 | 1002 |
### up to here |
1189 | 1003 |
threadLock.release() |
1190 | 1004 | |
1191 |
# detect equipments |
|
1192 |
pool = futures.ThreadPoolExecutor(max_workers = THREAD_MAX_WORKER) |
|
1193 |
for symbol in targetSymbolList[0]: |
|
1194 |
pool.submit(detectEquipmentOnPid, mainRes, symbol, listWidget, updateProgressSignal) |
|
1195 |
pool.shutdown(wait = True) |
|
1196 |
# up to here |
|
1197 | ||
1198 | 1005 |
pool = futures.ThreadPoolExecutor(max_workers = THREAD_MAX_WORKER) |
1199 |
for symbol in targetSymbolList[2]:
|
|
1200 |
if type(symbol) is list:
|
|
1201 |
pool.submit(detectSymbolsOnPid, mainRes, symbol, listWidget, updateProgressSignal)
|
|
1006 |
for targetItem in targetSymbolList:
|
|
1007 |
if type(targetItem) is list:
|
|
1008 |
pool.submit(detectSymbolsOnPid, mainRes, targetItem, listWidget, updateProgressSignal)
|
|
1202 | 1009 |
else: |
1203 |
pool.submit(detectSymbolOnPid, mainRes, symbol, listWidget, updateProgressSignal)
|
|
1010 |
pool.submit(detectSymbolOnPid, mainRes, targetItem, listWidget, updateProgressSignal)
|
|
1204 | 1011 |
pool.shutdown(wait = True) |
1205 | 1012 | |
1206 | 1013 |
## DEBUG |
... | ... | |
1211 | 1018 |
cv2.imwrite(os.path.join(project.getTempPath(), 'Tile', item.getName()+'.png'), _img) |
1212 | 1019 |
## up to here |
1213 | 1020 | |
1214 |
recognizeText(mainRes, textAreas, searchedSymbolList, updateProgressSignal, listWidget)
|
|
1021 |
initMainSrc(mainRes, textAreas, searchedSymbolList, updateProgressSignal, listWidget)
|
|
1215 | 1022 | |
1216 |
chan, appDocData.imgWidth, appDocData.imgHeight = src.shape[::-1]
|
|
1023 |
chan, docData.imgWidth, docData.imgHeight = src.shape[::-1]
|
|
1217 | 1024 |
drawFoundSymbolsOnCanvas(mainRes, textInfoList, listWidget) |
1218 | 1025 |
|
1219 |
appDocData.imgName = os.path.splitext(os.path.basename(mainRes))[0]
|
|
1026 |
docData.imgName = os.path.splitext(os.path.basename(mainRes))[0]
|
|
1220 | 1027 | |
1221 | 1028 |
pool = futures.ThreadPoolExecutor(max_workers = THREAD_MAX_WORKER) |
1222 | 1029 |
for sym in searchedSymbolList: |
... | ... | |
1226 | 1033 |
|
1227 | 1034 |
global MIN_TEXT_SIZE |
1228 | 1035 |
for textInfo in textInfoList: |
1229 |
|
|
1230 | 1036 |
if textInfo.getW() >= MIN_TEXT_SIZE or textInfo.getH() >= MIN_TEXT_SIZE: |
1231 | 1037 |
removeText(srcGray, (textInfo.getX(), textInfo.getY()), srcGray[textInfo.getY():textInfo.getY()+textInfo.getH(), textInfo.getX():textInfo.getX()+textInfo.getW()]) |
1232 | 1038 | |
... | ... | |
1277 | 1083 |
def getTextAreaInfo(filePath, imgGray, offsetX, offsetY): |
1278 | 1084 |
from AppDocData import AppDocData |
1279 | 1085 | |
1280 |
appDocData = AppDocData.instance()
|
|
1281 |
project = appDocData.getCurrentProject()
|
|
1086 |
docData = AppDocData.instance()
|
|
1087 |
project = docData.getCurrentProject()
|
|
1282 | 1088 | |
1283 |
configs = appDocData.getConfigs('Text Size', 'Max Text Size')
|
|
1089 |
configs = docData.getConfigs('Text Size', 'Max Text Size')
|
|
1284 | 1090 |
maxTextSize = int(configs[0].value) if 1 == len(configs) else 100 |
1285 | 1091 | |
1286 | 1092 |
contourImg = np.ones(imgGray.shape, np.uint8) * 255 |
... | ... | |
1303 | 1109 |
cv2.imwrite(path, contourImg) |
1304 | 1110 | |
1305 | 1111 |
rects = [] |
1306 |
configs = appDocData.getConfigs('Text Recognition', 'Expand Size')
|
|
1112 |
configs = docData.getConfigs('Text Recognition', 'Expand Size')
|
|
1307 | 1113 |
expandSize = int(configs[0].value) if 1 == len(configs) else 10 |
1308 |
configs = appDocData.getConfigs('Text Recognition', 'Shrink Size')
|
|
1114 |
configs = docData.getConfigs('Text Recognition', 'Shrink Size')
|
|
1309 | 1115 |
shrinkSize = int(configs[0].value) if 1 == len(configs) else 0 |
1310 | 1116 | |
1311 | 1117 |
eroded = cv2.erode(contourImg, np.ones((expandSize,expandSize), np.uint8)) |
... | ... | |
1354 | 1160 | |
1355 | 1161 |
rects.append([0 if horizontal > vertical else 90, QRect(x, y, w, h)]) |
1356 | 1162 | |
1357 |
configs = appDocData.getConfigs('Text Recognition', 'Merge Size')
|
|
1163 |
configs = docData.getConfigs('Text Recognition', 'Merge Size')
|
|
1358 | 1164 |
mergeSize = int(configs[0].value) if 1 == len(configs) else 10 |
1359 | 1165 |
# merge rectangles |
1360 | 1166 |
intersected = True |
... | ... | |
1397 | 1203 |
global noteTextInfoList |
1398 | 1204 | |
1399 | 1205 |
try: |
1400 |
appDocData = AppDocData.instance()
|
|
1206 |
docData = AppDocData.instance()
|
|
1401 | 1207 |
if os.path.isfile(orgImagePath) and os.path.isfile(recImagePath): |
1402 | 1208 |
imgOriginal = cv2.threshold(cvtGrayImage(cv2.imread(orgImagePath, 1)), 127, 255, cv2.THRESH_BINARY)[1] |
1403 | 1209 |
# remove equipment desc. area |
1404 |
configs = appDocData.getConfigs('{} Equipment Desc Area'.format(appDocData.imgName))
|
|
1210 |
configs = docData.getConfigs('{} Equipment Desc Area'.format(docData.imgName))
|
|
1405 | 1211 |
for config in configs: |
1406 | 1212 |
found = re.findall('\d+', config.value) |
1407 | 1213 |
if len(found) == 4: |
... | ... | |
1424 | 1230 |
# remove noise |
1425 | 1231 |
imgDiff = cv2.dilate(imgDiff, np.ones((2, 2), np.uint8)) |
1426 | 1232 | |
1427 |
appDocData = AppDocData.instance()
|
|
1428 |
project = appDocData.getCurrentProject()
|
|
1233 |
docData = AppDocData.instance()
|
|
1234 |
project = docData.getCurrentProject()
|
|
1429 | 1235 |
cv2.imwrite(os.path.join(project.getTempPath(), "DIFF_" + os.path.basename(orgImagePath)), imgDiff) |
1430 | 1236 |
except Exception as ex: |
1431 | 1237 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
DTI_PID/DTI_PID/DTI_PID.pyproj | ||
---|---|---|
82 | 82 |
<SubType>Code</SubType> |
83 | 83 |
</Compile> |
84 | 84 |
<Compile Include="Recognition_UI.py" /> |
85 |
<Compile Include="Shapes\SymbolSvgItem.py" /> |
|
85 | 86 |
<Compile Include="SingletonInstance.py" /> |
86 | 87 |
<Compile Include="symbol.py"> |
87 | 88 |
<SubType>Code</SubType> |
... | ... | |
106 | 107 |
<SubType>Code</SubType> |
107 | 108 |
</Compile> |
108 | 109 |
</ItemGroup> |
110 |
<ItemGroup> |
|
111 |
<Folder Include="Shapes\" /> |
|
112 |
</ItemGroup> |
|
109 | 113 |
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Python Tools\Microsoft.PythonTools.targets" /> |
110 | 114 |
<!-- Uncomment the CoreCompile target to enable the Build command in |
111 | 115 |
Visual Studio and specify your pre- and post-build commands in |
DTI_PID/DTI_PID/LineNoTracer.py | ||
---|---|---|
94 | 94 |
Jeongwoo 2018.05.17 Modify find secondary lines with 'while' |
95 | 95 |
Modify find secondary lines with 'while' used sublist for unconnected line |
96 | 96 |
humkyung 2018.05.18 set start line's owner before tracing |
97 |
humkyung 2018.07.05 update line type |
|
98 | 97 |
''' |
99 | 98 |
def execute(self, displayMessage, updateProgress, toler=50): |
100 | 99 |
from QEngineeringLineItem import QEngineeringLineItem |
... | ... | |
165 | 164 |
updateProgress.emit(maxValue) |
166 | 165 | |
167 | 166 |
docData.lineNos.append(trimLineNo) |
168 | ||
167 |
|
|
169 | 168 |
updateProgress.emit(maxValue) |
170 | 169 |
except Exception as ex: |
171 | 170 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
... | ... | |
245 | 244 |
elif type(item) is QEngineeringLineItem: |
246 | 245 |
lines.append(item) |
247 | 246 | |
247 |
# trace line no |
|
248 |
tracer = LineNoTracer(symbols, lines, lineNos) |
|
249 |
tracer.execute(worker.displayMessage, worker.updateProgress) |
|
250 |
# up to here |
|
251 | ||
252 | ||
253 |
findSymbols = [symbol for symbol in worker.graphicsView.scene.items() if type(symbol) is SymbolSvgItem and symbol.hasInstrumentLabel == 1] |
|
254 |
for symbol in findSymbols: |
|
255 |
symbol.getConnectedLabel(worker) |
|
256 | ||
248 | 257 |
# connect attribut |
249 | 258 |
texts = [item for item in worker.graphicsView.scene.items() if issubclass(type(item), QEngineeringTextItem)] |
250 | 259 |
for symbol in symbols: |
251 | 260 |
symbol.connectAttribute(texts) |
252 | 261 |
# up to here |
253 | ||
254 |
# trace line no |
|
255 |
tracer = LineNoTracer(symbols, lines, lineNos) |
|
256 |
tracer.execute(worker.displayMessage, worker.updateProgress) |
|
257 |
# up to here |
|
258 | 262 |
except Exception as ex: |
259 | 263 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
260 | 264 |
finally: |
DTI_PID/DTI_PID/MainWindow.py | ||
---|---|---|
481 | 481 |
else: |
482 | 482 |
_chan, w, h = img.shape[::-1] |
483 | 483 |
svg = SymbolSvgItem(svgPath) |
484 |
svg.buildItem(newSym.getName(), newSym.getType(), 0, [offsetX, 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()) |
|
484 |
svg.buildItem(newSym.getName(), newSym.getType(), 0, [offsetX, 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(), newSym.getHasInstrumentLabel)
|
|
485 | 485 | |
486 | 486 |
svg.removed.connect(self.resultTreeWidget.itemRemoved) |
487 | 487 |
svg.addSvgItemToScene(self.graphicsView.scene) |
... | ... | |
629 | 629 |
connPts = [(pt[0] + float(x.split(',')[0]), pt[1] + float(x.split(',')[1])) for x in symbol.getConnectionPoint().split('/') if 2 == len(x.split(','))] |
630 | 630 |
parentSymbol = symbol.getBaseSymbol() |
631 | 631 |
childSymbol = symbol.getAdditionalSymbol() |
632 |
|
|
632 |
hasInstrumentLabel = symbol.getHasInstrumentLabel() |
|
633 | ||
633 | 634 |
svgFilePath = os.path.join(project.getSvgFilePath(), type, name + '.svg') |
634 | 635 |
if os.path.isfile(svgFilePath): |
635 | 636 |
svg = SymbolSvgItem.createItem(type, svgFilePath) |
636 |
svg.buildItem(name, type, angle, pt, size, origin, connPts, parentSymbol, childSymbol) |
|
637 |
svg.buildItem(name, type, angle, pt, size, origin, connPts, parentSymbol, childSymbol, hasInstrumentLabel)
|
|
637 | 638 | |
638 | 639 |
#### lambda param=svg : bind 'svg' object to lambda('param') |
639 | 640 |
#### If case of 'lambda svg=svg:', function uses the 'svg' value bound to lambda |
... | ... | |
803 | 804 |
if childSymbolNode is not None: |
804 | 805 |
childSymbol = childSymbolNode.text |
805 | 806 |
|
807 |
hasInstrumentLabelNode = symbol.find('HASINSTRUMENTLABEL') |
|
808 |
if hasInstrumentLabelNode is not None: |
|
809 |
hasInstrumentLabel = hasInstrumentLabelNode.text |
|
810 | ||
806 | 811 |
svgFilePath = os.path.join(project.getSvgFilePath(), type, name + '.svg') |
807 | 812 |
if os.path.isfile(svgFilePath): |
808 | 813 |
svg = SymbolSvgItem.createItem(type, svgFilePath) |
809 |
svg.buildItem(name, type, angle, pt, size, origin, connPts, baseSymbol, childSymbol) |
|
814 |
svg.buildItem(name, type, angle, pt, size, origin, connPts, baseSymbol, childSymbol, hasInstrumentLabel)
|
|
810 | 815 | |
811 | 816 |
svg.removed.connect(self.itemRemoved) |
812 | 817 |
self.addSvgItemToScene(svg) |
DTI_PID/DTI_PID/QtImageViewer.py | ||
---|---|---|
436 | 436 |
if strConnPts is not None: |
437 | 437 |
connPts = [(float(x.split(',')[0]), float(x.split(',')[1])) for x in strConnPts.split('/')] |
438 | 438 | |
439 |
svg.buildItem(svgFileName, symbol.getType(), 0, None, None, [float(x) for x in symbol.getOriginalPoint().split(',')], connPts, symbol.getBaseSymbol(), symbol.getAdditionalSymbol()) |
|
439 |
svg.buildItem(svgFileName, symbol.getType(), 0, None, None, [float(x) for x in symbol.getOriginalPoint().split(',')], connPts, symbol.getBaseSymbol(), symbol.getAdditionalSymbol(), symbol.getHasInstrumentLabel())
|
|
440 | 440 | |
441 | 441 |
matches = [item for item in self.scene.items() if (type(item) is QEngineeringLineItem) and (item.distanceTo((scenePos.x(), scenePos.y())) < 20)] |
442 | 442 |
if len(matches) == 1: |
DTI_PID/DTI_PID/Shapes/SymbolSvgItem.py | ||
---|---|---|
45 | 45 |
self._owner = None |
46 | 46 |
self.parentSymbol = '' |
47 | 47 |
self.childSymbol = '' |
48 |
self.hasInstrumentLabel = 0 |
|
48 | 49 | |
49 | 50 |
self.setAcceptHoverEvents(True) |
50 | 51 |
self.setAcceptedMouseButtons(Qt.LeftButton) |
... | ... | |
94 | 95 |
@history 2018.05.09 Jeongwoo Clear self.connectors |
95 | 96 |
2018.05.30 Jeongwoo Add parameters (parentSymbol, childSymbol) |
96 | 97 |
''' |
97 |
def buildItem(self, name, type, angle, loc, size, origin, connPts, parentSymbol, childSymbol): |
|
98 |
def buildItem(self, name, type, angle, loc, size, origin, connPts, parentSymbol, childSymbol, hasInstrumentLabel):
|
|
98 | 99 |
try: |
99 | 100 |
self.name = name |
100 | 101 |
self.type = type |
... | ... | |
105 | 106 |
self.connPts = connPts |
106 | 107 |
self.parentSymbol = parentSymbol |
107 | 108 |
self.childSymbol = childSymbol |
109 |
self.hasInstrumentLabel = hasInstrumentLabel |
|
108 | 110 | |
109 | 111 |
self.connectors.clear() |
110 | 112 |
for pt in self.connPts: |
... | ... | |
338 | 340 | |
339 | 341 |
if selected is not None: self.attrs.append(selected) |
340 | 342 | |
343 | ||
344 |
''' |
|
345 |
@Auther Yecheol |
|
346 |
@Date 2018.07.06 |
|
347 |
@History add Get not connected Attribute Item |
|
348 |
''' |
|
349 |
def getConnectedLabel(self, Worker): |
|
350 |
import math |
|
351 |
from QEngineeringInstrumentItem import QEngineeringInstrumentItem |
|
352 | ||
353 | ||
354 |
findSymbols = [symbol for symbol in Worker.graphicsView.scene.items() if type(symbol) is QEngineeringInstrumentItem] |
|
355 | ||
356 |
for findSymbol in findSymbols: |
|
357 |
if len(findSymbol.conns) == 4: |
|
358 |
iNoneCount = 0 |
|
359 |
for conn in findSymbol.conns: |
|
360 |
if conn is None: |
|
361 |
iNoneCount += 1 |
|
362 |
|
|
363 |
if iNoneCount == len(findSymbol.conns): |
|
364 |
fX = self.origin[0] |
|
365 |
fY = self.origin[1] |
|
366 |
fFindX = findSymbol.origin[0] |
|
367 |
fFindY = findSymbol.origin[1] |
|
368 |
if math.fabs(fX - fFindX) < 200 and math.fabs(fY - fFindY) < 200: |
|
369 |
self.attrs.append(findSymbol) |
|
370 | ||
341 | 371 |
''' |
342 | 372 |
@brief get attribute |
343 | 373 |
@author humkyung |
... | ... | |
355 | 385 |
humkyung 2018.04.27 add originalpoint xml node |
356 | 386 |
humkyung 2018.05.02 add attribute of symbol |
357 | 387 |
Jeongwoo 2018.05.30 add attribute of symbol (parentSymbol, childSymbol, type, connectionPoint) |
388 |
yecheol 2018.07.11 add attribute of symbol (hasInstrumentLabel) |
|
358 | 389 |
''' |
359 | 390 |
def toXml(self): |
360 | 391 |
from xml.etree.ElementTree import Element, SubElement, dump, ElementTree |
... | ... | |
408 | 439 |
childSymbolNode = Element('CHILD') |
409 | 440 |
childSymbolNode.text = str(self.childSymbol) |
410 | 441 |
node.append(childSymbolNode) |
442 | ||
443 |
hasInstrumentLabelNode = Element('HASINSTRUMENTLABEL') |
|
444 |
hasInstrumentLabelNode.text = str(self.hasInstrumentLabel) |
|
445 |
node.append(hasInstrumentLabelNode) |
|
411 | 446 |
except Exception as ex: |
412 | 447 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
413 | 448 |
DTI_PID/DTI_PID/SymbolBase.py | ||
---|---|---|
7 | 7 |
, isDetectOnOrigin = False, rotationCount = 4, ocrOption = OCR_OPTION_NOT_EXEC, isContainChild = 0 |
8 | 8 |
, originalPoint = None, connectionPoint = None, baseSymbol = None, additionalSymbol = None |
9 | 9 |
, isExceptDetect = 0, hasInstrumentLabel = 0, uid = None): |
10 |
#def __init__(self, id, sName, sType, path = None, threshold = None, minMatchCount = 0 |
|
11 |
# , isDetectOnOrigin = False, rotationCount = 4, ocrOption = OCR_OPTION_NOT_EXEC, isContainChild = 0 |
|
12 |
# , originalPoint = None, connectionPoint = None, baseSymbol = None, additionalSymbol = None |
|
13 |
# , uid = None): |
|
10 | 14 |
self.uid = uid ## Auto increased Unique Id |
15 |
#self.id = id ## Symbol Id |
|
11 | 16 |
self.sName = sName |
12 | 17 |
self.sType = sType |
18 |
#self.path = path |
|
13 | 19 |
self.threshold = threshold |
14 | 20 |
self.minMatchCount = minMatchCount |
15 | 21 |
self.isDetectOnOrigin = isDetectOnOrigin |
... | ... | |
30 | 36 |
def getUid(self): |
31 | 37 |
return self.uid |
32 | 38 | |
39 |
''' |
|
40 |
def setId(self, id): |
|
41 |
self.id = id |
|
42 |
''' |
|
43 |
''' |
|
44 |
def getId(self): |
|
45 |
return self.id |
|
46 |
''' |
|
47 | ||
33 | 48 |
def setName(self, sName): |
34 | 49 |
self.sName = sName |
35 | 50 | |
... | ... | |
42 | 57 |
def getType(self): |
43 | 58 |
return self.sType |
44 | 59 |
|
60 |
#def setPath(self, path): |
|
61 |
# self.path = path |
|
62 | ||
45 | 63 |
def getPath(self): |
46 | 64 |
from AppDocData import AppDocData |
47 | ||
65 |
#return self.path |
|
48 | 66 |
return AppDocData.instance().getCurrentProject().getImageFilePath() + "/" + self.sType + "/" + self.sName + ".png" |
49 | 67 | |
50 | 68 |
def setThreshold(self, threshold): |
... | ... | |
113 | 131 |
def getIsExceptDetect(self): |
114 | 132 |
return self.isExceptDetect |
115 | 133 | |
116 |
def setHasInstrumentLabel(self, hasInstrumentLabel): |
|
117 |
self.hasInstrumentLabel = hasInstrumentLabel |
|
118 | ||
119 |
def getHasInstrumentLabel(self): |
|
120 |
return self.hasInstrumentLabel |
|
121 | 134 |
''' |
122 | 135 |
@Auther Yechecol |
123 | 136 |
@Date 2018.07.03 |
124 | 137 |
@History hasInstrumentLabel add |
125 | 138 |
''' |
139 |
def setHasInstrumentLabel(self, hasInstrumentLabel): |
|
140 |
self.hasInstrumentLabel = hasInstrumentLabel |
|
141 | ||
142 |
def getHasInstrumentLabel(self): |
|
143 |
return self.hasInstrumentLabel |
|
144 | ||
126 | 145 | |
127 | 146 | |
128 | 147 |
''' |
DTI_PID/DTI_PID/SymbolEditor_UI.py | ||
---|---|---|
209 | 209 |
self.scrollArea.setWidgetResizable(True) |
210 | 210 |
self.scrollArea.setObjectName("scrollArea") |
211 | 211 |
self.scrollAreaWidgetContents = QtWidgets.QWidget() |
212 |
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 401, 680))
|
|
212 |
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 409, 651))
|
|
213 | 213 |
self.scrollAreaWidgetContents.setMinimumSize(QtCore.QSize(378, 0)) |
214 | 214 |
self.scrollAreaWidgetContents.setMaximumSize(QtCore.QSize(16777215, 16777215)) |
215 | 215 |
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents") |
216 |
self.formLayout = QtWidgets.QFormLayout(self.scrollAreaWidgetContents) |
|
216 |
self.gridLayout_4 = QtWidgets.QGridLayout(self.scrollAreaWidgetContents) |
|
217 |
self.gridLayout_4.setObjectName("gridLayout_4") |
|
218 |
self.formLayout = QtWidgets.QFormLayout() |
|
219 |
self.formLayout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint) |
|
220 |
self.formLayout.setFieldGrowthPolicy(QtWidgets.QFormLayout.AllNonFixedFieldsGrow) |
|
221 |
self.formLayout.setLabelAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) |
|
222 |
self.formLayout.setFormAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop) |
|
223 |
self.formLayout.setContentsMargins(6, 6, 6, 6) |
|
217 | 224 |
self.formLayout.setObjectName("formLayout") |
225 |
self.idLabel = QtWidgets.QLabel(self.scrollAreaWidgetContents) |
|
226 |
font = QtGui.QFont() |
|
227 |
font.setBold(True) |
|
228 |
font.setWeight(75) |
|
229 |
self.idLabel.setFont(font) |
|
230 |
self.idLabel.setObjectName("idLabel") |
|
231 |
self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.idLabel) |
|
232 |
self.idLineEdit = QtWidgets.QLineEdit(self.scrollAreaWidgetContents) |
|
233 |
self.idLineEdit.setObjectName("idLineEdit") |
|
234 |
self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.idLineEdit) |
|
218 | 235 |
self.nameLabel = QtWidgets.QLabel(self.scrollAreaWidgetContents) |
219 | 236 |
font = QtGui.QFont() |
220 | 237 |
font.setBold(True) |
221 | 238 |
font.setWeight(75) |
222 | 239 |
self.nameLabel.setFont(font) |
223 | 240 |
self.nameLabel.setObjectName("nameLabel") |
224 |
self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.nameLabel)
|
|
241 |
self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.nameLabel)
|
|
225 | 242 |
self.nameLineEdit = QtWidgets.QLineEdit(self.scrollAreaWidgetContents) |
226 | 243 |
self.nameLineEdit.setObjectName("nameLineEdit") |
227 |
self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.nameLineEdit)
|
|
244 |
self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.nameLineEdit)
|
|
228 | 245 |
self.thresholdLabel = QtWidgets.QLabel(self.scrollAreaWidgetContents) |
229 | 246 |
font = QtGui.QFont() |
230 | 247 |
font.setBold(True) |
231 | 248 |
font.setWeight(75) |
232 | 249 |
self.thresholdLabel.setFont(font) |
233 | 250 |
self.thresholdLabel.setObjectName("thresholdLabel") |
234 |
self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.thresholdLabel)
|
|
251 |
self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.thresholdLabel)
|
|
235 | 252 |
self.thresholdLineEdit = QtWidgets.QLineEdit(self.scrollAreaWidgetContents) |
236 | 253 |
self.thresholdLineEdit.setObjectName("thresholdLineEdit") |
237 |
self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.thresholdLineEdit)
|
|
254 |
self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.thresholdLineEdit)
|
|
238 | 255 |
self.minMatchPointLabel = QtWidgets.QLabel(self.scrollAreaWidgetContents) |
239 | 256 |
font = QtGui.QFont() |
240 | 257 |
font.setBold(True) |
241 | 258 |
font.setWeight(75) |
242 | 259 |
self.minMatchPointLabel.setFont(font) |
243 | 260 |
self.minMatchPointLabel.setObjectName("minMatchPointLabel") |
244 |
self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.minMatchPointLabel)
|
|
261 |
self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.minMatchPointLabel)
|
|
245 | 262 |
self.minMatchPointLineEdit = QtWidgets.QLineEdit(self.scrollAreaWidgetContents) |
246 | 263 |
self.minMatchPointLineEdit.setObjectName("minMatchPointLineEdit") |
247 |
self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.minMatchPointLineEdit)
|
|
264 |
self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.minMatchPointLineEdit)
|
|
248 | 265 |
self.rotationCountLabel = QtWidgets.QLabel(self.scrollAreaWidgetContents) |
249 | 266 |
font = QtGui.QFont() |
250 | 267 |
font.setBold(True) |
251 | 268 |
font.setWeight(75) |
252 | 269 |
self.rotationCountLabel.setFont(font) |
253 | 270 |
self.rotationCountLabel.setObjectName("rotationCountLabel") |
254 |
self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.rotationCountLabel)
|
|
271 |
self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.rotationCountLabel)
|
|
255 | 272 |
self.rotationCountSpinBox = QtWidgets.QSpinBox(self.scrollAreaWidgetContents) |
256 | 273 |
self.rotationCountSpinBox.setMinimum(0) |
257 | 274 |
self.rotationCountSpinBox.setMaximum(3) |
258 | 275 |
self.rotationCountSpinBox.setProperty("value", 0) |
259 | 276 |
self.rotationCountSpinBox.setObjectName("rotationCountSpinBox") |
260 |
self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.rotationCountSpinBox)
|
|
277 |
self.formLayout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.rotationCountSpinBox)
|
|
261 | 278 |
self.isContainChildLabel = QtWidgets.QLabel(self.scrollAreaWidgetContents) |
262 | 279 |
font = QtGui.QFont() |
263 | 280 |
font.setBold(True) |
264 | 281 |
font.setWeight(75) |
265 | 282 |
self.isContainChildLabel.setFont(font) |
266 | 283 |
self.isContainChildLabel.setObjectName("isContainChildLabel") |
267 |
self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.isContainChildLabel)
|
|
284 |
self.formLayout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.isContainChildLabel)
|
|
268 | 285 |
self.isContainChildCheckBox = QtWidgets.QCheckBox(self.scrollAreaWidgetContents) |
269 | 286 |
self.isContainChildCheckBox.setText("") |
270 | 287 |
self.isContainChildCheckBox.setCheckable(True) |
271 | 288 |
self.isContainChildCheckBox.setObjectName("isContainChildCheckBox") |
272 |
self.formLayout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.isContainChildCheckBox)
|
|
289 |
self.formLayout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.isContainChildCheckBox)
|
|
273 | 290 |
self.typeLabel = QtWidgets.QLabel(self.scrollAreaWidgetContents) |
274 | 291 |
font = QtGui.QFont() |
275 | 292 |
font.setBold(True) |
276 | 293 |
font.setWeight(75) |
277 | 294 |
self.typeLabel.setFont(font) |
278 | 295 |
self.typeLabel.setObjectName("typeLabel") |
279 |
self.formLayout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.typeLabel)
|
|
296 |
self.formLayout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.typeLabel)
|
|
280 | 297 |
self.typeComboBox = QtWidgets.QComboBox(self.scrollAreaWidgetContents) |
281 | 298 |
self.typeComboBox.setObjectName("typeComboBox") |
282 |
self.formLayout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.typeComboBox)
|
|
299 |
self.formLayout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.typeComboBox)
|
|
283 | 300 |
self.baseSymbolLabel = QtWidgets.QLabel(self.scrollAreaWidgetContents) |
284 | 301 |
font = QtGui.QFont() |
285 | 302 |
font.setBold(True) |
286 | 303 |
font.setWeight(75) |
287 | 304 |
self.baseSymbolLabel.setFont(font) |
288 | 305 |
self.baseSymbolLabel.setObjectName("baseSymbolLabel") |
289 |
self.formLayout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.baseSymbolLabel)
|
|
306 |
self.formLayout.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.baseSymbolLabel)
|
|
290 | 307 |
self.baseSymbolComboBox = QtWidgets.QComboBox(self.scrollAreaWidgetContents) |
291 | 308 |
self.baseSymbolComboBox.setObjectName("baseSymbolComboBox") |
292 |
self.formLayout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.baseSymbolComboBox)
|
|
309 |
self.formLayout.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.baseSymbolComboBox)
|
|
293 | 310 |
self.additionalSymbolLabel = QtWidgets.QLabel(self.scrollAreaWidgetContents) |
294 | 311 |
font = QtGui.QFont() |
295 | 312 |
font.setBold(True) |
296 | 313 |
font.setWeight(75) |
297 | 314 |
self.additionalSymbolLabel.setFont(font) |
298 | 315 |
self.additionalSymbolLabel.setObjectName("additionalSymbolLabel") |
299 |
self.formLayout.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.additionalSymbolLabel)
|
|
316 |
self.formLayout.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.additionalSymbolLabel)
|
|
300 | 317 |
self.horizontalLayout_2 = QtWidgets.QHBoxLayout() |
301 | 318 |
self.horizontalLayout_2.setObjectName("horizontalLayout_2") |
302 | 319 |
self.defaultSymbolDirectionComboBox = QtWidgets.QComboBox(self.scrollAreaWidgetContents) |
... | ... | |
310 | 327 |
self.addAdditionalSymbolButton.setMaximumSize(QtCore.QSize(40, 16777215)) |
311 | 328 |
self.addAdditionalSymbolButton.setObjectName("addAdditionalSymbolButton") |
312 | 329 |
self.horizontalLayout_2.addWidget(self.addAdditionalSymbolButton) |
313 |
self.formLayout.setLayout(7, QtWidgets.QFormLayout.FieldRole, self.horizontalLayout_2)
|
|
330 |
self.formLayout.setLayout(8, QtWidgets.QFormLayout.FieldRole, self.horizontalLayout_2)
|
|
314 | 331 |
self.additionalSymbolListWidget = QtWidgets.QListWidget(self.scrollAreaWidgetContents) |
315 | 332 |
self.additionalSymbolListWidget.setObjectName("additionalSymbolListWidget") |
316 |
self.formLayout.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.additionalSymbolListWidget)
|
|
333 |
self.formLayout.setWidget(9, QtWidgets.QFormLayout.FieldRole, self.additionalSymbolListWidget)
|
|
317 | 334 |
self.originalPointLabel = QtWidgets.QLabel(self.scrollAreaWidgetContents) |
318 | 335 |
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) |
319 | 336 |
sizePolicy.setHorizontalStretch(0) |
... | ... | |
326 | 343 |
self.originalPointLabel.setFont(font) |
327 | 344 |
self.originalPointLabel.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) |
328 | 345 |
self.originalPointLabel.setObjectName("originalPointLabel") |
329 |
self.formLayout.setWidget(9, QtWidgets.QFormLayout.LabelRole, self.originalPointLabel)
|
|
346 |
self.formLayout.setWidget(10, QtWidgets.QFormLayout.LabelRole, self.originalPointLabel)
|
|
330 | 347 |
self.horizontalLayout_4 = QtWidgets.QHBoxLayout() |
331 | 348 |
self.horizontalLayout_4.setObjectName("horizontalLayout_4") |
332 | 349 |
self.originalPointLineEdit = QtWidgets.QLineEdit(self.scrollAreaWidgetContents) |
... | ... | |
337 | 354 |
self.addOriginalPointButton.setMaximumSize(QtCore.QSize(40, 16777215)) |
338 | 355 |
self.addOriginalPointButton.setObjectName("addOriginalPointButton") |
339 | 356 |
self.horizontalLayout_4.addWidget(self.addOriginalPointButton) |
340 |
self.formLayout.setLayout(9, QtWidgets.QFormLayout.FieldRole, self.horizontalLayout_4)
|
|
357 |
self.formLayout.setLayout(10, QtWidgets.QFormLayout.FieldRole, self.horizontalLayout_4)
|
|
341 | 358 |
self.connectionPointLabel = QtWidgets.QLabel(self.scrollAreaWidgetContents) |
342 | 359 |
font = QtGui.QFont() |
343 | 360 |
font.setBold(True) |
... | ... | |
345 | 362 |
self.connectionPointLabel.setFont(font) |
346 | 363 |
self.connectionPointLabel.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) |
347 | 364 |
self.connectionPointLabel.setObjectName("connectionPointLabel") |
348 |
self.formLayout.setWidget(10, QtWidgets.QFormLayout.LabelRole, self.connectionPointLabel)
|
|
365 |
self.formLayout.setWidget(13, QtWidgets.QFormLayout.LabelRole, self.connectionPointLabel)
|
|
349 | 366 |
self.horizontalLayout_6 = QtWidgets.QHBoxLayout() |
350 | 367 |
self.horizontalLayout_6.setObjectName("horizontalLayout_6") |
351 | 368 |
self.connectionPointLineEdit = QtWidgets.QLineEdit(self.scrollAreaWidgetContents) |
... | ... | |
356 | 373 |
self.addConnectionPointButton.setMaximumSize(QtCore.QSize(40, 16777215)) |
357 | 374 |
self.addConnectionPointButton.setObjectName("addConnectionPointButton") |
358 | 375 |
self.horizontalLayout_6.addWidget(self.addConnectionPointButton) |
359 |
self.formLayout.setLayout(10, QtWidgets.QFormLayout.FieldRole, self.horizontalLayout_6)
|
|
376 |
self.formLayout.setLayout(13, QtWidgets.QFormLayout.FieldRole, self.horizontalLayout_6)
|
|
360 | 377 |
self.connectionPointList = QtWidgets.QListWidget(self.scrollAreaWidgetContents) |
361 | 378 |
self.connectionPointList.setObjectName("connectionPointList") |
362 |
self.formLayout.setWidget(11, QtWidgets.QFormLayout.FieldRole, self.connectionPointList) |
|
363 |
self.hasInstrumentLabel = QtWidgets.QLabel(self.scrollAreaWidgetContents) |
|
364 |
font = QtGui.QFont() |
|
365 |
font.setBold(True) |
|
366 |
font.setWeight(75) |
|
367 |
self.hasInstrumentLabel.setFont(font) |
|
368 |
self.hasInstrumentLabel.setObjectName("hasInstrumentLabel") |
|
369 |
self.formLayout.setWidget(12, QtWidgets.QFormLayout.LabelRole, self.hasInstrumentLabel) |
|
370 |
self.hasInstrumentLabelCheckBox = QtWidgets.QCheckBox(self.scrollAreaWidgetContents) |
|
371 |
self.hasInstrumentLabelCheckBox.setText("") |
|
372 |
self.hasInstrumentLabelCheckBox.setObjectName("hasInstrumentLabelCheckBox") |
|
373 |
self.formLayout.setWidget(12, QtWidgets.QFormLayout.FieldRole, self.hasInstrumentLabelCheckBox) |
|
379 |
self.formLayout.setWidget(14, QtWidgets.QFormLayout.FieldRole, self.connectionPointList) |
|
374 | 380 |
self.isExceptDetectLabel = QtWidgets.QLabel(self.scrollAreaWidgetContents) |
375 | 381 |
font = QtGui.QFont() |
376 | 382 |
font.setBold(True) |
377 | 383 |
font.setWeight(75) |
378 | 384 |
self.isExceptDetectLabel.setFont(font) |
379 | 385 |
self.isExceptDetectLabel.setObjectName("isExceptDetectLabel") |
380 |
self.formLayout.setWidget(13, QtWidgets.QFormLayout.LabelRole, self.isExceptDetectLabel)
|
|
386 |
self.formLayout.setWidget(16, QtWidgets.QFormLayout.LabelRole, self.isExceptDetectLabel)
|
|
381 | 387 |
self.isExceptDetectCheckBox = QtWidgets.QCheckBox(self.scrollAreaWidgetContents) |
382 | 388 |
self.isExceptDetectCheckBox.setText("") |
383 | 389 |
self.isExceptDetectCheckBox.setObjectName("isExceptDetectCheckBox") |
384 |
self.formLayout.setWidget(13, QtWidgets.QFormLayout.FieldRole, self.isExceptDetectCheckBox)
|
|
390 |
self.formLayout.setWidget(16, QtWidgets.QFormLayout.FieldRole, self.isExceptDetectCheckBox)
|
|
385 | 391 |
self.immediateInsertLabel = QtWidgets.QLabel(self.scrollAreaWidgetContents) |
386 | 392 |
font = QtGui.QFont() |
387 | 393 |
font.setBold(True) |
388 | 394 |
font.setWeight(75) |
389 | 395 |
self.immediateInsertLabel.setFont(font) |
390 | 396 |
self.immediateInsertLabel.setObjectName("immediateInsertLabel") |
391 |
self.formLayout.setWidget(14, QtWidgets.QFormLayout.LabelRole, self.immediateInsertLabel)
|
|
397 |
self.formLayout.setWidget(17, QtWidgets.QFormLayout.LabelRole, self.immediateInsertLabel)
|
|
392 | 398 |
self.immediateInsertCheckBox = QtWidgets.QCheckBox(self.scrollAreaWidgetContents) |
393 | 399 |
self.immediateInsertCheckBox.setText("") |
394 | 400 |
self.immediateInsertCheckBox.setObjectName("immediateInsertCheckBox") |
395 |
self.formLayout.setWidget(14, QtWidgets.QFormLayout.FieldRole, self.immediateInsertCheckBox) |
|
396 |
self.buttonBox = QtWidgets.QDialogButtonBox(self.scrollAreaWidgetContents) |
|
397 |
self.buttonBox.setLayoutDirection(QtCore.Qt.LeftToRight) |
|
398 |
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Close|QtWidgets.QDialogButtonBox.Save) |
|
399 |
self.buttonBox.setObjectName("buttonBox") |
|
400 |
self.formLayout.setWidget(15, QtWidgets.QFormLayout.SpanningRole, self.buttonBox) |
|
401 |
self.formLayout.setWidget(17, QtWidgets.QFormLayout.FieldRole, self.immediateInsertCheckBox) |
|
402 |
self.hasInstrumentLabel = QtWidgets.QLabel(self.scrollAreaWidgetContents) |
|
403 |
font = QtGui.QFont() |
|
404 |
font.setBold(True) |
|
405 |
font.setWeight(75) |
|
406 |
self.hasInstrumentLabel.setFont(font) |
|
407 |
self.hasInstrumentLabel.setObjectName("hasInstrumentLabel") |
|
408 |
self.formLayout.setWidget(15, QtWidgets.QFormLayout.LabelRole, self.hasInstrumentLabel) |
|
409 |
self.hasInstrumentLabelCheckBox = QtWidgets.QCheckBox(self.scrollAreaWidgetContents) |
|
410 |
self.hasInstrumentLabelCheckBox.setText("") |
|
411 |
self.hasInstrumentLabelCheckBox.setObjectName("hasInstrumentLabelCheckBox") |
|
412 |
self.formLayout.setWidget(15, QtWidgets.QFormLayout.FieldRole, self.hasInstrumentLabelCheckBox) |
|
413 |
self.gridLayout_4.addLayout(self.formLayout, 0, 0, 1, 1) |
|
401 | 414 |
self.scrollArea.setWidget(self.scrollAreaWidgetContents) |
402 | 415 |
self.verticalLayout.addWidget(self.scrollArea) |
416 |
self.buttonBox = QtWidgets.QDialogButtonBox(self.widget) |
|
417 |
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Close|QtWidgets.QDialogButtonBox.Save) |
|
418 |
self.buttonBox.setObjectName("buttonBox") |
|
419 |
self.verticalLayout.addWidget(self.buttonBox) |
|
403 | 420 |
self.gridLayout_2.addLayout(self.verticalLayout, 0, 0, 1, 1) |
404 | 421 |
self.gridLayout_3.addWidget(self.splitter, 0, 0, 1, 1) |
405 | 422 | |
... | ... | |
426 | 443 |
self.flipHorizontalButton.setText(_translate("Dialog", "Flip Horizontal")) |
427 | 444 |
self.guidelineCheckbox.setText(_translate("Dialog", "Show Guideline")) |
428 | 445 |
self.initZoomButton.setText(_translate("Dialog", "Init Zoom")) |
446 |
self.idLabel.setText(_translate("Dialog", "ID")) |
|
429 | 447 |
self.nameLabel.setText(_translate("Dialog", "심볼명")) |
430 | 448 |
self.thresholdLabel.setText(_translate("Dialog", "임계값(%)")) |
431 | 449 |
self.minMatchPointLabel.setText(_translate("Dialog", "최소 특징점 개수")) |
... | ... | |
439 | 457 |
self.addOriginalPointButton.setText(_translate("Dialog", "추가")) |
440 | 458 |
self.connectionPointLabel.setText(_translate("Dialog", "Connection Point")) |
441 | 459 |
self.addConnectionPointButton.setText(_translate("Dialog", "추가")) |
442 |
self.hasInstrumentLabel.setText(_translate("Dialog", "Ins\'t 라벨 포함 여부")) |
|
443 | 460 |
self.isExceptDetectLabel.setText(_translate("Dialog", "검출 미포함 여부")) |
444 | 461 |
self.immediateInsertLabel.setText(_translate("Dialog", "즉시 삽입 여부\n" |
445 | 462 |
"(심볼 생성 시)")) |
463 |
self.hasInstrumentLabel.setText(_translate("Dialog", "Ins\'t 라벨 포함 여부")) |
|
446 | 464 | |
447 | 465 | |
448 | 466 |
if __name__ == "__main__": |
DTI_PID/DTI_PID/UI/SymbolEditor.ui | ||
---|---|---|
346 | 346 |
<rect> |
347 | 347 |
<x>0</x> |
348 | 348 |
<y>0</y> |
349 |
<width>401</width>
|
|
350 |
<height>680</height>
|
|
349 |
<width>409</width>
|
|
350 |
<height>651</height>
|
|
351 | 351 |
</rect> |
352 | 352 |
</property> |
353 | 353 |
<property name="minimumSize"> |
... | ... | |
362 | 362 |
<height>16777215</height> |
363 | 363 |
</size> |
364 | 364 |
</property> |
365 |
<layout class="QFormLayout" name="formLayout">
|
|
365 |
<layout class="QGridLayout" name="gridLayout_4">
|
|
366 | 366 |
<item row="0" column="0"> |
367 |
<widget class="QLabel" name="nameLabel"> |
|
368 |
<property name="font"> |
|
369 |
<font> |
|
370 |
<weight>75</weight> |
|
371 |
<bold>true</bold> |
|
372 |
</font> |
|
367 |
<layout class="QFormLayout" name="formLayout"> |
|
368 |
<property name="sizeConstraint"> |
|
369 |
<enum>QLayout::SetDefaultConstraint</enum> |
|
373 | 370 |
</property> |
374 |
<property name="text">
|
|
375 |
<string>심볼명</string>
|
|
371 |
<property name="fieldGrowthPolicy">
|
|
372 |
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
|
376 | 373 |
</property> |
377 |
</widget> |
|
378 |
</item> |
|
379 |
<item row="0" column="1"> |
|
380 |
<widget class="QLineEdit" name="nameLineEdit"/> |
|
381 |
</item> |
|
382 |
<item row="1" column="0"> |
|
383 |
<widget class="QLabel" name="thresholdLabel"> |
|
384 |
<property name="font"> |
|
385 |
<font> |
|
386 |
<weight>75</weight> |
|
387 |
<bold>true</bold> |
|
388 |
</font> |
|
389 |
</property> |
|
390 |
<property name="text"> |
|
391 |
<string>임계값(%)</string> |
|
392 |
</property> |
|
393 |
</widget> |
|
394 |
</item> |
|
395 |
<item row="1" column="1"> |
|
396 |
<widget class="QLineEdit" name="thresholdLineEdit"/> |
|
397 |
</item> |
|
398 |
<item row="2" column="0"> |
|
399 |
<widget class="QLabel" name="minMatchPointLabel"> |
|
400 |
<property name="font"> |
|
401 |
<font> |
|
402 |
<weight>75</weight> |
|
403 |
<bold>true</bold> |
|
404 |
</font> |
|
405 |
</property> |
|
406 |
<property name="text"> |
|
407 |
<string>최소 특징점 개수</string> |
|
408 |
</property> |
|
409 |
</widget> |
|
410 |
</item> |
|
411 |
<item row="2" column="1"> |
|
412 |
<widget class="QLineEdit" name="minMatchPointLineEdit"/> |
|
413 |
</item> |
|
414 |
<item row="3" column="0"> |
|
415 |
<widget class="QLabel" name="rotationCountLabel"> |
|
416 |
<property name="font"> |
|
417 |
<font> |
|
418 |
<weight>75</weight> |
|
419 |
<bold>true</bold> |
|
420 |
</font> |
|
421 |
</property> |
|
422 |
<property name="text"> |
|
423 |
<string>검출 시 심볼 회전수</string> |
|
424 |
</property> |
|
425 |
</widget> |
|
426 |
</item> |
|
427 |
<item row="3" column="1"> |
|
428 |
<widget class="QSpinBox" name="rotationCountSpinBox"> |
|
429 |
<property name="minimum"> |
|
430 |
<number>0</number> |
|
431 |
</property> |
|
432 |
<property name="maximum"> |
|
433 |
<number>3</number> |
|
434 |
</property> |
|
435 |
<property name="value"> |
|
436 |
<number>0</number> |
|
437 |
</property> |
|
438 |
</widget> |
|
439 |
</item> |
|
440 |
<item row="4" column="0"> |
|
441 |
<widget class="QLabel" name="isContainChildLabel"> |
|
442 |
<property name="font"> |
|
443 |
<font> |
|
444 |
<weight>75</weight> |
|
445 |
<bold>true</bold> |
|
446 |
</font> |
|
447 |
</property> |
|
448 |
<property name="text"> |
|
449 |
<string>자식 심볼 포함 여부</string> |
|
450 |
</property> |
|
451 |
</widget> |
|
452 |
</item> |
|
453 |
<item row="4" column="1"> |
|
454 |
<widget class="QCheckBox" name="isContainChildCheckBox"> |
|
455 |
<property name="text"> |
|
456 |
<string/> |
|
457 |
</property> |
|
458 |
<property name="checkable"> |
|
459 |
<bool>true</bool> |
|
460 |
</property> |
|
461 |
</widget> |
|
462 |
</item> |
|
463 |
<item row="5" column="0"> |
|
464 |
<widget class="QLabel" name="typeLabel"> |
|
465 |
<property name="font"> |
|
466 |
<font> |
|
467 |
<weight>75</weight> |
|
468 |
<bold>true</bold> |
|
469 |
</font> |
|
374 |
<property name="labelAlignment"> |
|
375 |
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> |
|
470 | 376 |
</property> |
471 |
<property name="text">
|
|
472 |
<string>심볼 타입</string>
|
|
377 |
<property name="formAlignment">
|
|
378 |
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
|
473 | 379 |
</property> |
474 |
</widget> |
|
475 |
</item> |
|
476 |
<item row="5" column="1"> |
|
477 |
<widget class="QComboBox" name="typeComboBox"/> |
|
478 |
</item> |
|
479 |
<item row="6" column="0"> |
|
480 |
<widget class="QLabel" name="baseSymbolLabel"> |
|
481 |
<property name="font"> |
|
482 |
<font> |
|
483 |
<weight>75</weight> |
|
484 |
<bold>true</bold> |
|
485 |
</font> |
|
380 |
<property name="leftMargin"> |
|
381 |
<number>6</number> |
|
486 | 382 |
</property> |
487 |
<property name="text">
|
|
488 |
<string>기초 심볼</string>
|
|
383 |
<property name="topMargin">
|
|
384 |
<number>6</number>
|
|
489 | 385 |
</property> |
490 |
</widget> |
|
491 |
</item> |
|
492 |
<item row="6" column="1"> |
|
493 |
<widget class="QComboBox" name="baseSymbolComboBox"/> |
|
494 |
</item> |
|
495 |
<item row="7" column="0"> |
|
496 |
<widget class="QLabel" name="additionalSymbolLabel"> |
|
497 |
<property name="font"> |
|
498 |
<font> |
|
499 |
<weight>75</weight> |
|
500 |
<bold>true</bold> |
|
501 |
</font> |
|
386 |
<property name="rightMargin"> |
|
387 |
<number>6</number> |
|
502 | 388 |
</property> |
503 |
<property name="text">
|
|
504 |
<string>부가 심볼</string>
|
|
389 |
<property name="bottomMargin">
|
|
390 |
<number>6</number>
|
|
505 | 391 |
</property> |
506 |
</widget> |
|
507 |
</item> |
|
508 |
<item row="7" column="1"> |
|
509 |
<layout class="QHBoxLayout" name="horizontalLayout_2"> |
|
510 |
<item> |
|
511 |
<widget class="QComboBox" name="defaultSymbolDirectionComboBox"> |
|
512 |
<property name="maximumSize"> |
|
513 |
<size> |
|
514 |
<width>50</width> |
|
515 |
<height>16777215</height> |
|
516 |
</size> |
|
392 |
<item row="0" column="0"> |
|
393 |
<widget class="QLabel" name="idLabel"> |
|
394 |
<property name="font"> |
|
395 |
<font> |
|
396 |
<weight>75</weight> |
|
397 |
<bold>true</bold> |
|
398 |
</font> |
|
399 |
</property> |
|
400 |
<property name="text"> |
|
401 |
<string>ID</string> |
|
517 | 402 |
</property> |
518 | 403 |
</widget> |
519 | 404 |
</item> |
520 |
<item> |
|
521 |
<widget class="QComboBox" name="additionalSymbolComboBox"/>
|
|
405 |
<item row="0" column="1">
|
|
406 |
<widget class="QLineEdit" name="idLineEdit"/>
|
|
522 | 407 |
</item> |
523 |
<item> |
|
524 |
<widget class="QPushButton" name="addAdditionalSymbolButton">
|
|
525 |
<property name="maximumSize">
|
|
526 |
<size>
|
|
527 |
<width>40</width>
|
|
528 |
<height>16777215</height>
|
|
529 |
</size>
|
|
408 |
<item row="1" column="0">
|
|
409 |
<widget class="QLabel" name="nameLabel">
|
|
410 |
<property name="font">
|
|
411 |
<font>
|
|
412 |
<weight>75</weight>
|
|
413 |
<bold>true</bold>
|
|
414 |
</font>
|
|
530 | 415 |
</property> |
531 | 416 |
<property name="text"> |
532 |
<string>추가</string>
|
|
417 |
<string>심볼명</string>
|
|
533 | 418 |
</property> |
534 | 419 |
</widget> |
535 | 420 |
</item> |
536 |
</layout> |
|
537 |
</item> |
|
538 |
<item row="8" column="1"> |
|
539 |
<widget class="QListWidget" name="additionalSymbolListWidget"/> |
|
540 |
</item> |
|
541 |
<item row="9" column="0"> |
|
542 |
<widget class="QLabel" name="originalPointLabel"> |
|
543 |
<property name="sizePolicy"> |
|
544 |
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> |
|
545 |
<horstretch>0</horstretch> |
|
546 |
<verstretch>0</verstretch> |
|
547 |
</sizepolicy> |
|
548 |
</property> |
|
549 |
<property name="font"> |
|
550 |
<font> |
|
551 |
<weight>75</weight> |
|
552 |
<bold>true</bold> |
|
553 |
</font> |
|
554 |
</property> |
|
555 |
<property name="text"> |
|
556 |
<string>Original Point</string> |
내보내기 Unified diff