개정판 9aaebab3
issue #366: flip detection on going
Change-Id: I665d6497daaf0723f39aa91e5d909a7d3ef7a2c6
DTI_PID/DTI_PID/MainWindow.py | ||
---|---|---|
1616 | 1616 |
name = symbol.getName() |
1617 | 1617 |
angle = round(math.radians(symbol.getRotatedAngle()), 2) |
1618 | 1618 |
_type = symbol.getType() |
1619 |
flip = symbol.getDetectFlip() |
|
1619 | 1620 |
origin = [0,0] |
1620 | 1621 |
if 2 == len(symbol.getOriginalPoint().split(',')): |
1621 | 1622 |
tokens = symbol.getOriginalPoint().split(',') |
... | ... | |
1634 | 1635 | |
1635 | 1636 |
svgFilePath = os.path.join(project.getSvgFilePath(), _type, name + '.svg') |
1636 | 1637 |
if os.path.isfile(svgFilePath): |
1637 |
svg = SymbolSvgItem.createItem(_type, svgFilePath) |
|
1638 |
svg.buildItem(name, _type, angle, pt, size, origin, connPts, parentSymbol, childSymbol, hasInstrumentLabel) |
|
1638 |
svg = SymbolSvgItem.createItem(_type, svgFilePath, flip=flip) |
|
1639 |
#print(pt) |
|
1640 |
#print(origin) |
|
1641 |
svg.buildItem(name, _type, angle, pt, size, origin, connPts, parentSymbol, childSymbol, hasInstrumentLabel, flip=flip) |
|
1639 | 1642 |
svg.reCalculationRotatedItem() |
1640 | 1643 |
svg.area = 'Drawing' |
1641 | 1644 |
DTI_PID/DTI_PID/RecognitionDialog.py | ||
---|---|---|
305 | 305 |
## up to here |
306 | 306 |
|
307 | 307 |
pool = futures.ThreadPoolExecutor(max_workers = THREAD_MAX_WORKER) |
308 | ||
308 | 309 |
for sym in searchedSymbolList: |
309 | 310 |
pool.submit(Worker.removeDetectedSymbol, sym, appDocData.imgSrc) |
310 | 311 |
pool.shutdown(wait = True) |
... | ... | |
363 | 364 |
|
364 | 365 |
listWidget.addItem(worker.tr('Creating detected infos...')) |
365 | 366 |
worker.displayTitle.emit(worker.tr('Creating detected infos...')) |
367 |
#print(searchedSymbolList[0].getDetectFlip()) |
|
368 |
#print(searchedSymbolList[1].getDetectFlip()) |
|
366 | 369 |
createDetectedItems(searchedSymbolList, textInfoList, otherTextInfoList if otherTextInfoList is not None else [], titleBlockTextInfoList if titleBlockTextInfoList is not None else []) |
367 | 370 | |
368 | 371 |
if isLineChecked: |
... | ... | |
550 | 553 |
''' |
551 | 554 |
@staticmethod |
552 | 555 |
def detectSymbolOnPid(mainRes, targetSymbol, listWidget, worker): |
556 |
import copy |
|
553 | 557 |
global ocrCompletedSrc |
554 | 558 |
global threadLock |
555 | 559 |
global maxProgressValue |
... | ... | |
569 | 573 |
baseSymbol = targetSymbol.getBaseSymbol() |
570 | 574 |
additionalSymbol = targetSymbol.getAdditionalSymbol() |
571 | 575 |
isExceptDetect = targetSymbol.getIsExceptDetect() |
572 |
detectFlip = targetSymbol.getDetectFlip() |
|
576 |
detectFlip = 1#targetSymbol.getDetectFlip()
|
|
573 | 577 |
|
574 | 578 |
# check if symbol file is target or not |
575 | 579 |
if isExceptDetect == 1: |
... | ... | |
590 | 594 |
|
591 | 595 |
sym = cv2.imread(symbolPath, 1) |
592 | 596 |
symGray = Worker.cvtGrayImage(sym) |
597 |
symGrayOri = copy.copy(symGray) |
|
593 | 598 |
## TODO: 이진화 시켰을때 심볼이 검출되지 않음 |
594 | 599 |
## symGray = cv2.threshold(cvtGrayImage(sym), 127, 255, cv2.THRESH_BINARY)[1] |
595 | 600 |
## cv2.imshow('symbol', symGray) |
... | ... | |
624 | 629 |
continue |
625 | 630 |
else: |
626 | 631 |
pass |
632 |
symGray = symGrayOri |
|
627 | 633 |
symGray = cv2.flip(symGray, 1) |
634 |
#cv2.imwrite('out.png', symGray) |
|
628 | 635 |
opx = sow - float(symbolOriginalPoint.split(',')[0]) |
629 |
opy = soh - float(symbolOriginalPoint.split(',')[1])
|
|
636 |
opy = float(symbolOriginalPoint.split(',')[1]) |
|
630 | 637 |
symbolOriginalPoint = str(opx) + ',' + str(opy) |
631 | 638 | |
632 | 639 |
symbolConnectionPoint = symbolConnectionPoint.split("/") |
... | ... | |
638 | 645 |
symbol_idx = '0' |
639 | 646 |
if len(tokens) == 2: |
640 | 647 |
cpx = sow - float(tokens[0]) |
641 |
cpy = soh - float(tokens[1])
|
|
648 |
cpy = float(tokens[1]) |
|
642 | 649 |
cflip = direction + ',' + str(cpx) + ',' + str(cpy) |
643 | 650 |
elif len(tokens) == 3: |
644 | 651 |
direction = tokens[0] |
645 | 652 |
cpx = sow - float(tokens[1]) |
646 |
cpy = soh - float(tokens[2])
|
|
653 |
cpy = float(tokens[2]) |
|
647 | 654 |
cflip = direction + ',' + str(cpx) + ',' + str(cpy) |
648 | 655 |
elif len(tokens) == 4: |
649 | 656 |
direction = tokens[0] |
650 | 657 |
cpx = sow - float(tokens[1]) |
651 |
cpy = soh - float(tokens[2])
|
|
658 |
cpy = float(tokens[2]) |
|
652 | 659 |
symbol_idx = tokens[3] |
653 | 660 |
cflip = direction + ',' + str(cpx) + ',' + str(cpy) + ',' + str(symbol_idx) |
654 | 661 | |
... | ... | |
694 | 701 |
continue |
695 | 702 |
|
696 | 703 |
searchedItemSp = (roiItemSp[0]+pt[0] + round(offsetDrawingArea[0]), roiItemSp[1]+pt[1] + round(offsetDrawingArea[1])) |
704 |
#print(searchedItemSp) |
|
697 | 705 |
|
698 | 706 |
overlapArea = 0 |
699 | 707 |
symbolIndex = -1 |
... | ... | |
719 | 727 |
Worker.addSearchedSymbol(symbolName, symbolType , |
720 | 728 |
searchedItemSp, sw, sh, symbolThreshold, symbolMinMatchCount, hitRate, symbolRotatedAngle , |
721 | 729 |
isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild , |
722 |
originalPoint, connectionPoint, baseSymbol, additionalSymbol,isExceptDetect) |
|
730 |
originalPoint, connectionPoint, baseSymbol, additionalSymbol,isExceptDetect, detectFlip=1 if index is 1 else 0)
|
|
723 | 731 |
threadLock.release() |
724 | 732 |
else: ## 겹치는 영역이 기준값보다 클 경우 |
725 | 733 |
if symbolIndex != -1 and symbolIndex < len(searchedSymbolList): |
... | ... | |
734 | 742 |
isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild , |
735 | 743 |
','.join(str(x) for x in originalPoint), |
736 | 744 |
'/'.join('{},{},{},{}'.format(param[0], param[1], param[2], param[3]) for param in connectionPoint), |
737 |
baseSymbol, additionalSymbol,isExceptDetect) |
|
745 |
baseSymbol, additionalSymbol,isExceptDetect, detectFlip=1 if index is 1 else 0)
|
|
738 | 746 |
threadLock.release() |
739 | 747 |
## 현재 심볼과 검출된 심볼이 같지 않을 경우 (포함) |
740 | 748 |
elif appDocData.isEquipmentType(searchedSymbol.getType()): |
... | ... | |
756 | 764 |
isDetectOnOrigin, symbolRotateCount, symbolOcrOption, isContainChild , |
757 | 765 |
','.join(str(x) for x in originalPoint), |
758 | 766 |
'/'.join('{},{},{},{}'.format(param[0], param[1], param[2], param[3]) for param in connectionPoint), |
759 |
baseSymbol, additionalSymbol,isExceptDetect) |
|
767 |
baseSymbol, additionalSymbol,isExceptDetect, detectFlip=1 if index is 1 else 0)
|
|
760 | 768 |
threadLock.release() |
761 | 769 | |
762 | 770 |
## Rotate Symbol |
... | ... | |
1063 | 1071 |
def addSearchedSymbol(sName, sType |
1064 | 1072 |
, sp, w, h, threshold, minMatchCount, hitRate, rotatedAngle |
1065 | 1073 |
, isDetectOnOrigin, rotateCount, ocrOption, isContainChild |
1066 |
, originalPoint, connectionPoint, baseSymbol, additionalSymbol, isExceptDetect): |
|
1074 |
, originalPoint, connectionPoint, baseSymbol, additionalSymbol, isExceptDetect, detectFlip):
|
|
1067 | 1075 |
global searchedSymbolList |
1068 | 1076 | |
1069 | 1077 |
newSym = None |
... | ... | |
1073 | 1081 |
isDetectOnOrigin, rotateCount, ocrOption, isContainChild , |
1074 | 1082 |
','.join(str(x) for x in originalPoint), |
1075 | 1083 |
'/'.join('{},{},{},{}'.format(param[0], param[1], param[2], param[3]) for param in connectionPoint), |
1076 |
baseSymbol, additionalSymbol, isExceptDetect) |
|
1084 |
baseSymbol, additionalSymbol, isExceptDetect, detectFlip=detectFlip)
|
|
1077 | 1085 |
|
1078 | 1086 |
searchedSymbolList.append(newSym) |
1079 | 1087 |
except Exception as ex: |
... | ... | |
1266 | 1274 |
#symbolId = symbol.getId() |
1267 | 1275 |
symbolPath = symbol.getPath() |
1268 | 1276 |
symbolSp = symbol.getSp() |
1269 |
symbolWidth = symbol.getWidth() |
|
1270 |
symbolHeight = symbol.getHeight() |
|
1271 | 1277 |
symbolRotatedAngle = symbol.getRotatedAngle() |
1272 |
symbolOcrOption = symbol.getOcrOption() |
|
1273 |
|
|
1278 | ||
1274 | 1279 |
symImg = cv2.cvtColor(cv2.imread(symbolPath, 1), cv2.COLOR_BGR2GRAY) |
1280 |
if symbol.getDetectFlip() is 1: |
|
1281 |
symImg = cv2.flip(symImg, 1) |
|
1275 | 1282 |
for i in range(symbolRotatedAngle//90): |
1276 | 1283 |
symImg = cv2.rotate(symImg, cv2.ROTATE_90_COUNTERCLOCKWISE) |
1277 | 1284 |
|
... | ... | |
1294 | 1301 |
angle = sym.getRotatedAngle() |
1295 | 1302 |
symImg = cv2.imread(path) |
1296 | 1303 |
symImg = cv2.threshold(Worker.cvtGrayImage(symImg), 127, 255, cv2.THRESH_BINARY)[1] |
1297 |
|
|
1304 |
if sym.getDetectFlip() is 1: |
|
1305 |
symImg = cv2.flip(symImg, 1) |
|
1306 | ||
1298 | 1307 |
for i in range(angle//90): |
1299 | 1308 |
symImg = cv2.rotate(symImg, cv2.ROTATE_90_COUNTERCLOCKWISE) |
1300 | 1309 |
|
DTI_PID/DTI_PID/Shapes/SymbolSvgItem.py | ||
---|---|---|
27 | 27 |
18.05.25 Jeongwoo Call setColor() method |
28 | 28 |
18.05.30 Jeongwoo Add self variables (parentSymbol, childSymbol) |
29 | 29 |
''' |
30 |
def __init__(self, path, uid=None): |
|
30 |
def __init__(self, path, uid=None, flip=None):
|
|
31 | 31 |
import uuid |
32 | 32 | |
33 | 33 |
QGraphicsSvgItem.__init__(self) |
... | ... | |
46 | 46 |
self.parentSymbol = '' |
47 | 47 |
self.childSymbol = '' |
48 | 48 |
self.hasInstrumentLabel = 0 |
49 |
self.flip = flip |
|
49 | 50 |
# attributeType uid |
50 | 51 |
self.attribute = '' |
51 | 52 |
|
... | ... | |
58 | 59 |
self.transfer = Transfer() |
59 | 60 | |
60 | 61 |
try: |
62 |
#print(self.flip) |
|
63 |
#if self.flip is 1: |
|
64 |
# path = path.replace('.svg', '_Flip.svg') |
|
61 | 65 |
f = QFile(path) |
62 | 66 |
f.open(QIODevice.ReadOnly) |
63 | 67 |
array = f.readAll() |
... | ... | |
187 | 191 |
@history 2018.05.09 Jeongwoo Clear self.connectors |
188 | 192 |
2018.05.30 Jeongwoo Add parameters (parentSymbol, childSymbol) |
189 | 193 |
''' |
190 |
def buildItem(self, name, type, angle, loc, size, origin, connPts, parentSymbol, childSymbol, hasInstrumentLabel): |
|
194 |
def buildItem(self, name, type, angle, loc, size, origin, connPts, parentSymbol, childSymbol, hasInstrumentLabel, flip=None):
|
|
191 | 195 |
try: |
192 | 196 |
docData = AppDocData.instance() |
193 | 197 |
self.name = name |
... | ... | |
198 | 202 |
self.origin = origin |
199 | 203 |
symbolInfo = docData.getSymbolByQuery('name', name) |
200 | 204 |
originalPoint = symbolInfo.getOriginalPoint().split(',') |
201 |
self.symbolOrigin = (float(originalPoint[0]), float(originalPoint[1])) |
|
205 |
self.symbolOrigin = [float(originalPoint[0]), float(originalPoint[1])] |
|
206 |
if flip is 1: |
|
207 |
self.symbolOrigin[0] = self.size[0] - self.symbolOrigin[0] |
|
202 | 208 | |
203 | 209 |
# setting connectors |
204 | 210 |
connectionPoints = symbolInfo.getConnectionPoint().split('/') |
... | ... | |
948 | 954 |
humkyung 2018.07.19 create nozzle instance if type is 'Nozzles' |
949 | 955 |
''' |
950 | 956 |
@staticmethod |
951 |
def createItem(type, path, uid=None): |
|
957 |
def createItem(type, path, uid=None, flip=None):
|
|
952 | 958 |
from QEngineeringOPCItem import QEngineeringOPCItem |
953 | 959 |
from EngineeringEquipmentItem import QEngineeringEquipmentItem |
954 | 960 |
from EngineeringInstrumentItem import QEngineeringInstrumentItem |
... | ... | |
974 | 980 |
elif type == 'Error': |
975 | 981 |
item = QEngineeringErrorItem(path, uid) |
976 | 982 |
else: |
977 |
item = SymbolSvgItem(path, uid) |
|
983 |
item = SymbolSvgItem(path, uid, flip=flip)
|
|
978 | 984 | |
979 | 985 |
return item |
980 | 986 | |
... | ... | |
1122 | 1128 |
''' |
1123 | 1129 |
def addSvgItemToScene(self, scene): |
1124 | 1130 |
transform = QTransform() |
1131 |
#print(self.symbolOrigin) |
|
1132 |
|
|
1125 | 1133 |
transform.translate(self.loc[0] + self.symbolOrigin[0], self.loc[1] + self.symbolOrigin[1]) |
1126 | 1134 |
transform.rotateRadians(-self.angle) |
1127 | 1135 |
currentPoint = self.getCurrentPoint() |
1128 | 1136 |
transform.translate(-currentPoint[0], -currentPoint[1]) |
1129 | 1137 | |
1138 |
if self.flip is 1: |
|
1139 |
transform.scale(-1.0, 1.0) |
|
1140 |
transform.translate(-self.size[0], 0) |
|
1141 | ||
1130 | 1142 |
self.setTransform(transform) |
1131 | 1143 |
scene.addItem(self) |
1132 | 1144 |
DTI_PID/DTI_PID/SymbolBase.py | ||
---|---|---|
6 | 6 |
def __init__(self, sName, sType, threshold = None, minMatchCount = 0 |
7 | 7 |
, isDetectOnOrigin = False, rotationCount = 4, ocrOption = OCR_OPTION_NOT_EXEC, isContainChild = 0 |
8 | 8 |
, originalPoint = None, connectionPoint = None, baseSymbol = None, additionalSymbol = None |
9 |
, isExceptDetect = 0, hasInstrumentLabel = 0, uid = None, width = None, height = None): |
|
9 |
, isExceptDetect = 0, hasInstrumentLabel = 0, uid = None, width = None, height = None, detectFlip = None):
|
|
10 | 10 |
self.uid = uid ## Auto increased Unique Id |
11 | 11 |
self.sName = sName |
12 | 12 |
self.sType = sType |
... | ... | |
22 | 22 |
self.additionalSymbol = additionalSymbol |
23 | 23 |
self.isExceptDetect = isExceptDetect |
24 | 24 |
self.hasInstrumentLabel = hasInstrumentLabel |
25 |
#self.detectFlip = detectFlip |
|
26 |
self.detectFlip = 1 |
|
25 |
self.detectFlip = detectFlip |
|
27 | 26 |
self._owner = None |
28 | 27 |
self.width = width |
29 | 28 |
self.height = height |
DTI_PID/DTI_PID/SymbolEditorDialog.py | ||
---|---|---|
440 | 440 |
if isSuccess: |
441 | 441 |
try: |
442 | 442 |
image = self.ui.imageView.image() |
443 |
#imageFlip = self.ui.imageView.image().mirrored(horizontal = True, vertical = False) |
|
443 | 444 |
if image is not None: |
444 | 445 |
if self.selectedSymbol is not None: |
445 | 446 |
self.deleteImageAndSvg(self.selectedSymbol.getImageFileFullPath(), self.selectedSymbol.getSvgFileFullPath()) |
... | ... | |
448 | 449 |
os.makedirs(imageLocation) |
449 | 450 |
|
450 | 451 |
image.save(imagePath, 'PNG') |
452 |
#if self.ui.makeFlipCheckBox.isChecked(): |
|
453 |
# imageFlip.save(imagePath + '_Flip', 'PNG') |
|
451 | 454 | |
452 | 455 |
svgLocation = os.path.join(self.project.getSvgFilePath(), fileType) |
453 | 456 |
if not os.path.exists(svgLocation): |
... | ... | |
456 | 459 |
normal_color = self.ui.comboBoxNormalColor.itemData(self.ui.comboBoxNormalColor.currentIndex()) |
457 | 460 |
hover_color = self.ui.comboBoxHoverColor.itemData(self.ui.comboBoxHoverColor.currentIndex()) |
458 | 461 |
potrace.convertImageToSvg(imagePath, os.path.join(svgLocation + "/" + fileName + ".svg"), normalColor=normal_color, hoverColor=hover_color) |
462 |
#if self.ui.makeFlipCheckBox.isChecked(): |
|
463 |
# potrace.convertImageToSvg(imagePath + '_Flip', os.path.join(svgLocation + "/" + fileName + "_Flip.svg"), normalColor=normal_color, hoverColor=hover_color) |
|
459 | 464 |
self.isAccepted = True |
460 | 465 |
QDialog.accept(self) |
461 | 466 |
except: |
DTI_PID/DTI_PID/symbol.py | ||
---|---|---|
12 | 12 |
class Symbol(SymbolBase): |
13 | 13 |
def __init__(self, sName, sType, sp, width, height, threshold, minMatchCount, hitRate, rotatedAngle |
14 | 14 |
, isDetectOnOrigin, rotationCount, ocrOption, isContainChild = 0 |
15 |
, originalPoint = None, connectionPoint = None, baseSymbol = None, additionalSymbol = None, isExceptDetect = 0, hasInstrumentLabel = 0, uid = None): |
|
15 |
, originalPoint = None, connectionPoint = None, baseSymbol = None, additionalSymbol = None, isExceptDetect = 0, hasInstrumentLabel = 0, uid = None, detectFlip = None):
|
|
16 | 16 |
SymbolBase.__init__(self, sName, sType, threshold, minMatchCount |
17 | 17 |
, isDetectOnOrigin, rotationCount, ocrOption, isContainChild |
18 |
, originalPoint, connectionPoint, baseSymbol, additionalSymbol, isExceptDetect, hasInstrumentLabel, uid) |
|
18 |
, originalPoint, connectionPoint, baseSymbol, additionalSymbol, isExceptDetect, hasInstrumentLabel, uid, detectFlip=detectFlip)
|
|
19 | 19 |
self.sp = sp |
20 | 20 |
self.width = width |
21 | 21 |
self.height = height |
내보내기 Unified diff