개정판 dacf55a0
issue #663: 노즐 인식 부분 수정
Change-Id: I89d1b870a73a6ae525a9a17009080202128dac72
DTI_PID/DTI_PID/AppDocData.py | ||
---|---|---|
594 | 594 |
self._symbolBase = {} |
595 | 595 |
return (isUpdated, symbol.getType(), symbol.getName(), symbol.getPath()) |
596 | 596 |
|
597 |
''' |
|
598 |
@brief Get Detecting Target Symbol List (Field 'isExceptDetect' == False(0)) |
|
599 |
@author Jeongwoo |
|
600 |
@date 18.04.24 |
|
601 |
@history humkyung 2018.06.28 select symbol order by threshold descending |
|
602 |
''' |
|
603 |
|
|
604 | 597 |
def getTargetSymbolList(self): |
598 |
"""get symbol list to be detected except isExceptDetect field is unset""" |
|
605 | 599 |
targetSymbolList = [] |
606 | 600 |
|
607 | 601 |
with self.project.database.connect() as conn: |
608 | 602 |
cursor = conn.cursor() |
609 |
sql = """SELECT a.UID,a.Name,b.Type,a.Threshold,a.MinMatchPoint,a.IsDetectOrigin,a.RotationCount,a.OCROption,a.IsContainChild,a.OriginalPoint,a.ConnectionPoint,
|
|
610 |
a.BaseSymbol,a.AdditionalSymbol,a.IsExceptDetect,a.HasInstrumentLabel,a.flip,a.TextArea,\
|
|
611 |
b.UID FROM Symbol a inner join SymbolType b on a.SymbolType_UID=b.UID WHERE
|
|
612 |
a.IsExceptDetect = 0 order by width * height desc"""
|
|
603 |
sql = """SELECT a.UID,a.Name,b.Type,a.Threshold,a.MinMatchPoint,a.IsDetectOrigin,a.RotationCount, |
|
604 |
a.OCROption,a.IsContainChild,a.OriginalPoint,a.ConnectionPoint,a.BaseSymbol,a.AdditionalSymbol,
|
|
605 |
a.IsExceptDetect,a.HasInstrumentLabel,a.flip,a.TextArea,b.UID FROM Symbol a inner join SymbolType b on
|
|
606 |
a.SymbolType_UID=b.UID WHERE a.IsExceptDetect = 0 order by width * height desc"""
|
|
613 | 607 |
try: |
614 | 608 |
cursor.execute(sql) |
615 | 609 |
rows = cursor.fetchall() |
DTI_PID/DTI_PID/RecognitionDialog.py | ||
---|---|---|
337 | 337 |
if worker.isSymbolChecked: |
338 | 338 |
worker.displayTitle.emit(worker.tr('Detecting symbols...')) |
339 | 339 |
|
340 |
# detect equipments |
|
341 |
pool = futures.ThreadPoolExecutor(max_workers=THREAD_MAX_WORKER)
|
|
342 |
for symbol in targetSymbolList[0]:
|
|
343 |
pool.submit(Worker.detectEquipmentOnPid, mainRes, symbol, listWidget, worker)
|
|
344 |
pool.shutdown(wait=True)
|
|
340 |
# detect only equipments
|
|
341 |
with futures.ThreadPoolExecutor(max_workers=THREAD_MAX_WORKER) as pool:
|
|
342 |
future_equipment = {pool.submit(Worker.detectSymbolsOnPid, mainRes, symbol, listWidget, worker):
|
|
343 |
symbol for symbol in targetSymbolList[0]}
|
|
344 |
futures.wait(future_equipment)
|
|
345 | 345 |
# up to here |
346 | 346 |
|
347 |
# detect normal symbols |
|
347 | 348 |
with futures.ThreadPoolExecutor(max_workers=THREAD_MAX_WORKER) as pool: |
348 | 349 |
future_symbol = {pool.submit(Worker.detectSymbolsOnPid, mainRes, symbol, listWidget, worker): |
349 | 350 |
symbol for symbol in targetSymbolList[2]} |
350 | 351 |
futures.wait(future_symbol) |
352 |
# up to here |
|
351 | 353 |
|
352 | 354 |
if worker.isTrainingChecked: |
353 | 355 |
import uuid |
... | ... | |
365 | 367 |
continue |
366 | 368 |
|
367 | 369 |
#cv2.imwrite('c:\\temp\\before-imgSrc.png', area.img) |
368 |
#pool = futures.ThreadPoolExecutor(max_workers=THREAD_MAX_WORKER) |
|
369 | 370 |
searchedTextSymList = [] |
370 | 371 |
for sym in searchedSymbolList: |
371 | 372 |
Worker.remove_detected_symbol_image(sym, app_doc_data.imgSrc) |
372 |
#pool.submit(Worker.remove_detected_symbol_image, sym, app_doc_data.imgSrc) |
|
373 |
#pool.shutdown(wait=True) |
|
374 |
#cv2.imwrite('c:\\temp\\imgSrc.png', area.img) |
|
375 | 373 |
else: |
376 | 374 |
''' |
377 | 375 |
import math |
... | ... | |
560 | 558 |
searchedSymbolList.pop(searchedSymbolList.index(searchedTextSymList[index])) |
561 | 559 |
|
562 | 560 |
pool = futures.ThreadPoolExecutor(max_workers=THREAD_MAX_WORKER) |
563 |
|
|
564 | 561 |
for sym in valid_sym: |
565 | 562 |
pool.submit(Worker.remove_detected_symbol_image, sym, app_doc_data.imgSrc) |
566 | 563 |
pool.shutdown(wait=True) |
567 | 564 |
# up to here |
568 | 565 |
|
569 | 566 |
# remove text from image |
570 |
Worker.drawFoundSymbolsOnCanvas(mainRes, textInfoList, listWidget) |
|
571 | 567 |
textDetector.remove_text_from_image(area.img, offset) |
572 | 568 |
if not worker.isTextChecked: |
573 | 569 |
textInfoList.clear() |
... | ... | |
576 | 572 |
removedSymbolImgPath = os.path.join(project.getTempPath(), os.path.basename(mainRes)) |
577 | 573 |
cv2.imwrite(removedSymbolImgPath, app_doc_data.imgSrc) |
578 | 574 |
|
579 |
area = AppDocData.instance().getArea('Drawing') |
|
580 |
if area is not None: |
|
581 |
area.img = app_doc_data.imgSrc[round(area.y + 1):round(area.y + area.height), |
|
582 |
round(area.x + 1):round(area.x + area.width)] |
|
583 |
cv2.imwrite(os.path.join(project.getTempPath(), "RECT_" + os.path.basename(mainRes)), |
|
584 |
app_doc_data.imgSrc) |
|
585 |
|
|
586 | 575 |
listWidget.addItem("Recognized symbol count : " + str(len(searchedSymbolList))) |
587 | 576 |
|
588 |
# get difference between original and recognized image |
|
589 |
foundFilePath = os.path.join(project.getTempPath(), "FOUND_" + os.path.basename(mainRes)) |
|
590 |
Worker.getDifference(mainRes, foundFilePath) |
|
591 |
# up to here |
|
592 |
|
|
593 | 577 |
listWidget.addItem(worker.tr('Creating detected infos...')) |
594 | 578 |
worker.displayTitle.emit(worker.tr('Creating detected infos...')) |
595 | 579 |
createDetectedItems(searchedSymbolList, textInfoList, |
... | ... | |
610 | 594 |
conn.connectedItem = None |
611 | 595 |
worker.scene.removeItem(lineItem) |
612 | 596 |
|
597 |
# try to detect nozzle from image drawing |
|
598 |
if worker.isSymbolChecked: |
|
599 |
worker.displayTitle.emit(worker.tr('Detecting nozzle and flange...')) |
|
600 |
|
|
601 |
nozzles = [] |
|
602 |
with futures.ThreadPoolExecutor(max_workers=THREAD_MAX_WORKER) as pool: |
|
603 |
future_nozzle = {pool.submit(Worker.detect_nozzles, mainRes, symbol, listWidget, worker): |
|
604 |
symbol for symbol in targetSymbolList[1]} |
|
605 |
for future in futures.as_completed(future_nozzle): |
|
606 |
data = future.result() |
|
607 |
if data: |
|
608 |
nozzles.extend(data) |
|
609 |
|
|
610 |
createDetectedItems(nozzles, [], [], []) |
|
611 |
|
|
612 |
for nozzle in nozzles: |
|
613 |
Worker.remove_detected_symbol_image(nozzle, app_doc_data.imgSrc) |
|
614 |
# up to here |
|
615 |
|
|
616 |
area = AppDocData.instance().getArea('Drawing') |
|
617 |
if area is not None: |
|
618 |
area.img = app_doc_data.imgSrc[round(area.y + 1):round(area.y + area.height), |
|
619 |
round(area.x + 1):round(area.x + area.width)] |
|
620 |
cv2.imwrite(os.path.join(project.getTempPath(), "RECT_" + os.path.basename(mainRes)), |
|
621 |
app_doc_data.imgSrc) |
|
622 |
|
|
623 |
Worker.drawFoundSymbolsOnCanvas(mainRes, searchedSymbolList, textInfoList, listWidget) |
|
624 |
|
|
625 |
# get difference between original and recognized image |
|
626 |
foundFilePath = os.path.join(project.getTempPath(), "FOUND_" + os.path.basename(mainRes)) |
|
627 |
Worker.getDifference(mainRes, foundFilePath) |
|
628 |
# up to here |
|
629 |
|
|
613 | 630 |
# connect symbol to symbol |
614 | 631 |
try: |
615 | 632 |
configs = app_doc_data.getConfigs('Line Detector', 'Length to connect line') |
... | ... | |
826 | 843 |
''' |
827 | 844 |
|
828 | 845 |
@staticmethod |
829 |
def detectEquipmentOnPid(mainRes, targetSymbol, listWidget, worker): |
|
846 |
def detect_nozzles(mainRes, targetSymbol, listWidget, worker): |
|
847 |
res = [] |
|
830 | 848 |
try: |
831 |
equipments = Worker.detectSymbolOnPid(mainRes, targetSymbol, listWidget, worker) |
|
849 |
app_doc_data = AppDocData.instance() |
|
850 |
|
|
851 |
nozzles = Worker.detectSymbolOnPid(mainRes, targetSymbol, listWidget, worker) |
|
852 |
equipments = [symbol for symbol in searchedSymbolList if app_doc_data.isEquipmentType(symbol.getType())] |
|
832 | 853 |
for equipment in equipments: |
833 |
# detect nozzles around equimpent |
|
834 |
for nozzle in targetSymbolList[1]: |
|
835 |
Worker.detectNozzleOnPid(equipment, nozzle, listWidget, worker) |
|
836 |
# up to here |
|
854 |
rect = QRectF(equipment.sp[0], equipment.sp[1], equipment.width, equipment.height) |
|
855 |
rect.adjust(-equipment.width*0.1, -equipment.height*0.1, equipment.width*0.1, equipment.height*0.1) |
|
856 |
matches = [nozzle for nozzle in nozzles if rect.contains(nozzle.rect)] |
|
857 |
res.extend(matches) |
|
858 |
for match in matches: |
|
859 |
nozzles.remove(match) |
|
837 | 860 |
except Exception as ex: |
838 | 861 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
839 | 862 |
sys.exc_info()[-1].tb_lineno) |
840 | 863 |
worker.displayLog(MessageType.Error, message) |
841 | 864 |
|
865 |
return res |
|
866 |
|
|
842 | 867 |
''' |
843 | 868 |
@brief detect symbol on PID |
844 | 869 |
@author jwkim |
... | ... | |
1243 | 1268 |
sys.exc_info()[-1].tb_lineno) |
1244 | 1269 |
return results |
1245 | 1270 |
|
1246 |
''' |
|
1247 |
@brief detect nozzlez |
|
1248 |
@author humkyung |
|
1249 |
@date 2018.07.07 |
|
1250 |
@history humkyhung 2018.07.17 pass equpment as parameter instead of image |
|
1251 |
''' |
|
1252 |
@staticmethod |
|
1253 |
def detectNozzleOnPid(equipment, nozzle, listWidget, worker): |
|
1254 |
global src |
|
1255 |
global threadLock |
|
1256 |
global maxProgressValue |
|
1257 |
|
|
1258 |
try: |
|
1259 |
symbolName = nozzle.getName() |
|
1260 |
symbolType = nozzle.getType() |
|
1261 |
symbolPath = nozzle.getPath() |
|
1262 |
symbolThreshold = nozzle.getThreshold() |
|
1263 |
symbolMinMatchCount = nozzle.getMinMatchCount() |
|
1264 |
isDetectOnOrigin = nozzle.getIsDetectOnOrigin() |
|
1265 |
symbolRotateCount = nozzle.getRotationCount() |
|
1266 |
symbolOcrOption = nozzle.getOcrOption() |
|
1267 |
isContainChild = nozzle.getIsContainChild() |
|
1268 |
symbolOriginalPoint = nozzle.getOriginalPoint() |
|
1269 |
symbolConnectionPoint = nozzle.getConnectionPoint() |
|
1270 |
baseSymbol = nozzle.getBaseSymbol() |
|
1271 |
additionalSymbol = nozzle.getAdditionalSymbol() |
|
1272 |
isExceptDetect = nozzle.getIsExceptDetect() |
|
1273 |
text_area = text_area |
|
1274 |
|
|
1275 |
foundSymbolCount = 0 |
|
1276 |
|
|
1277 |
# check if symbol file exists |
|
1278 |
if not os.path.isfile(symbolPath): |
|
1279 |
item = QListWidgetItem('{} file not found'.format(os.path.split(os.path.basename(symbolPath))[0])) |
|
1280 |
item.setBackground(QColor('red')) |
|
1281 |
listWidget.addItem(item) |
|
1282 |
return |
|
1283 |
# up to here |
|
1284 |
|
|
1285 |
symGray = Worker.cvtGrayImage(cv2.imread(symbolPath, 1)) |
|
1286 |
sow, soh = symGray.shape[::-1] # symbol original w, h |
|
1287 |
|
|
1288 |
# get image of equipment with offset of nozzle size |
|
1289 |
appDocData = AppDocData.instance() |
|
1290 |
pt = equipment.getSp() |
|
1291 |
nozzleSize = max(sow, soh) |
|
1292 |
sx = round(pt[0]) - nozzleSize |
|
1293 |
sy = round(pt[1]) - nozzleSize |
|
1294 |
ex = round(pt[0] + equipment.getWidth()) + nozzleSize |
|
1295 |
ey = round(pt[1] + equipment.getHeight()) + nozzleSize |
|
1296 |
offset = (sx, sy) |
|
1297 |
eqpSize = (pt[0], pt[1], equipment.getWidth(), equipment.getHeight()) |
|
1298 |
img = appDocData.imgSrc[sy:ey, sx:ex] |
|
1299 |
srcWidth, srcHeight = img.shape[::-1] |
|
1300 |
# up to here |
|
1301 |
|
|
1302 |
roiItemSp = (0, 0) |
|
1303 |
roiItemEp = (srcWidth, srcHeight) |
|
1304 |
roiItem = img |
|
1305 |
|
|
1306 |
symbolAngle = 0 |
|
1307 |
for rc in range(symbolRotateCount + 1): # Rotation Count를 사용자 기준으로 받아서 1을 더한 후 사용 |
|
1308 |
sw, sh = symGray.shape[::-1] |
|
1309 |
roiw = (roiItemEp[0] - roiItemSp[0]) |
|
1310 |
roih = (roiItemEp[1] - roiItemSp[1]) |
|
1311 |
|
|
1312 |
# get Rotated Original Point |
|
1313 |
originalPoint = Worker.getCalculatedOriginalPoint(additionalSymbol, symbolOriginalPoint, symbolAngle, |
|
1314 |
sw, sh, sow, soh) |
|
1315 |
connectionPoint = Worker.getCalculatedConnectionPoint(symbolConnectionPoint, symbolAngle, sw, sh, sow, |
|
1316 |
soh) |
|
1317 |
dx = connectionPoint[0][0] - originalPoint[0] |
|
1318 |
dy = connectionPoint[0][1] - originalPoint[1] |
|
1319 |
|
|
1320 |
# Template Matching |
|
1321 |
tmRes = cv2.matchTemplate(roiItem, symGray, cv2.TM_CCOEFF_NORMED) |
|
1322 |
loc = np.where(tmRes >= symbolThreshold) |
|
1323 |
|
|
1324 |
for pt in zip(*loc[::-1]): |
|
1325 |
mpCount = 0 # Match Point Count |
|
1326 |
symbolIndex = -1 |
|
1327 |
|
|
1328 |
roi = roiItem[pt[1]:pt[1] + sh, pt[0]:pt[0] + sw] |
|
1329 |
|
|
1330 |
if symbolMinMatchCount > 0: |
|
1331 |
mpCount = Worker.getMatchPointCount(roi, symGray) |
|
1332 |
if not (mpCount >= symbolMinMatchCount): |
|
1333 |
continue |
|
1334 |
|
|
1335 |
mid = (offset[0] + pt[0] + (originalPoint[0] + connectionPoint[0][0]) * 0.5, |
|
1336 |
offset[1] + pt[1] + (originalPoint[1] + connectionPoint[0][1]) * 0.5) |
|
1337 |
searchedItemSp = (roiItemSp[0] + pt[0] + offset[0], roiItemSp[1] + pt[1] + offset[1]) |
|
1338 |
# check searched nozzle location |
|
1339 |
if abs(dx) > abs(dy): |
|
1340 |
if dx > 0: |
|
1341 |
if mid[0] < eqpSize[0] + eqpSize[2] * 0.5: continue |
|
1342 |
else: |
|
1343 |
if mid[0] > eqpSize[0] + eqpSize[2] * 0.5: continue |
|
1344 |
else: |
|
1345 |
if dy > 0: |
|
1346 |
if mid[1] < eqpSize[1] + eqpSize[3] * 0.5: continue |
|
1347 |
else: |
|
1348 |
if mid[1] > eqpSize[1] + eqpSize[3] * 0.5: continue |
|
1349 |
# up to here |
|
1350 |
|
|
1351 |
overlapArea = 0 |
|
1352 |
nozzles = [symbol for symbol in searchedSymbolList if symbol.getType() == 'Nozzles'] |
|
1353 |
for i in range(len(nozzles)): |
|
1354 |
_pt = nozzles[i].getSp() |
|
1355 |
rect = QRectF(_pt[0], _pt[1], nozzles[i].getWidth(), nozzles[i].getHeight()) |
|
1356 |
_rect = QRectF(searchedItemSp[0], searchedItemSp[1], sw, sh) |
|
1357 |
if rect.intersects(_rect): |
|
1358 |
intersect = rect.intersected(_rect) |
|
1359 |
overlapArea = intersect.width() * intersect.height() |
|
1360 |
if overlapArea > ACCEPT_OVERLAY_AREA: |
|
1361 |
symbolIndex = i |
|
1362 |
break |
|
1363 |
|
|
1364 |
hitRate = tmRes[pt[1], pt[0]] |
|
1365 |
|
|
1366 |
## 겹치는 영역이 기준값보다 작을 경우 |
|
1367 |
if overlapArea <= ACCEPT_OVERLAY_AREA: |
|
1368 |
threadLock.acquire() |
|
1369 |
foundSymbolCount = foundSymbolCount + 1 |
|
1370 |
searched = Worker.addSearchedSymbol(symbolName, symbolType |
|
1371 |
, searchedItemSp, sw, sh, symbolThreshold, |
|
1372 |
symbolMinMatchCount, hitRate, symbolAngle |
|
1373 |
, isDetectOnOrigin, symbolRotateCount, symbolOcrOption, |
|
1374 |
isContainChild |
|
1375 |
, originalPoint, connectionPoint, baseSymbol, |
|
1376 |
additionalSymbol, isExceptDetect, text_area) |
|
1377 |
searched.owner = equipment |
|
1378 |
threadLock.release() |
|
1379 |
## 겹치는 영역이 기준값보다 클 경우 |
|
1380 |
else: |
|
1381 |
if symbolIndex != -1 and symbolIndex < len(nozzles): |
|
1382 |
searchedSymbol = nozzles[symbolIndex] |
|
1383 |
## 현재 심볼과 검출된 심볼이 같을 경우 Match Point가 더 높은 정보로 교체 |
|
1384 |
if symbolName == searchedSymbol.getName(): |
|
1385 |
symbolHitRate = searchedSymbol.getHitRate() |
|
1386 |
if symbolHitRate < hitRate: |
|
1387 |
threadLock.acquire() |
|
1388 |
nozzles[symbolIndex] = symbol.Symbol(symbolName, symbolType, |
|
1389 |
searchedItemSp, sw, sh, symbolThreshold, |
|
1390 |
symbolMinMatchCount, hitRate, symbolAngle, |
|
1391 |
isDetectOnOrigin, symbolRotateCount, |
|
1392 |
symbolOcrOption, isContainChild, |
|
1393 |
','.join(str(x) for x in originalPoint), |
|
1394 |
'/'.join( |
|
1395 |
'{},{},{},{}'.format(param[0], param[1], |
|
1396 |
param[2], param[3]) |
|
1397 |
for param in connectionPoint), |
|
1398 |
baseSymbol, additionalSymbol, isExceptDetect, text_area) |
|
1399 |
threadLock.release() |
|
1400 |
## 현재 심볼과 검출된 심볼이 같지 않을 경우 (포함) |
|
1401 |
elif appDocData.isEquipmentType(searchedSymbol.getType()): |
|
1402 |
threadLock.acquire() |
|
1403 |
foundSymbolCount = foundSymbolCount + 1 |
|
1404 |
searched = Worker.addSearchedSymbol(symbolName, symbolType |
|
1405 |
, searchedItemSp, sw, sh, symbolThreshold, hitRate, |
|
1406 |
hitRate, symbolAngle |
|
1407 |
, isDetectOnOrigin, symbolRotateCount, |
|
1408 |
symbolOcrOption, isContainChild |
|
1409 |
, originalPoint, connectionPoint, baseSymbol, |
|
1410 |
additionalSymbol, isExceptDetect, text_area) |
|
1411 |
searched.owner = equipment |
|
1412 |
threadLock.release() |
|
1413 |
|
|
1414 |
## Rotate Symbol |
|
1415 |
symGray = cv2.rotate(symGray, cv2.ROTATE_90_COUNTERCLOCKWISE) |
|
1416 |
symbolAngle = symbolAngle + 90 |
|
1417 |
|
|
1418 |
if additionalSymbol is not None: |
|
1419 |
additionalSymbol = Worker.getRotatedChildInfo(additionalSymbol) |
|
1420 |
|
|
1421 |
threadLock.acquire() |
|
1422 |
listWidget.addItem('Found Symbol : ' + os.path.splitext(os.path.basename(symbolPath))[0] + ' - (' + str( |
|
1423 |
foundSymbolCount) + ')') |
|
1424 |
threadLock.release() |
|
1425 |
|
|
1426 |
worker.updateProgress.emit(maxProgressValue, symbolPath) |
|
1427 |
|
|
1428 |
return [symbol for symbol in searchedSymbolList if symbol.getName() == symbolName] |
|
1429 |
except Exception as ex: |
|
1430 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
|
1431 |
sys.exc_info()[-1].tb_lineno) |
|
1432 |
worker.displayLog(MessageType.Error, message) |
|
1433 |
|
|
1434 |
return [] |
|
1435 |
|
|
1436 | 1271 |
# Convert into Grayscale image |
1437 | 1272 |
@staticmethod |
1438 | 1273 |
def cvtGrayImage(img): |
... | ... | |
1699 | 1534 |
|
1700 | 1535 |
@staticmethod |
1701 | 1536 |
def detectSymbolsOnPid(mainRes, targetSymbols, listWidget, updateProgressSignal): |
1537 |
res = [] |
|
1538 |
|
|
1702 | 1539 |
if type(targetSymbols) is list: |
1703 | 1540 |
for detailTarget in targetSymbols: |
1704 |
Worker.detectSymbolOnPid(mainRes, detailTarget, listWidget, updateProgressSignal)
|
|
1541 |
res.extend(Worker.detectSymbolOnPid(mainRes, detailTarget, listWidget, updateProgressSignal))
|
|
1705 | 1542 |
else: |
1706 |
Worker.detectSymbolOnPid(mainRes, targetSymbols, listWidget, updateProgressSignal) |
|
1543 |
res = Worker.detectSymbolOnPid(mainRes, targetSymbols, listWidget, updateProgressSignal) |
|
1544 |
|
|
1545 |
return res |
|
1707 | 1546 |
|
1708 | 1547 |
@staticmethod |
1709 | 1548 |
def convertDirectionCodeToValue(directionCode): |
... | ... | |
1731 | 1570 |
else: |
1732 | 1571 |
return "NONE" |
1733 | 1572 |
|
1734 |
''' |
|
1735 |
@brief draw found symbols and texts |
|
1736 |
@author Jeongwoo |
|
1737 |
''' |
|
1738 |
|
|
1739 | 1573 |
@staticmethod |
1740 |
def drawFoundSymbolsOnCanvas(drawingPath, textInfos, listWidget): |
|
1574 |
def drawFoundSymbolsOnCanvas(drawingPath, symbols, textInfos, listWidget): |
|
1575 |
"""draw found symbols and texts to image""" |
|
1576 |
|
|
1741 | 1577 |
global src |
1742 | 1578 |
global ocrCompletedSrc |
1743 | 1579 |
global canvas |
1744 | 1580 |
|
1745 |
appDocData = AppDocData.instance()
|
|
1746 |
canvas = np.zeros(appDocData.imgSrc.shape, np.uint8)
|
|
1581 |
app_doc_data = AppDocData.instance()
|
|
1582 |
canvas = np.zeros(app_doc_data.imgSrc.shape, np.uint8)
|
|
1747 | 1583 |
canvas[::] = 255 |
1748 | 1584 |
|
1749 | 1585 |
try: |
1750 |
appDocData = AppDocData.instance() |
|
1751 |
project = appDocData.getCurrentProject() |
|
1586 |
project = app_doc_data.getCurrentProject() |
|
1752 | 1587 |
|
1753 |
for symbol in searchedSymbolList:
|
|
1588 |
for symbol in symbols:
|
|
1754 | 1589 |
Worker.drawFoundSymbols(symbol, listWidget) |
1755 | 1590 |
|
1756 | 1591 |
for text in textInfos: |
... | ... | |
1759 | 1594 |
right = text.getX() + text.getW() |
1760 | 1595 |
bottom = text.getY() + text.getH() |
1761 | 1596 |
|
1762 |
canvas[top:bottom, left:right] = appDocData.imgSrc[top:bottom, left:right]
|
|
1597 |
canvas[top:bottom, left:right] = app_doc_data.imgSrc[top:bottom, left:right]
|
|
1763 | 1598 |
|
1764 | 1599 |
cv2.imwrite(os.path.join(project.getTempPath(), "FOUND_" + os.path.basename(drawingPath)), canvas) |
1765 | 1600 |
except Exception as ex: |
... | ... | |
1844 | 1679 |
global textInfoList |
1845 | 1680 |
|
1846 | 1681 |
try: |
1847 |
appDocData = AppDocData.instance()
|
|
1682 |
app_doc_data = AppDocData.instance()
|
|
1848 | 1683 |
if os.path.isfile(orgImagePath) and os.path.isfile(recImagePath): |
1849 | 1684 |
imgOriginal = \ |
1850 | 1685 |
cv2.threshold(Worker.cvtGrayImage(cv2.imread(orgImagePath, 1)), 127, 255, cv2.THRESH_BINARY)[1] |
1851 | 1686 |
|
1852 |
configs = appDocData.getConfigs('Filter', 'DilateSize')
|
|
1687 |
configs = app_doc_data.getConfigs('Filter', 'DilateSize')
|
|
1853 | 1688 |
if 1 == len(configs) and int(configs[0].value) is not 0: |
1854 | 1689 |
size = int(configs[0].value) |
1855 | 1690 |
kernel = np.ones((size, size), np.uint8) |
1856 | 1691 |
imgOriginal = cv2.erode(imgOriginal, kernel, iterations=1) |
1857 | 1692 |
|
1858 | 1693 |
# remove not drawing area |
1859 |
configs = appDocData.getConfigs('{} Equipment Desc Area'.format(appDocData.imgName))
|
|
1694 |
configs = app_doc_data.getConfigs('{} Equipment Desc Area'.format(app_doc_data.imgName))
|
|
1860 | 1695 |
for config in configs: |
1861 | 1696 |
found = re.findall('\\d+', config.value) |
1862 | 1697 |
if len(found) == 4: |
1863 | 1698 |
cv2.rectangle(imgOriginal, (int(found[0]), int(found[1])), |
1864 | 1699 |
(int(found[0]) + int(found[2]), int(found[1]) + int(found[3])), 255, -1) |
1865 | 1700 |
|
1866 |
configs = appDocData.getConfigs('{} Typical Area'.format(appDocData.imgName))
|
|
1701 |
configs = app_doc_data.getConfigs('{} Typical Area'.format(app_doc_data.imgName))
|
|
1867 | 1702 |
for config in configs: |
1868 | 1703 |
found = re.findall('\\d+', config.value) |
1869 | 1704 |
if len(found) == 4: |
1870 | 1705 |
cv2.rectangle(imgOriginal, (int(found[0]), int(found[1])), |
1871 | 1706 |
(int(found[0]) + int(found[2]), int(found[1]) + int(found[3])), 255, -1) |
1872 | 1707 |
|
1873 |
noteArea = appDocData.getArea('Note')
|
|
1708 |
noteArea = app_doc_data.getArea('Note')
|
|
1874 | 1709 |
if noteArea is not None: |
1875 |
noteArea.img = appDocData.imgSrc[round(noteArea.y):round(noteArea.y + noteArea.height),
|
|
1710 |
noteArea.img = app_doc_data.imgSrc[round(noteArea.y):round(noteArea.y + noteArea.height),
|
|
1876 | 1711 |
round(noteArea.x):round(noteArea.x + noteArea.width)].copy() |
1877 | 1712 |
cv2.rectangle(imgOriginal, (round(noteArea.x), round(noteArea.y)), |
1878 | 1713 |
(round(noteArea.x + noteArea.width), round(noteArea.y + noteArea.height)), 255, -1) |
... | ... | |
1883 | 1718 |
|
1884 | 1719 |
imgDiff = np.ones(imgOriginal.shape, np.uint8) * 255 |
1885 | 1720 |
|
1886 |
area = AppDocData.instance().getArea('Drawing')
|
|
1721 |
area = app_doc_data.getArea('Drawing')
|
|
1887 | 1722 |
if area is not None: |
1888 | 1723 |
x = round(area.x) |
1889 | 1724 |
y = round(area.y) |
... | ... | |
1896 | 1731 |
# remove noise |
1897 | 1732 |
imgDiff = cv2.dilate(imgDiff, np.ones((2, 2), np.uint8)) |
1898 | 1733 |
|
1899 |
appDocData = AppDocData.instance() |
|
1900 |
project = appDocData.getCurrentProject() |
|
1734 |
project = app_doc_data.getCurrentProject() |
|
1901 | 1735 |
cv2.imwrite(os.path.join(project.getTempPath(), "DIFF_" + os.path.basename(orgImagePath)), imgDiff) |
1902 | 1736 |
except Exception as ex: |
1903 | 1737 |
from App import App |
DTI_PID/DTI_PID/symbol.py | ||
---|---|---|
3 | 3 |
This is symbol module |
4 | 4 |
""" |
5 | 5 |
|
6 |
from PyQt5.QtCore import QRectF |
|
6 | 7 |
from SymbolBase import SymbolBase |
7 | 8 |
|
8 | 9 |
''' |
... | ... | |
78 | 79 |
def getText(self): |
79 | 80 |
return self.text |
80 | 81 |
|
82 |
@property |
|
83 |
def rect(self) -> QRectF: |
|
84 |
return QRectF(self.sp[0], self.sp[1], self.width, self.height) |
|
85 |
|
|
81 | 86 |
''' |
82 | 87 |
@brief check if contains given text area |
83 | 88 |
@author humkyung |
내보내기 Unified diff