112 |
112 |
if area > minArea and area < maxArea: selectedContours.append(contour)
|
113 |
113 |
contourImage = cv2.drawContours(image, selectedContours, -1, (255,255,255), -1); # draw contour with white color
|
114 |
114 |
except Exception as ex:
|
|
115 |
from App import App
|
|
116 |
|
115 |
117 |
message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
|
116 |
|
MainWindow.instance().displayMessage.emit(MessageType.Error, message)
|
|
118 |
App.mainWnd().addMessage.emit(MessageType.Error, message)
|
117 |
119 |
|
118 |
120 |
return contourImage
|
119 |
121 |
|
... | ... | |
166 |
168 |
# up to here
|
167 |
169 |
# up to here
|
168 |
170 |
except Exception as ex:
|
|
171 |
from App import App
|
|
172 |
|
169 |
173 |
message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
|
170 |
|
MainWindow.instance().displayMessage.emit(MessageType.Error, message)
|
|
174 |
App.mainWnd().addMessage.emit(MessageType.Error, message)
|
171 |
175 |
|
172 |
176 |
@staticmethod
|
173 |
177 |
def executeRecognition(createDetectedItems, path, listWidget, isLineChecked, worker, batch, createUnknownItems):
|
... | ... | |
565 |
569 |
baseSymbol = targetSymbol.getBaseSymbol()
|
566 |
570 |
additionalSymbol = targetSymbol.getAdditionalSymbol()
|
567 |
571 |
isExceptDetect = targetSymbol.getIsExceptDetect()
|
|
572 |
detectFlip = targetSymbol.getDetectFlip()
|
568 |
573 |
|
569 |
574 |
# check if symbol file is target or not
|
570 |
575 |
if isExceptDetect == 1:
|
... | ... | |
611 |
616 |
roiItemEp = (srcWidth, srcHeight)
|
612 |
617 |
roiItem = copiedBasePid
|
613 |
618 |
|
614 |
|
symbolRotatedAngle = 0
|
615 |
|
for rc in range(symbolRotateCount + 1): ## Rotation Count를 사용자 기준으로 받아서 1을 더한 후 사용
|
616 |
|
sw, sh = symGray.shape[::-1]
|
617 |
|
roiw = (roiItemEp[0] - roiItemSp[0])
|
618 |
|
roih = (roiItemEp[1] - roiItemSp[1])
|
619 |
|
|
620 |
|
## Case : Bigger Symbol than Split ROI
|
621 |
|
if roiw < sw or roih < sh:
|
622 |
|
symGray = cv2.rotate(symGray, cv2.ROTATE_90_COUNTERCLOCKWISE)
|
623 |
|
symbolRotatedAngle = symbolRotatedAngle + 90
|
624 |
|
|
625 |
|
if baseSymbol is not None and additionalSymbol is not None:
|
626 |
|
additionalSymbol = Worker.getRotatedChildInfo(additionalSymbol)
|
|
619 |
for index in range(2):
|
|
620 |
if index is 0:
|
|
621 |
#continue
|
|
622 |
pass
|
|
623 |
elif detectFlip is not 1 and index is 1:
|
627 |
624 |
continue
|
|
625 |
else:
|
|
626 |
pass
|
|
627 |
symGray = cv2.flip(symGray, 1)
|
|
628 |
opx = sow - float(symbolOriginalPoint.split(',')[0])
|
|
629 |
opy = soh - float(symbolOriginalPoint.split(',')[1])
|
|
630 |
symbolOriginalPoint = str(opx) + ',' + str(opy)
|
|
631 |
|
|
632 |
symbolConnectionPoint = symbolConnectionPoint.split("/")
|
|
633 |
symbolConnectionPointStr = ''
|
|
634 |
for strConnPt in symbolConnectionPoint:
|
|
635 |
tokens = strConnPt.split(',')
|
|
636 |
|
|
637 |
direction = 'AUTO'
|
|
638 |
symbol_idx = '0'
|
|
639 |
if len(tokens) == 2:
|
|
640 |
cpx = sow - float(tokens[0])
|
|
641 |
cpy = soh - float(tokens[1])
|
|
642 |
cflip = direction + ',' + str(cpx) + ',' + str(cpy)
|
|
643 |
elif len(tokens) == 3:
|
|
644 |
direction = tokens[0]
|
|
645 |
cpx = sow - float(tokens[1])
|
|
646 |
cpy = soh - float(tokens[2])
|
|
647 |
cflip = direction + ',' + str(cpx) + ',' + str(cpy)
|
|
648 |
elif len(tokens) == 4:
|
|
649 |
direction = tokens[0]
|
|
650 |
cpx = sow - float(tokens[1])
|
|
651 |
cpy = soh - float(tokens[2])
|
|
652 |
symbol_idx = tokens[3]
|
|
653 |
cflip = direction + ',' + str(cpx) + ',' + str(cpy) + ',' + str(symbol_idx)
|
|
654 |
|
|
655 |
if symbolConnectionPointStr == '':
|
|
656 |
symbolConnectionPointStr = cflip
|
|
657 |
else:
|
|
658 |
symbolConnectionPointStr = symbolConnectionPointStr + '/' + cflip
|
|
659 |
symbolConnectionPoint = symbolConnectionPointStr
|
|
660 |
|
|
661 |
#print(symbolOriginalPoint)
|
|
662 |
#print(symbolConnectionPoint)
|
|
663 |
symbolRotatedAngle = 0
|
|
664 |
for rc in range(symbolRotateCount + 1): ## Rotation Count를 사용자 기준으로 받아서 1을 더한 후 사용
|
|
665 |
sw, sh = symGray.shape[::-1]
|
|
666 |
roiw = (roiItemEp[0] - roiItemSp[0])
|
|
667 |
roih = (roiItemEp[1] - roiItemSp[1])
|
|
668 |
|
|
669 |
## Case : Bigger Symbol than Split ROI
|
|
670 |
if roiw < sw or roih < sh:
|
|
671 |
symGray = cv2.rotate(symGray, cv2.ROTATE_90_COUNTERCLOCKWISE)
|
|
672 |
symbolRotatedAngle = symbolRotatedAngle + 90
|
|
673 |
|
|
674 |
if baseSymbol is not None and additionalSymbol is not None:
|
|
675 |
additionalSymbol = Worker.getRotatedChildInfo(additionalSymbol)
|
|
676 |
continue
|
628 |
677 |
|
629 |
|
## get Rotated Original Point
|
630 |
|
originalPoint = Worker.getCalculatedOriginalPoint(additionalSymbol, symbolOriginalPoint, symbolRotatedAngle, sw, sh, sow, soh)
|
631 |
|
connectionPoint = Worker.getCalculatedConnectionPoint(symbolConnectionPoint, symbolRotatedAngle, sw, sh, sow, soh)
|
|
678 |
## get Rotated Original Point
|
|
679 |
originalPoint = Worker.getCalculatedOriginalPoint(additionalSymbol, symbolOriginalPoint, symbolRotatedAngle, sw, sh, sow, soh)
|
|
680 |
connectionPoint = Worker.getCalculatedConnectionPoint(symbolConnectionPoint, symbolRotatedAngle, sw, sh, sow, soh)
|
632 |
681 |
|
633 |
|
## Template Matching
|
634 |
|
tmRes = cv2.matchTemplate(roiItem, symGray, cv2.TM_CCOEFF_NORMED)
|
635 |
|
loc = np.where(tmRes >= symbolThreshold)
|
|
682 |
## Template Matching
|
|
683 |
tmRes = cv2.matchTemplate(roiItem, symGray, cv2.TM_CCOEFF_NORMED)
|
|
684 |
loc = np.where(tmRes >= symbolThreshold)
|
636 |
685 |
|
637 |
|
for pt in zip(*loc[::-1]):
|
638 |
|
mpCount = 0 # Match Point Count
|
|
686 |
for pt in zip(*loc[::-1]):
|
|
687 |
mpCount = 0 # Match Point Count
|
639 |
688 |
|
640 |
|
roi = roiItem[pt[1]:pt[1]+sh, pt[0]:pt[0]+sw]
|
|
689 |
roi = roiItem[pt[1]:pt[1]+sh, pt[0]:pt[0]+sw]
|
641 |
690 |
|
642 |
|
if symbolMinMatchCount > 0:
|
643 |
|
mpCount = Worker.getMatchPointCount(roi, symGray)
|
644 |
|
if not (mpCount >= symbolMinMatchCount):
|
645 |
|
continue
|
|
691 |
if symbolMinMatchCount > 0:
|
|
692 |
mpCount = Worker.getMatchPointCount(roi, symGray)
|
|
693 |
if not (mpCount >= symbolMinMatchCount):
|
|
694 |
continue
|
646 |
695 |
|
647 |
|
searchedItemSp = (roiItemSp[0]+pt[0] + round(offsetDrawingArea[0]), roiItemSp[1]+pt[1] + round(offsetDrawingArea[1]))
|
|
696 |
searchedItemSp = (roiItemSp[0]+pt[0] + round(offsetDrawingArea[0]), roiItemSp[1]+pt[1] + round(offsetDrawingArea[1]))
|
648 |
697 |
|
649 |
|
overlapArea = 0
|
650 |
|
symbolIndex = -1
|
651 |
|
for i in range(len(searchedSymbolList)):
|
652 |
|
area = Worker.contains(searchedSymbolList[i], searchedItemSp, sw, sh)
|
653 |
|
if area > ACCEPT_OVERLAY_AREA:
|
654 |
|
if area > overlapArea:
|
655 |
|
overlapArea = area
|
656 |
|
symbolIndex = i
|
657 |
|
"""
|
658 |
|
categories = [appDocData.isEquipmentType(symbolType), appDocData.isEquipmentType(searchedSymbolList[i].getType())]
|
659 |
|
if categories[0] == categories[1]:
|
660 |
|
symbolIndex = i
|
661 |
|
break
|
662 |
|
"""
|
|
698 |
overlapArea = 0
|
|
699 |
symbolIndex = -1
|
|
700 |
for i in range(len(searchedSymbolList)):
|
|
701 |
area = Worker.contains(searchedSymbolList[i], searchedItemSp, sw, sh)
|
|
702 |
if area > ACCEPT_OVERLAY_AREA:
|
|
703 |
if area > overlapArea:
|
|
704 |
overlapArea = area
|
|
705 |
symbolIndex = i
|
|
706 |
"""
|
|
707 |
categories = [appDocData.isEquipmentType(symbolType), appDocData.isEquipmentType(searchedSymbolList[i].getType())]
|
|
708 |
if categories[0] == categories[1]:
|
|
709 |
symbolIndex = i
|
|
710 |
break
|
|
711 |
"""
|
663 |
712 |
|
664 |
|
hitRate = tmRes[pt[1], pt[0]]
|
665 |
|
|
666 |
|
## 겹치는 영역이 기준값보다 작을 경우
|
667 |
|
if overlapArea <= ACCEPT_OVERLAY_AREA:
|
668 |
|
threadLock.acquire()
|
669 |
|
foundSymbolCount = foundSymbolCount + 1
|
670 |
|
Worker.addSearchedSymbol(symbolName, symbolType ,
|
671 |
|
searchedItemSp, sw, sh, symbolThreshold, symbolMinMatchCount, hitRate, symbolRotatedAngle ,
|
672 |
|
isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild ,
|
673 |
|
originalPoint, connectionPoint, baseSymbol, additionalSymbol,isExceptDetect)
|
674 |
|
threadLock.release()
|
675 |
|
else: ## 겹치는 영역이 기준값보다 클 경우
|
676 |
|
if symbolIndex != -1 and symbolIndex < len(searchedSymbolList):
|
677 |
|
searchedSymbol = searchedSymbolList[symbolIndex]
|
678 |
|
## 현재 심볼과 검출된 심볼이 같을 경우 Match Point가 더 높은 정보로 교체
|
679 |
|
if symbolName == searchedSymbol.getName():
|
680 |
|
symbolHitRate = searchedSymbol.getHitRate()
|
681 |
|
if symbolHitRate < hitRate:
|
682 |
|
threadLock.acquire()
|
683 |
|
searchedSymbolList[symbolIndex] = symbol.Symbol(symbolName, symbolType ,
|
684 |
|
searchedItemSp, sw, sh, symbolThreshold, symbolMinMatchCount, hitRate, symbolRotatedAngle ,
|
685 |
|
isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild ,
|
686 |
|
','.join(str(x) for x in originalPoint),
|
687 |
|
'/'.join('{},{},{},{}'.format(param[0], param[1], param[2], param[3]) for param in connectionPoint),
|
688 |
|
baseSymbol, additionalSymbol,isExceptDetect)
|
689 |
|
threadLock.release()
|
690 |
|
## 현재 심볼과 검출된 심볼이 같지 않을 경우 (포함)
|
691 |
|
elif appDocData.isEquipmentType(searchedSymbol.getType()):
|
692 |
|
if searchedSymbol.area > sw*sh*10: # searched equipment area is greather than 10 times of symbol's area
|
693 |
|
threadLock.acquire()
|
694 |
|
foundSymbolCount = foundSymbolCount + 1
|
695 |
|
Worker.addSearchedSymbol(symbolName, symbolType ,
|
696 |
|
searchedItemSp, sw, sh, symbolThreshold, hitRate, hitRate, symbolRotatedAngle ,
|
697 |
|
isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild ,
|
698 |
|
originalPoint, connectionPoint, baseSymbol, additionalSymbol,isExceptDetect)
|
699 |
|
threadLock.release()
|
700 |
|
else:
|
|
713 |
hitRate = tmRes[pt[1], pt[0]]
|
|
714 |
|
|
715 |
## 겹치는 영역이 기준값보다 작을 경우
|
|
716 |
if overlapArea <= ACCEPT_OVERLAY_AREA:
|
|
717 |
threadLock.acquire()
|
|
718 |
foundSymbolCount = foundSymbolCount + 1
|
|
719 |
Worker.addSearchedSymbol(symbolName, symbolType ,
|
|
720 |
searchedItemSp, sw, sh, symbolThreshold, symbolMinMatchCount, hitRate, symbolRotatedAngle ,
|
|
721 |
isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild ,
|
|
722 |
originalPoint, connectionPoint, baseSymbol, additionalSymbol,isExceptDetect)
|
|
723 |
threadLock.release()
|
|
724 |
else: ## 겹치는 영역이 기준값보다 클 경우
|
|
725 |
if symbolIndex != -1 and symbolIndex < len(searchedSymbolList):
|
701 |
726 |
searchedSymbol = searchedSymbolList[symbolIndex]
|
702 |
|
symbolHitRate = searchedSymbol.getHitRate()
|
703 |
|
if symbolHitRate - searchedSymbol.getThreshold() < hitRate - symbolThreshold:
|
704 |
|
threadLock.acquire()
|
705 |
|
searchedSymbolList[symbolIndex] = symbol.Symbol(symbolName, symbolType ,
|
706 |
|
searchedItemSp, sw, sh, symbolThreshold, symbolMinMatchCount, hitRate, symbolRotatedAngle ,
|
707 |
|
isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild ,
|
708 |
|
','.join(str(x) for x in originalPoint),
|
709 |
|
'/'.join('{},{},{},{}'.format(param[0], param[1], param[2], param[3]) for param in connectionPoint),
|
710 |
|
baseSymbol, additionalSymbol,isExceptDetect)
|
711 |
|
threadLock.release()
|
712 |
|
|
713 |
|
## Rotate Symbol
|
714 |
|
symGray = cv2.rotate(symGray, cv2.ROTATE_90_COUNTERCLOCKWISE)
|
715 |
|
symbolRotatedAngle = symbolRotatedAngle + 90
|
|
727 |
## 현재 심볼과 검출된 심볼이 같을 경우 Match Point가 더 높은 정보로 교체
|
|
728 |
if symbolName == searchedSymbol.getName():
|
|
729 |
symbolHitRate = searchedSymbol.getHitRate()
|
|
730 |
if symbolHitRate < hitRate:
|
|
731 |
threadLock.acquire()
|
|
732 |
searchedSymbolList[symbolIndex] = symbol.Symbol(symbolName, symbolType ,
|
|
733 |
searchedItemSp, sw, sh, symbolThreshold, symbolMinMatchCount, hitRate, symbolRotatedAngle ,
|
|
734 |
isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild ,
|
|
735 |
','.join(str(x) for x in originalPoint),
|
|
736 |
'/'.join('{},{},{},{}'.format(param[0], param[1], param[2], param[3]) for param in connectionPoint),
|
|
737 |
baseSymbol, additionalSymbol,isExceptDetect)
|
|
738 |
threadLock.release()
|
|
739 |
## 현재 심볼과 검출된 심볼이 같지 않을 경우 (포함)
|
|
740 |
elif appDocData.isEquipmentType(searchedSymbol.getType()):
|
|
741 |
if searchedSymbol.area > sw*sh*10: # searched equipment area is greather than 10 times of symbol's area
|
|
742 |
threadLock.acquire()
|
|
743 |
foundSymbolCount = foundSymbolCount + 1
|
|
744 |
Worker.addSearchedSymbol(symbolName, symbolType ,
|
|
745 |
searchedItemSp, sw, sh, symbolThreshold, hitRate, hitRate, symbolRotatedAngle ,
|
|
746 |
isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild ,
|
|
747 |
originalPoint, connectionPoint, baseSymbol, additionalSymbol,isExceptDetect)
|
|
748 |
threadLock.release()
|
|
749 |
else:
|
|
750 |
searchedSymbol = searchedSymbolList[symbolIndex]
|
|
751 |
symbolHitRate = searchedSymbol.getHitRate()
|
|
752 |
if symbolHitRate - searchedSymbol.getThreshold() < hitRate - symbolThreshold:
|
|
753 |
threadLock.acquire()
|
|
754 |
searchedSymbolList[symbolIndex] = symbol.Symbol(symbolName, symbolType ,
|
|
755 |
searchedItemSp, sw, sh, symbolThreshold, symbolMinMatchCount, hitRate, symbolRotatedAngle ,
|
|
756 |
isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild ,
|
|
757 |
','.join(str(x) for x in originalPoint),
|
|
758 |
'/'.join('{},{},{},{}'.format(param[0], param[1], param[2], param[3]) for param in connectionPoint),
|
|
759 |
baseSymbol, additionalSymbol,isExceptDetect)
|
|
760 |
threadLock.release()
|
|
761 |
|
|
762 |
## Rotate Symbol
|
|
763 |
symGray = cv2.rotate(symGray, cv2.ROTATE_90_COUNTERCLOCKWISE)
|
|
764 |
symbolRotatedAngle = symbolRotatedAngle + 90
|
716 |
765 |
|
717 |
|
if additionalSymbol is not None:
|
718 |
|
additionalSymbol = Worker.getRotatedChildInfo(additionalSymbol)
|
|
766 |
if additionalSymbol is not None:
|
|
767 |
additionalSymbol = Worker.getRotatedChildInfo(additionalSymbol)
|
719 |
768 |
|
720 |
769 |
threadLock.acquire()
|
721 |
770 |
listWidget.addItem('Found Symbol : ' + os.path.splitext(os.path.basename(symbolPath))[0] + ' - (' + str(foundSymbolCount) + ')')
|
... | ... | |
1313 |
1362 |
project = appDocData.getCurrentProject()
|
1314 |
1363 |
cv2.imwrite(os.path.join(project.getTempPath(), "DIFF_" + os.path.basename(orgImagePath)), imgDiff)
|
1315 |
1364 |
except Exception as ex:
|
|
1365 |
from App import App
|
|
1366 |
|
1316 |
1367 |
message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
|
1317 |
|
MainWindow.instance().displayMessage.emit(MessageType.Error, message)
|
|
1368 |
App.mainWnd().addMessage.emit(MessageType.Error, message)
|
1318 |
1369 |
|
1319 |
1370 |
|
1320 |
1371 |
'''
|