개정판 4821cb74
issue #366: 텍스트 검사 기능 추가(white list 외의 문자를 포함하는 경우 밑줄 표시)
issue #663: 텍스트를 포함하는 심볼의 경우 텍스트를 제거하고 심볼을 인식하도록 수정
Change-Id: I80c09fe22e1a4267875d1af91237807e227873f2
DTI_PID/DTI_PID/Drawing.py | ||
---|---|---|
131 | 131 |
# drawing opening mode |
132 | 132 |
configs = app_doc_data.getConfigs('Filter', 'Mode') |
133 | 133 |
if 1 == len(configs) and int(configs[0].value) is not 0: |
134 |
kernel_sharpen_2 = np.array([[-1, -1, -1, -1, -1], [-1, 2, 2, 2, -1], [-1, 2, 8, 2, -1], [-1, 2, 2, 2, -1], |
|
135 |
[-2, -1, -1, -1, -1]]) / 8.0 # 정규화위해 8로나눔 |
|
136 |
self._image = cv2.filter2D(self._image, -1, kernel_sharpen_2) |
|
137 |
self._image = cv2.GaussianBlur(self._image, (5, 5), 10, 10) |
|
138 |
self._image = cv2.adaptiveThreshold(self._image, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 15, 5) |
|
139 |
|
|
140 |
selected_contours = [] |
|
141 |
contours, hierarchy = cv2.findContours(self._image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) |
|
142 |
index = 0 |
|
143 |
for contour in contours: |
|
144 |
child, parent = hierarchy[0][index][2], hierarchy[0][index][3] |
|
145 |
if child == -1: |
|
146 |
[x, y, w, h] = cv2.boundingRect(contour) |
|
147 |
if w * h < 5*5: |
|
148 |
selected_contours.append(contour) |
|
149 |
index += 1 |
|
150 |
# draw contour with white color |
|
151 |
self._image = cv2.drawContours(self._image, selected_contours, -1, (255, 255, 255), -1) |
|
152 |
else: |
|
153 |
self._image = cv2.threshold(self._image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1] |
|
154 |
#self._image = cv2.adaptiveThreshold(self._image, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 15, 2) |
|
134 |
kernel_sharpen_2 = np.array([[-1, -1, -1, -1, -1], |
|
135 |
[-1, 2, 2, 2, -1], |
|
136 |
[-1, 2, 8, 2, -1], |
|
137 |
[-1, 2, 2, 2, -1], |
|
138 |
[-2, -1, -1, -1, -1]]) / 8.0 # 정규화위해 8로나눔 |
|
139 |
kernel = np.array([[-1, -1, -1], |
|
140 |
[-1, 9, -1], |
|
141 |
[-1, -1, -1]]) |
|
142 |
#self._image = cv2.filter2D(self._image, -1, kernel_sharpen_2) # 이미지 외곽선 강화 |
|
143 |
#self._image = cv2.GaussianBlur(self._image, (1, 1), 0, 0) # gaussian blur |
|
144 |
|
|
145 |
self._image = cv2.threshold(self._image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1] |
|
146 |
#self._image = cv2.threshold(self._image, 100, 255, cv2.THRESH_BINARY)[1] |
|
147 |
#self._image = cv2.GaussianBlur(self._image, (1, 1), 0, 0) # gaussian blur |
|
148 |
if 1 == len(configs) and int(configs[0].value) is not 0: |
|
149 |
kernel_sharpen_2 = np.array([[-1, -1, -1, -1, -1], |
|
150 |
[-1, 2, 2, 2, -1], |
|
151 |
[-1, 2, 8, 2, -1], |
|
152 |
[-1, 2, 2, 2, -1], |
|
153 |
[-2, -1, -1, -1, -1]]) / 8.0 # 정규화위해 8로나눔 |
|
154 |
kernel = np.array([[-1, -1, -1], |
|
155 |
[-1, 9, -1], |
|
156 |
[-1, -1, -1]]) |
|
157 |
#self._image = cv2.filter2D(self._image, -1, kernel_sharpen_2) # 이미지 외곽선 강화 |
|
158 |
self._image = cv2.GaussianBlur(self._image, (1, 1), 0, 0) # gaussian blur |
|
159 |
|
|
160 |
""" |
|
161 |
configs = app_doc_data.getConfigs('Small Object Size', 'Min Area') |
|
162 |
min_area = int(configs[0].value) if 1 == len(configs) else 20 |
|
163 |
configs = app_doc_data.getConfigs('Small Object Size', 'Max Area') |
|
164 |
max_area = int(configs[0].value) if 1 == len(configs) else 50 |
|
165 |
|
|
166 |
selected_contours = [] |
|
167 |
contours, hierarchy = cv2.findContours(self._image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) |
|
168 |
index = 0 |
|
169 |
for contour in contours: |
|
170 |
child, parent = hierarchy[0][index][2], hierarchy[0][index][3] |
|
171 |
if child == -1: |
|
172 |
area = cv2.contourArea(contour, False) |
|
173 |
if area < min_area: |
|
174 |
selected_contours.append(contour) |
|
175 |
index += 1 |
|
176 |
# draw contour with white color |
|
177 |
self._image = cv2.drawContours(self._image, selected_contours, -1, (255, 255, 255), -1) |
|
178 |
""" |
|
155 | 179 |
|
156 | 180 |
configs = app_doc_data.getConfigs('Filter', 'DilateSize') |
157 | 181 |
if 1 == len(configs) and int(configs[0].value) is not 0: |
DTI_PID/DTI_PID/OcrResultDialog.py | ||
---|---|---|
6 | 6 |
import io, sys |
7 | 7 |
import numpy as np |
8 | 8 |
import math |
9 |
|
|
9 | 10 |
from PyQt5.QtCore import * |
10 | 11 |
from PyQt5.QtGui import * |
11 | 12 |
from PyQt5.QtWidgets import * |
... | ... | |
16 | 17 |
from AppDocData import * |
17 | 18 |
|
18 | 19 |
|
20 |
class SpellTextEdit(QTextEdit): |
|
21 |
def __init__(self, *args): |
|
22 |
QTextEdit.__init__(self, *args) |
|
23 |
|
|
24 |
# Default dictionary based on the current locale. |
|
25 |
app_doc_data = AppDocData.instance() |
|
26 |
white_char_list = app_doc_data.getConfigs('Text Recognition', 'White Character List') |
|
27 |
self.highlighter = Highlighter(self.document()) |
|
28 |
self.highlighter.white_char_list = white_char_list[0].value if white_char_list else None |
|
29 |
|
|
30 |
|
|
31 |
class Highlighter(QSyntaxHighlighter): |
|
32 |
err_format = QTextCharFormat() |
|
33 |
err_format.setUnderlineColor(Qt.red) |
|
34 |
err_format.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline) |
|
35 |
|
|
36 |
def __init__(self, *args): |
|
37 |
QSyntaxHighlighter.__init__(self, *args) |
|
38 |
|
|
39 |
self.white_char_list = None |
|
40 |
|
|
41 |
def highlightBlock(self, text): |
|
42 |
pos = 0 |
|
43 |
for word in text.split(): |
|
44 |
if self.white_char_list and any((c not in self.white_char_list) for c in word): |
|
45 |
self.setFormat(pos, len(word), self.err_format) |
|
46 |
pos += len(word) + 1 |
|
47 |
|
|
48 |
|
|
19 | 49 |
class QOcrResultDialog(QDialog): |
20 | 50 |
def __init__(self, parent, qimage, boundingBox, isModify=False, text=None): |
21 | 51 |
QDialog.__init__(self, parent) |
... | ... | |
31 | 61 |
|
32 | 62 |
self.ui = OcrResultDialog_UI.Ui_Dialog() |
33 | 63 |
self.ui.setupUi(self) |
64 |
self.ui.detectResultTextEdit = SpellTextEdit() |
|
65 |
self.ui.detectResultTextEdit.setFont(QFont('Consolas', 15, QFont.Bold)) |
|
66 |
self.ui.horizontalLayoutTextEdit.addWidget(self.ui.detectResultTextEdit) |
|
34 | 67 |
|
35 | 68 |
appDocData = AppDocData.instance() |
36 | 69 |
configs = appDocData.getAppConfigs('app', 'mode') |
DTI_PID/DTI_PID/OcrResultDialog_UI.py | ||
---|---|---|
2 | 2 |
|
3 | 3 |
# Form implementation generated from reading ui file '.\UI\OcrResultDialog.ui' |
4 | 4 |
# |
5 |
# Created by: PyQt5 UI code generator 5.13.0
|
|
5 |
# Created by: PyQt5 UI code generator 5.14.1
|
|
6 | 6 |
# |
7 | 7 |
# WARNING! All changes made in this file will be lost! |
8 | 8 |
|
... | ... | |
99 | 99 |
self.detectResultVerticalLayout_2 = QtWidgets.QVBoxLayout() |
100 | 100 |
self.detectResultVerticalLayout_2.setContentsMargins(8, 8, 8, 8) |
101 | 101 |
self.detectResultVerticalLayout_2.setObjectName("detectResultVerticalLayout_2") |
102 |
self.gridLayout_3 = QtWidgets.QGridLayout() |
|
103 |
self.gridLayout_3.setObjectName("gridLayout_3") |
|
102 | 104 |
self.horizontalLayout_3 = QtWidgets.QHBoxLayout() |
103 | 105 |
self.horizontalLayout_3.setObjectName("horizontalLayout_3") |
104 | 106 |
self.detectResultLabel_2 = QtWidgets.QLabel(self.bottomWidget) |
... | ... | |
114 | 116 |
self.checkBoxSeperate.setChecked(True) |
115 | 117 |
self.checkBoxSeperate.setObjectName("checkBoxSeperate") |
116 | 118 |
self.horizontalLayout_3.addWidget(self.checkBoxSeperate) |
117 |
self.detectResultVerticalLayout_2.addLayout(self.horizontalLayout_3) |
|
118 |
self.detectResultTextEdit = QtWidgets.QTextEdit(self.bottomWidget) |
|
119 |
self.detectResultTextEdit.setMaximumSize(QtCore.QSize(16777215, 200)) |
|
120 |
font = QtGui.QFont() |
|
121 |
font.setFamily("Consolas") |
|
122 |
font.setPointSize(15) |
|
123 |
self.detectResultTextEdit.setFont(font) |
|
124 |
self.detectResultTextEdit.setObjectName("detectResultTextEdit") |
|
125 |
self.detectResultVerticalLayout_2.addWidget(self.detectResultTextEdit) |
|
119 |
self.gridLayout_3.addLayout(self.horizontalLayout_3, 0, 0, 1, 1) |
|
120 |
self.horizontalLayoutTextEdit = QtWidgets.QHBoxLayout() |
|
121 |
self.horizontalLayoutTextEdit.setObjectName("horizontalLayoutTextEdit") |
|
122 |
self.gridLayout_3.addLayout(self.horizontalLayoutTextEdit, 1, 0, 1, 1) |
|
123 |
self.detectResultVerticalLayout_2.addLayout(self.gridLayout_3) |
|
126 | 124 |
self.verticalLayout_4.addLayout(self.detectResultVerticalLayout_2) |
127 | 125 |
self.gridLayout_2.addWidget(self.splitter, 1, 0, 1, 1) |
128 | 126 |
self.horizontalLayout_2 = QtWidgets.QHBoxLayout() |
DTI_PID/DTI_PID/RecognitionDialog.py | ||
---|---|---|
301 | 301 |
|
302 | 302 |
area = app_doc_data.getArea('Drawing') |
303 | 303 |
if area is not None: |
304 |
# copy image |
|
304 | 305 |
area.img = app_doc_data.imgSrc[round(area.y):round(area.y + area.height), |
305 | 306 |
round(area.x):round(area.x + area.width)] |
307 |
|
|
308 |
_, area.mask = cv2.threshold(area.img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) |
|
309 |
""" |
|
310 |
# area.contours, area.hierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) |
|
306 | 311 |
not_area = cv2.bitwise_not(area.img) |
307 | 312 |
area.not_img = not_area |
308 |
area_contours, area_hierachy = cv2.findContours(area.not_img , cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
|
|
313 |
area_contours, area_hierachy = cv2.findContours(area.not_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) |
|
309 | 314 |
area.contours = area_contours |
310 | 315 |
area.hierachy = area_hierachy |
316 |
""" |
|
311 | 317 |
|
312 | 318 |
maxProgressValue = 0 |
313 | 319 |
listWidget.addItem("Start recognition : " + mainRes) |
... | ... | |
329 | 335 |
if worker.isSymbolChecked: |
330 | 336 |
worker.displayTitle.emit(worker.tr('Detecting symbols...')) |
331 | 337 |
|
332 |
""" |
|
333 |
contours, _ = cv1.findContours(image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) |
|
334 |
for contour in contours: |
|
335 |
area = cv1.contourArea(contour, False) |
|
336 |
if min_area < area < max_area: |
|
337 |
epsilon = cv1.arcLength(contour, True) * 0.001 |
|
338 |
approx = cv1.approxPolyDP(contour, epsilon, True) |
|
339 |
approx = [pt[-1] for pt in approx] |
|
340 |
self.graphics_view.scene.contours.append(approx) |
|
341 |
""" |
|
342 |
|
|
343 | 338 |
# detect equipments |
344 | 339 |
pool = futures.ThreadPoolExecutor(max_workers=THREAD_MAX_WORKER) |
345 | 340 |
for symbol in targetSymbolList[0]: |
... | ... | |
374 | 369 |
|
375 | 370 |
searchedTextSymList = [] |
376 | 371 |
for sym in searchedSymbolList: |
372 |
""" |
|
377 | 373 |
if sym.getHasInstrumentLabel() >= 1: |
378 | 374 |
searchedTextSymList.append(sym) |
379 | 375 |
continue |
376 |
""" |
|
380 | 377 |
pool.submit(Worker.remove_detected_symbol_image, sym, app_doc_data.imgSrc) |
381 | 378 |
pool.shutdown(wait=True) |
382 | 379 |
else: |
... | ... | |
446 | 443 |
|
447 | 444 |
area = app_doc_data.getArea('Drawing') |
448 | 445 |
if area is not None: |
446 |
# copy area image |
|
449 | 447 |
area.img = app_doc_data.imgSrc[round(area.y):round(area.y + area.height), |
450 | 448 |
round(area.x):round(area.x + area.width)] |
451 | 449 |
|
... | ... | |
848 | 846 |
app_doc_data = AppDocData.instance() |
849 | 847 |
area = app_doc_data.getArea('Drawing') |
850 | 848 |
if area is not None: |
851 |
roiItem = area.img |
|
852 |
# roiItem = area.img.copy() |
|
849 |
roiItem = area.img.copy() if hasInstrumentLabel else area.img |
|
853 | 850 |
offsetDrawingArea.append(area.x) |
854 | 851 |
offsetDrawingArea.append(area.y) |
855 | 852 |
else: |
... | ... | |
864 | 861 |
roiItemSp = (0, 0) |
865 | 862 |
roiItemEp = (srcWidth, srcHeight) |
866 | 863 |
|
867 |
""" |
|
868 |
cv2.imwrite('c:\\Temp\\contour.png', roiItem) |
|
869 |
# remove objects smaller than symbol |
|
870 |
selected_contours = [] |
|
871 |
roiItem = cv2.bitwise_not(roiItem) |
|
872 |
cv2.imwrite('c:\\Temp\\not_contour.png', roiItem) |
|
873 |
contours, hierarchy = cv2.findContours(roiItem, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) |
|
874 |
index = 0 |
|
875 |
for contour in contours: |
|
876 |
child, parent = hierarchy[0][index][2], hierarchy[0][index][3] |
|
877 |
if child == -1 and parent != -1: |
|
878 |
[x, y, w, h] = cv2.boundingRect(contour) |
|
879 |
if w * h < sow * soh * 0.9: |
|
880 |
selected_contours.append(contour) |
|
881 |
index += 1 |
|
882 |
# up to here |
|
883 |
|
|
884 |
# draw contour with white color |
|
885 |
roiItem = cv2.drawContours(roiItem, selected_contours, -1, (255, 255, 255), -1) |
|
886 |
|
|
887 |
inverted_contours = [] |
|
888 |
contours, hierarchy = cv2.findContours(roiItem, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) |
|
889 |
index = 0 |
|
890 |
for contour in contours: |
|
891 |
child, parent = hierarchy[0][index][2], hierarchy[0][index][3] |
|
892 |
if child == -1 and parent != -1: |
|
864 |
# For OPC |
|
865 |
if area is not None and hasInstrumentLabel: |
|
866 |
# remove objects smaller than symbol |
|
867 |
selected_contours = [] |
|
868 |
contours, hierarchy = cv2.findContours(area.mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) |
|
869 |
index = 0 |
|
870 |
for contour in contours: |
|
871 |
child, parent = hierarchy[0][index][2], hierarchy[0][index][3] |
|
893 | 872 |
[x, y, w, h] = cv2.boundingRect(contour) |
894 |
if w * h < sow * soh * 0.9:
|
|
895 |
inverted_contours.append(contour)
|
|
896 |
index += 1
|
|
897 |
|
|
898 |
roiItem = cv2.bitwise_not(roiItem)
|
|
899 |
roiItem = cv2.drawContours(roiItem, inverted_contours, -1, (255, 255, 255), -1)
|
|
873 |
if w * h < sow * soh * 0.5:
|
|
874 |
contour_area = cv2.contourArea(contour, True)
|
|
875 |
if contour_area > 0:
|
|
876 |
selected_contours.append(contour) |
|
877 |
index += 1
|
|
878 |
# up to here
|
|
900 | 879 |
|
901 |
cv2.imwrite('c:\\Temp\\contour1.png', roiItem)
|
|
902 |
"""
|
|
880 |
# draw contour with white color
|
|
881 |
roiItem = cv2.drawContours(roiItem, selected_contours, -1, (255, 255, 255), -1)
|
|
903 | 882 |
|
904 | 883 |
for index in range(2): |
905 | 884 |
if index is 0: |
... | ... | |
968 | 947 |
connectionPoint = Worker.getCalculatedConnectionPoint(symbolConnectionPoint, symbolRotatedAngle, sw, |
969 | 948 |
sh, sow, soh) |
970 | 949 |
|
971 |
## For OPC
|
|
950 |
# For OPC |
|
972 | 951 |
if area is not None and (symbolType == "Piping OPC\'s" or symbolType == "Instrument OPC\'s"): |
973 | 952 |
worker.detectOPCOnPid(area, symGray) |
974 | 953 |
|
975 |
## Template Matching
|
|
954 |
# Template Matching |
|
976 | 955 |
tmRes = cv2.matchTemplate(roiItem, symGray, cv2.TM_CCOEFF_NORMED) |
977 | 956 |
loc = np.where(tmRes >= symbolThreshold) |
978 | 957 |
|
... | ... | |
1121 | 1100 |
threadLock.release() |
1122 | 1101 |
|
1123 | 1102 |
""" |
1124 |
# restore objects smaller than symbol |
|
1125 |
roiItem = cv2.drawContours(roiItem, inverted_contours, -1, (0, 0, 0), -1) |
|
1126 |
roiItem = cv2.drawContours(roiItem, selected_contours, -1, (255, 255, 255), -1) |
|
1127 |
# up to here |
|
1128 |
cv2.imwrite('c:\\Temp\\contour2.png', roiItem) |
|
1103 |
if area is not None and hasInstrumentLabel: |
|
1104 |
# restore objects smaller than symbol |
|
1105 |
roiItem = cv2.drawContours(roiItem, outside_contours, -1, (0, 0, 0), -1) |
|
1106 |
roiItem = cv2.drawContours(roiItem, hole_contours, -1, (255, 255, 255), -1) |
|
1107 |
# up to here |
|
1108 |
cv2.imwrite('c:\\Temp\\contour2.png', roiItem) |
|
1129 | 1109 |
""" |
1130 | 1110 |
|
1131 | 1111 |
worker.updateProgress.emit(maxProgressValue, symbolPath) |
... | ... | |
1139 | 1119 |
return [] |
1140 | 1120 |
|
1141 | 1121 |
@staticmethod |
1142 |
def detectOPCOnPid(area, symGray): |
|
1122 |
def detectOPCOnPid(area, symGray) -> None:
|
|
1143 | 1123 |
# symbol = cv2.copyMakeBorder(symGray, 1, 1, 1, 1, cv2.BORDER_CONSTANT, value=255) |
1144 | 1124 |
# not_symbol = cv2.bitwise_not(symbol) |
1145 | 1125 |
# symbol_contours, symbol_hierachy = cv2.findContours(not_symbol, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) |
... | ... | |
1156 | 1136 |
# if area_area * 1.3 >= symbol_area >= area_area * 0.7: |
1157 | 1137 |
# cv2.matchShape(symbol_contours[i], contour, ) |
1158 | 1138 |
# results.append() |
1159 |
#
|
|
1139 |
# |
|
1160 | 1140 |
# break |
1161 | 1141 |
|
1162 |
return results
|
|
1142 |
return None
|
|
1163 | 1143 |
|
1164 | 1144 |
''' |
1165 | 1145 |
@brief detect nozzle |
DTI_PID/DTI_PID/Shapes/EngineeringTextItem.py | ||
---|---|---|
24 | 24 |
from SymbolSvgItem import SymbolSvgItem |
25 | 25 |
|
26 | 26 |
|
27 |
class Highlighter(QSyntaxHighlighter): |
|
28 |
err_format = QTextCharFormat() |
|
29 |
err_format.setUnderlineColor(Qt.red) |
|
30 |
err_format.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline) |
|
31 |
|
|
32 |
def __init__(self, *args): |
|
33 |
QSyntaxHighlighter.__init__(self, *args) |
|
34 |
|
|
35 |
self.white_char_list = None |
|
36 |
|
|
37 |
def highlightBlock(self, text): |
|
38 |
pos = 0 |
|
39 |
for word in text.split(): |
|
40 |
if self.white_char_list and any((c not in self.white_char_list) for c in word): |
|
41 |
self.setFormat(pos, len(word), self.err_format) |
|
42 |
pos += len(word) + 1 |
|
43 |
|
|
44 |
|
|
27 | 45 |
class QEngineeringTextItem(QGraphicsTextItem, QEngineeringAbstractItem): |
28 | 46 |
HIGHLIGHT = '#BC4438' |
29 | 47 |
ZVALUE = 210 |
... | ... | |
57 | 75 |
self.attribute = '' |
58 | 76 |
self._properties = {} |
59 | 77 |
|
78 |
self.highlighter = None |
|
79 |
|
|
60 | 80 |
self.transfer = Transfer() |
61 | 81 |
self.setZValue(QEngineeringTextItem.ZVALUE) |
62 | 82 |
|
... | ... | |
223 | 243 |
@author humkyung |
224 | 244 |
@date 2018.07.08 |
225 | 245 |
''' |
226 |
|
|
227 | 246 |
def paint(self, painter, options=None, widget=None): |
228 | 247 |
self.setColor(self.getColor()) |
229 | 248 |
|
... | ... | |
245 | 264 |
# up to here |
246 | 265 |
|
247 | 266 |
painter.setPen(QPen(color)) |
248 |
painter.drawText(rect, Qt.AlignCenter, self.text()) |
|
249 | 267 |
|
250 | 268 |
if self.isSelected(): |
251 | 269 |
self.drawFocusRect(painter) |
252 | 270 |
|
271 |
QGraphicsTextItem.paint(self, painter, options, widget) |
|
272 |
|
|
253 | 273 |
''' |
254 | 274 |
@brief Delete text item |
255 | 275 |
@author Jeongwoo |
... | ... | |
377 | 397 |
''' |
378 | 398 |
def addTextItemToScene(self, scene): |
379 | 399 |
try: |
380 |
docData = AppDocData.instance()
|
|
381 |
configs = docData.getConfigs('Text Style', 'Font Name')
|
|
400 |
app_doc_data = AppDocData.instance()
|
|
401 |
configs = app_doc_data.getConfigs('Text Style', 'Font Name')
|
|
382 | 402 |
fontName = configs[0].value if configs else 'Arial' |
383 |
configs = docData.getConfigs('Text Style', 'Font Size')
|
|
403 |
configs = app_doc_data.getConfigs('Text Style', 'Font Size')
|
|
384 | 404 |
fontSize = int(configs[0].value) if configs else -1 |
385 | 405 |
|
386 | 406 |
sx = 1 |
... | ... | |
449 | 469 |
self.setFont(font) |
450 | 470 |
rect = self.boundingRect() |
451 | 471 |
|
452 |
""" |
|
453 |
doc = self.document() |
|
454 |
doc.setDocumentMargin(0) |
|
455 |
doc.adjustSize() |
|
456 |
doc_size = doc.size() |
|
457 |
|
|
458 |
sx = rect.width() / doc_size.width() |
|
459 |
sy = rect.height() / doc_size.height() |
|
460 |
""" |
|
461 |
|
|
462 | 472 |
sx = width / rect.width() |
463 | 473 |
sy = height / rect.height() |
464 | 474 |
|
... | ... | |
468 | 478 |
|
469 | 479 |
self.setTransform(transform) |
470 | 480 |
|
481 |
self.document().setDocumentMargin(0) |
|
482 |
white_char_list = app_doc_data.getConfigs('Text Recognition', 'White Character List') |
|
483 |
self.highlighter = Highlighter(self.document()) |
|
484 |
self.highlighter.white_char_list = white_char_list[0].value if white_char_list else None |
|
485 |
|
|
471 | 486 |
scene.addItem(self) |
472 | 487 |
except Exception as ex: |
473 | 488 |
from App import App |
... | ... | |
538 | 553 |
if component['Owner'] and component['Owner'] != 'None': |
539 | 554 |
item._owner = uuid.UUID(component['Owner']) |
540 | 555 |
|
541 |
## assign area
|
|
556 |
# assign area |
|
542 | 557 |
if not component['Area']: |
543 | 558 |
app_doc_data = AppDocData.instance() |
544 | 559 |
for area in app_doc_data.getAreaList(): |
DTI_PID/DTI_PID/SpellTextEdit.py | ||
---|---|---|
1 |
# coding: utf-8 |
|
2 |
""" This is SpellTextEdit module """ |
|
3 |
|
|
4 |
from PyQt5.QtCore import * |
|
5 |
from PyQt5.QtGui import * |
|
6 |
from PyQt5.QtWidgets import * |
|
7 |
from App import App |
|
8 |
from AppDocData import * |
|
9 |
|
|
10 |
__author__ = "humkyung <humkyung.doftech.co.kr>" |
|
11 |
|
|
12 |
|
|
13 |
class SpellTextEdit(QTextEdit): |
|
14 |
def __init__(self, *args): |
|
15 |
QTextEdit.__init__(self, *args) |
|
16 |
|
|
17 |
# Default dictionary based on the current locale. |
|
18 |
app_doc_data = AppDocData.instance() |
|
19 |
white_char_list = app_doc_data.getConfigs('Text Recognition', 'White Character List') |
|
20 |
self.highlighter = Highlighter(self.document()) |
|
21 |
self.highlighter.white_char_list = white_char_list[0].value if white_char_list else None |
|
22 |
|
|
23 |
|
|
24 |
class Highlighter(QSyntaxHighlighter): |
|
25 |
err_format = QTextCharFormat() |
|
26 |
err_format.setUnderlineColor(Qt.red) |
|
27 |
err_format.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline) |
|
28 |
|
|
29 |
def __init__(self, *args): |
|
30 |
QSyntaxHighlighter.__init__(self, *args) |
|
31 |
|
|
32 |
self.white_char_list = None |
|
33 |
|
|
34 |
def highlightBlock(self, text): |
|
35 |
pos = 0 |
|
36 |
for word in text.split(): |
|
37 |
if self.white_char_list and any((c not in self.white_char_list) for c in word): |
|
38 |
self.setFormat(pos, len(word), self.err_format) |
|
39 |
pos += len(word) + 1 |
DTI_PID/DTI_PID/SymbolEditorDialog.py | ||
---|---|---|
67 | 67 |
# for display image |
68 | 68 |
if display: |
69 | 69 |
self.ui.nameLineEdit.setEnabled(False) |
70 |
self.ui.thresholdLineEdit.setEnabled(False)
|
|
70 |
self.ui.spinBoxThreshold.setEnabled(False)
|
|
71 | 71 |
self.ui.rotationCountSpinBox.setEnabled(False) |
72 | 72 |
self.ui.isContainChildCheckBox.setEnabled(False) |
73 | 73 |
self.ui.typeComboBox.setEnabled(False) |
... | ... | |
225 | 225 |
''' |
226 | 226 |
|
227 | 227 |
def initForms(self): |
228 |
self.ui.thresholdLineEdit.setValidator(QRegExpValidator(QtCore.QRegExp("^[0-9]\d+$"))) # ([0-1]{1}[.])?[0-9]+ |
|
229 | 228 |
self.ui.minMatchPointLineEdit.setValidator(QRegExpValidator(QtCore.QRegExp("^[0-9]\d+$"))) |
230 | 229 |
self.initDefaultSymbolDirectionComboBoxItems() |
231 | 230 |
self.ui.addAdditionalSymbolButton.clicked.connect(self.addAdditionalSymbolEvent) |
... | ... | |
276 | 275 |
self.ui.immediateInsertCheckBox.setDisabled(True) |
277 | 276 |
|
278 | 277 |
self.ui.nameLineEdit.setText(self.selectedSymbol.getName()) |
279 |
self.ui.thresholdLineEdit.setText(str(int(self.selectedSymbol.getThreshold() * 100)))
|
|
278 |
self.ui.spinBoxThreshold.setValue(int(self.selectedSymbol.getThreshold() * 100))
|
|
280 | 279 |
self.ui.minMatchPointLineEdit.setText(str(self.selectedSymbol.getMinMatchCount())) |
281 | 280 |
self.ui.rotationCountSpinBox.setValue(self.selectedSymbol.getRotationCount() * 90) |
282 | 281 |
self.ui.isContainChildCheckBox.setChecked(True if self.selectedSymbol.getIsContainChild() else False) |
... | ... | |
487 | 486 |
fileName = name |
488 | 487 |
else: |
489 | 488 |
fileName = self.makeFileName(type, name, name) |
490 |
threshold = self.ui.thresholdLineEdit.text()
|
|
489 |
threshold = str(self.ui.spinBoxThreshold.value())
|
|
491 | 490 |
minMatchPoint = self.ui.minMatchPointLineEdit.text() |
492 | 491 |
rotationCount = int(self.ui.rotationCountSpinBox.value() / 90) |
493 | 492 |
ocrOption = 0 |
... | ... | |
722 | 721 |
if selectedItems is not None: |
723 | 722 |
for item in selectedItems: |
724 | 723 |
self.ui.additionalSymbolListWidget.takeItem(self.ui.additionalSymbolListWidget.row(item)) |
724 |
elif event.key() == Qt.Key_Escape: |
|
725 |
self.reject() |
|
725 | 726 |
|
726 | 727 |
''' |
727 | 728 |
@brief Hand Tool Button Clicked |
... | ... | |
1077 | 1078 |
infoTitle = self.ui.nameLabel.text() |
1078 | 1079 |
return (False, EXCEPTION_MSG_FORMAT.format(infoTitle)) |
1079 | 1080 |
|
1080 |
thresholdText = self.ui.thresholdLineEdit.text()
|
|
1081 |
thresholdText = str(self.ui.spinBoxThreshold.value())
|
|
1081 | 1082 |
threshold = float(thresholdText) if thresholdText else -1 |
1082 |
if not (threshold >= 0 and threshold <= 100):
|
|
1083 |
if not (0 <= threshold <= 100):
|
|
1083 | 1084 |
infoTitle = self.ui.thresholdLabel.text() |
1084 | 1085 |
return (False, EXCEPTION_MSG_FORMAT.format(infoTitle)) |
1085 | 1086 |
|
DTI_PID/DTI_PID/SymbolEditor_UI.py | ||
---|---|---|
1 | 1 |
# -*- coding: utf-8 -*- |
2 | 2 |
|
3 |
# Form implementation generated from reading ui file './UI/SymbolEditor.ui'
|
|
3 |
# Form implementation generated from reading ui file '.\UI\SymbolEditor.ui'
|
|
4 | 4 |
# |
5 |
# Created by: PyQt5 UI code generator 5.11.3
|
|
5 |
# Created by: PyQt5 UI code generator 5.14.1
|
|
6 | 6 |
# |
7 | 7 |
# WARNING! All changes made in this file will be lost! |
8 | 8 |
|
9 |
|
|
9 | 10 |
from PyQt5 import QtCore, QtGui, QtWidgets |
10 | 11 |
|
12 |
|
|
11 | 13 |
class Ui_Dialog(object): |
12 | 14 |
def setupUi(self, Dialog): |
13 | 15 |
Dialog.setObjectName("Dialog") |
... | ... | |
362 | 364 |
self.thresholdLabel.setFont(font) |
363 | 365 |
self.thresholdLabel.setObjectName("thresholdLabel") |
364 | 366 |
self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.thresholdLabel) |
365 |
self.thresholdLineEdit = QtWidgets.QLineEdit(self.scrollAreaWidgetContents) |
|
366 |
self.thresholdLineEdit.setObjectName("thresholdLineEdit") |
|
367 |
self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.thresholdLineEdit) |
|
368 | 367 |
self.minMatchPointLabel = QtWidgets.QLabel(self.scrollAreaWidgetContents) |
369 | 368 |
font = QtGui.QFont() |
370 | 369 |
font.setBold(True) |
... | ... | |
571 | 570 |
self.spinBoxhasInstrumentLabel.setMaximum(10) |
572 | 571 |
self.spinBoxhasInstrumentLabel.setObjectName("spinBoxhasInstrumentLabel") |
573 | 572 |
self.formLayout.setWidget(15, QtWidgets.QFormLayout.FieldRole, self.spinBoxhasInstrumentLabel) |
573 |
self.spinBoxThreshold = QtWidgets.QSpinBox(self.scrollAreaWidgetContents) |
|
574 |
self.spinBoxThreshold.setMinimum(1) |
|
575 |
self.spinBoxThreshold.setMaximum(100) |
|
576 |
self.spinBoxThreshold.setProperty("value", 75) |
|
577 |
self.spinBoxThreshold.setObjectName("spinBoxThreshold") |
|
578 |
self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.spinBoxThreshold) |
|
574 | 579 |
self.gridLayout_4.addLayout(self.formLayout, 0, 0, 1, 1) |
575 | 580 |
self.scrollArea.setWidget(self.scrollAreaWidgetContents) |
576 | 581 |
self.verticalLayout.addWidget(self.scrollArea) |
... | ... | |
585 | 590 |
self.buttonBox.accepted.connect(Dialog.accept) |
586 | 591 |
self.buttonBox.rejected.connect(Dialog.reject) |
587 | 592 |
QtCore.QMetaObject.connectSlotsByName(Dialog) |
593 |
Dialog.setTabOrder(self.handButton, self.cropButton) |
|
594 |
Dialog.setTabOrder(self.cropButton, self.penButton) |
|
595 |
Dialog.setTabOrder(self.penButton, self.penWidthSpinBox) |
|
596 |
Dialog.setTabOrder(self.penWidthSpinBox, self.eraserButton) |
|
597 |
Dialog.setTabOrder(self.eraserButton, self.eraserSpinBox) |
|
598 |
Dialog.setTabOrder(self.eraserSpinBox, self.fitImageButton) |
|
599 |
Dialog.setTabOrder(self.fitImageButton, self.areaEraserButton) |
|
600 |
Dialog.setTabOrder(self.areaEraserButton, self.rotateLeftButton) |
|
601 |
Dialog.setTabOrder(self.rotateLeftButton, self.rotateRightButton) |
|
602 |
Dialog.setTabOrder(self.rotateRightButton, self.flipHorizontalButton) |
|
603 |
Dialog.setTabOrder(self.flipHorizontalButton, self.flipVerticalButton) |
|
604 |
Dialog.setTabOrder(self.flipVerticalButton, self.zoomButton) |
|
605 |
Dialog.setTabOrder(self.zoomButton, self.areaZoomButton) |
|
606 |
Dialog.setTabOrder(self.areaZoomButton, self.initZoomButton) |
|
607 |
Dialog.setTabOrder(self.initZoomButton, self.removeTextButton) |
|
608 |
Dialog.setTabOrder(self.removeTextButton, self.guidelineCheckbox) |
|
609 |
Dialog.setTabOrder(self.guidelineCheckbox, self.comboBoxNormalColor) |
|
610 |
Dialog.setTabOrder(self.comboBoxNormalColor, self.comboBoxHoverColor) |
|
611 |
Dialog.setTabOrder(self.comboBoxHoverColor, self.scrollArea) |
|
612 |
Dialog.setTabOrder(self.scrollArea, self.nameLineEdit) |
|
613 |
Dialog.setTabOrder(self.nameLineEdit, self.spinBoxThreshold) |
|
614 |
Dialog.setTabOrder(self.spinBoxThreshold, self.minMatchPointLineEdit) |
|
615 |
Dialog.setTabOrder(self.minMatchPointLineEdit, self.rotationCountSpinBox) |
|
616 |
Dialog.setTabOrder(self.rotationCountSpinBox, self.isContainChildCheckBox) |
|
617 |
Dialog.setTabOrder(self.isContainChildCheckBox, self.typeComboBox) |
|
618 |
Dialog.setTabOrder(self.typeComboBox, self.baseSymbolComboBox) |
|
619 |
Dialog.setTabOrder(self.baseSymbolComboBox, self.spinBoxParent) |
|
620 |
Dialog.setTabOrder(self.spinBoxParent, self.defaultSymbolDirectionComboBox) |
|
621 |
Dialog.setTabOrder(self.defaultSymbolDirectionComboBox, self.additionalSymbolComboBox) |
|
622 |
Dialog.setTabOrder(self.additionalSymbolComboBox, self.addAdditionalSymbolButton) |
|
623 |
Dialog.setTabOrder(self.addAdditionalSymbolButton, self.additionalSymbolListWidget) |
|
624 |
Dialog.setTabOrder(self.additionalSymbolListWidget, self.originalPointLineEdit) |
|
625 |
Dialog.setTabOrder(self.originalPointLineEdit, self.addOriginalPointButton) |
|
626 |
Dialog.setTabOrder(self.addOriginalPointButton, self.connectionPointLineEdit) |
|
627 |
Dialog.setTabOrder(self.connectionPointLineEdit, self.addConnectionPointButton) |
|
628 |
Dialog.setTabOrder(self.addConnectionPointButton, self.pushButtonDelConnPt) |
|
629 |
Dialog.setTabOrder(self.pushButtonDelConnPt, self.tableWidgetConnList) |
|
630 |
Dialog.setTabOrder(self.tableWidgetConnList, self.spinBoxhasInstrumentLabel) |
|
631 |
Dialog.setTabOrder(self.spinBoxhasInstrumentLabel, self.isExceptDetectCheckBox) |
|
632 |
Dialog.setTabOrder(self.isExceptDetectCheckBox, self.immediateInsertCheckBox) |
|
633 |
Dialog.setTabOrder(self.immediateInsertCheckBox, self.makeFlipCheckBox) |
|
634 |
Dialog.setTabOrder(self.makeFlipCheckBox, self.checkBoxChange) |
|
635 |
Dialog.setTabOrder(self.checkBoxChange, self.pushButtonChange) |
|
588 | 636 |
|
589 | 637 |
def retranslateUi(self, Dialog): |
590 | 638 |
_translate = QtCore.QCoreApplication.translate |
... | ... | |
613 | 661 |
self.label_3.setText(_translate("Dialog", "Change Base, Additional")) |
614 | 662 |
self.label_4.setText(_translate("Dialog", "Symbol Info on Drawing")) |
615 | 663 |
self.pushButtonChange.setText(_translate("Dialog", "Change Item on Drawing without DB Update")) |
616 |
|
|
617 | 664 |
import MainWindow_rc |
618 |
|
|
619 |
if __name__ == "__main__": |
|
620 |
import sys |
|
621 |
app = QtWidgets.QApplication(sys.argv) |
|
622 |
Dialog = QtWidgets.QDialog() |
|
623 |
ui = Ui_Dialog() |
|
624 |
ui.setupUi(Dialog) |
|
625 |
Dialog.show() |
|
626 |
sys.exit(app.exec_()) |
|
627 |
|
DTI_PID/DTI_PID/TextDataListDialog.py | ||
---|---|---|
5 | 5 |
from AppDocData import AppDocData |
6 | 6 |
import TextDataList_UI |
7 | 7 |
from EngineeringTextItem import QEngineeringTextItem |
8 |
from SpellTextEdit import SpellTextEdit |
|
8 | 9 |
|
9 | 10 |
|
10 | 11 |
class forDoubleClicked(): |
... | ... | |
30 | 31 |
self.ui.tableWidget.setColumnCount(2) |
31 | 32 |
self.ui.tableWidget.setSortingEnabled(True) |
32 | 33 |
|
33 |
## column header 명 설정
|
|
34 |
# column header 명 설정 |
|
34 | 35 |
self.ui.tableWidget.setHorizontalHeaderLabels([self.tr('Text Image'), self.tr('Recognized Text')]) |
35 | 36 |
self.ui.tableWidget.horizontalHeaderItem(1).setSizeHint(QSize(30, 30)) |
36 | 37 |
self.ui.tableWidget.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch) |
... | ... | |
52 | 53 |
allowed_error = 0.001 |
53 | 54 |
for textItem in self.textItems: |
54 | 55 |
imageWidget = QTableWidgetItem() |
55 |
# textImage = AppDocData.instance().getCurrentPidSource().getQImageOnRect(QRect(textItem.loc[0] - 3, textItem.loc[1] - 3, textItem.size[0] + 6, textItem.size[1] + 6)) |
|
56 | 56 |
textImage = self.graphicsView.image().copy(textItem.loc[0] - 3, textItem.loc[1] - 3, textItem.size[0] + 6, |
57 | 57 |
textItem.size[1] + 6) |
58 | 58 |
if abs(textItem.angle - 0) <= allowed_error: |
... | ... | |
70 | 70 |
self.ui.tableWidget.setItem(row, 0, imageWidget) |
71 | 71 |
|
72 | 72 |
textWidget = QTableWidgetItem(textItem.text()) |
73 |
textWidget.setFont(QFont('Consolas', 15, QFont.Bold)) |
|
74 | 73 |
textWidget.tag = textItem |
75 | 74 |
self.ui.tableWidget.setItem(row, 1, textWidget) |
75 |
font = QFont('Consolas', 15, QFont.Bold) |
|
76 |
text_edit = SpellTextEdit(textItem.text()) |
|
77 |
text_edit.setFont(font) |
|
78 |
text_edit.setEnabled(False) |
|
79 |
self.ui.tableWidget.setCellWidget(row, 1, text_edit) |
|
76 | 80 |
row = row + 1 |
77 | 81 |
|
78 | 82 |
def listCellDoubleClicked(self, row, col): |
... | ... | |
92 | 96 |
if newTextItem is not None: |
93 | 97 |
self.ui.tableWidget.item(row, col).tag = newTextItem |
94 | 98 |
self.ui.tableWidget.item(row, col).setText(newTextItem.text()) |
99 |
self.ui.tableWidget.cellWidget(row, col).setPlainText(newTextItem.text()) |
|
95 | 100 |
|
96 | 101 |
except Exception as ex: |
97 | 102 |
from App import App |
DTI_PID/DTI_PID/TextDetector.py | ||
---|---|---|
376 | 376 |
if os.path.isfile(path): |
377 | 377 |
imgOCR = cv2.imread(path) |
378 | 378 |
imgOCR = \ |
379 |
cv2.threshold(cv2.cvtColor(imgOCR, cv2.COLOR_BGR2GRAY), 127, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
|
|
379 |
cv2.threshold(cv2.cvtColor(imgOCR, cv2.COLOR_BGR2GRAY), 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
|
|
380 | 380 |
|
381 | 381 |
# remove recognized text from image |
382 | 382 |
for text in self.textInfoList: |
DTI_PID/DTI_PID/UI/OcrResultDialog.ui | ||
---|---|---|
236 | 236 |
<number>8</number> |
237 | 237 |
</property> |
238 | 238 |
<item> |
239 |
<layout class="QHBoxLayout" name="horizontalLayout_3"> |
|
240 |
<item> |
|
241 |
<widget class="QLabel" name="detectResultLabel_2"> |
|
242 |
<property name="font"> |
|
243 |
<font> |
|
244 |
<weight>75</weight> |
|
245 |
<bold>true</bold> |
|
246 |
</font> |
|
247 |
</property> |
|
248 |
<property name="text"> |
|
249 |
<string>Recognition Result</string> |
|
250 |
</property> |
|
251 |
</widget> |
|
252 |
</item> |
|
253 |
<item> |
|
254 |
<spacer name="horizontalSpacer"> |
|
255 |
<property name="orientation"> |
|
256 |
<enum>Qt::Horizontal</enum> |
|
257 |
</property> |
|
258 |
<property name="sizeHint" stdset="0"> |
|
259 |
<size> |
|
260 |
<width>40</width> |
|
261 |
<height>20</height> |
|
262 |
</size> |
|
263 |
</property> |
|
264 |
</spacer> |
|
239 |
<layout class="QGridLayout" name="gridLayout_3"> |
|
240 |
<item row="0" column="0"> |
|
241 |
<layout class="QHBoxLayout" name="horizontalLayout_3"> |
|
242 |
<item> |
|
243 |
<widget class="QLabel" name="detectResultLabel_2"> |
|
244 |
<property name="font"> |
|
245 |
<font> |
|
246 |
<weight>75</weight> |
|
247 |
<bold>true</bold> |
|
248 |
</font> |
|
249 |
</property> |
|
250 |
<property name="text"> |
|
251 |
<string>Recognition Result</string> |
|
252 |
</property> |
|
253 |
</widget> |
|
254 |
</item> |
|
255 |
<item> |
|
256 |
<spacer name="horizontalSpacer"> |
|
257 |
<property name="orientation"> |
|
258 |
<enum>Qt::Horizontal</enum> |
|
259 |
</property> |
|
260 |
<property name="sizeHint" stdset="0"> |
|
261 |
<size> |
|
262 |
<width>40</width> |
|
263 |
<height>20</height> |
|
264 |
</size> |
|
265 |
</property> |
|
266 |
</spacer> |
|
267 |
</item> |
|
268 |
<item> |
|
269 |
<widget class="QCheckBox" name="checkBoxSeperate"> |
|
270 |
<property name="text"> |
|
271 |
<string>Seperate</string> |
|
272 |
</property> |
|
273 |
<property name="checked"> |
|
274 |
<bool>true</bool> |
|
275 |
</property> |
|
276 |
</widget> |
|
277 |
</item> |
|
278 |
</layout> |
|
265 | 279 |
</item> |
266 |
<item> |
|
267 |
<widget class="QCheckBox" name="checkBoxSeperate"> |
|
268 |
<property name="text"> |
|
269 |
<string>Seperate</string> |
|
270 |
</property> |
|
271 |
<property name="checked"> |
|
272 |
<bool>true</bool> |
|
273 |
</property> |
|
274 |
</widget> |
|
280 |
<item row="1" column="0"> |
|
281 |
<layout class="QHBoxLayout" name="horizontalLayoutTextEdit"/> |
|
275 | 282 |
</item> |
276 | 283 |
</layout> |
277 | 284 |
</item> |
278 |
<item> |
|
279 |
<widget class="QTextEdit" name="detectResultTextEdit"> |
|
280 |
<property name="maximumSize"> |
|
281 |
<size> |
|
282 |
<width>16777215</width> |
|
283 |
<height>200</height> |
|
284 |
</size> |
|
285 |
</property> |
|
286 |
<property name="font"> |
|
287 |
<font> |
|
288 |
<family>Consolas</family> |
|
289 |
<pointsize>15</pointsize> |
|
290 |
</font> |
|
291 |
</property> |
|
292 |
</widget> |
|
293 |
</item> |
|
294 | 285 |
</layout> |
295 | 286 |
</item> |
296 | 287 |
</layout> |
DTI_PID/DTI_PID/UI/SymbolEditor.ui | ||
---|---|---|
798 | 798 |
</property> |
799 | 799 |
</widget> |
800 | 800 |
</item> |
801 |
<item row="1" column="1"> |
|
802 |
<widget class="QLineEdit" name="thresholdLineEdit"/> |
|
803 |
</item> |
|
804 | 801 |
<item row="2" column="0"> |
805 | 802 |
<widget class="QLabel" name="minMatchPointLabel"> |
806 | 803 |
<property name="font"> |
... | ... | |
1202 | 1199 |
</property> |
1203 | 1200 |
</widget> |
1204 | 1201 |
</item> |
1202 |
<item row="1" column="1"> |
|
1203 |
<widget class="QSpinBox" name="spinBoxThreshold"> |
|
1204 |
<property name="minimum"> |
|
1205 |
<number>1</number> |
|
1206 |
</property> |
|
1207 |
<property name="maximum"> |
|
1208 |
<number>100</number> |
|
1209 |
</property> |
|
1210 |
<property name="value"> |
|
1211 |
<number>75</number> |
|
1212 |
</property> |
|
1213 |
</widget> |
|
1214 |
</item> |
|
1205 | 1215 |
</layout> |
1206 | 1216 |
</item> |
1207 | 1217 |
</layout> |
... | ... | |
1223 | 1233 |
</item> |
1224 | 1234 |
</layout> |
1225 | 1235 |
</widget> |
1236 |
<tabstops> |
|
1237 |
<tabstop>handButton</tabstop> |
|
1238 |
<tabstop>cropButton</tabstop> |
|
1239 |
<tabstop>penButton</tabstop> |
|
1240 |
<tabstop>penWidthSpinBox</tabstop> |
|
1241 |
<tabstop>eraserButton</tabstop> |
|
1242 |
<tabstop>eraserSpinBox</tabstop> |
|
1243 |
<tabstop>fitImageButton</tabstop> |
|
1244 |
<tabstop>areaEraserButton</tabstop> |
|
1245 |
<tabstop>rotateLeftButton</tabstop> |
|
1246 |
<tabstop>rotateRightButton</tabstop> |
|
1247 |
<tabstop>flipHorizontalButton</tabstop> |
|
1248 |
<tabstop>flipVerticalButton</tabstop> |
|
1249 |
<tabstop>zoomButton</tabstop> |
|
1250 |
<tabstop>areaZoomButton</tabstop> |
|
1251 |
<tabstop>initZoomButton</tabstop> |
|
1252 |
<tabstop>removeTextButton</tabstop> |
|
1253 |
<tabstop>guidelineCheckbox</tabstop> |
|
1254 |
<tabstop>comboBoxNormalColor</tabstop> |
|
1255 |
<tabstop>comboBoxHoverColor</tabstop> |
|
1256 |
<tabstop>scrollArea</tabstop> |
|
1257 |
<tabstop>nameLineEdit</tabstop> |
|
1258 |
<tabstop>spinBoxThreshold</tabstop> |
|
1259 |
<tabstop>minMatchPointLineEdit</tabstop> |
|
1260 |
<tabstop>rotationCountSpinBox</tabstop> |
|
1261 |
<tabstop>isContainChildCheckBox</tabstop> |
|
1262 |
<tabstop>typeComboBox</tabstop> |
|
1263 |
<tabstop>baseSymbolComboBox</tabstop> |
|
1264 |
<tabstop>spinBoxParent</tabstop> |
|
1265 |
<tabstop>defaultSymbolDirectionComboBox</tabstop> |
|
1266 |
<tabstop>additionalSymbolComboBox</tabstop> |
|
1267 |
<tabstop>addAdditionalSymbolButton</tabstop> |
|
1268 |
<tabstop>additionalSymbolListWidget</tabstop> |
|
1269 |
<tabstop>originalPointLineEdit</tabstop> |
|
1270 |
<tabstop>addOriginalPointButton</tabstop> |
|
1271 |
<tabstop>connectionPointLineEdit</tabstop> |
|
1272 |
<tabstop>addConnectionPointButton</tabstop> |
|
1273 |
<tabstop>pushButtonDelConnPt</tabstop> |
|
1274 |
<tabstop>tableWidgetConnList</tabstop> |
|
1275 |
<tabstop>spinBoxhasInstrumentLabel</tabstop> |
|
1276 |
<tabstop>isExceptDetectCheckBox</tabstop> |
|
1277 |
<tabstop>immediateInsertCheckBox</tabstop> |
|
1278 |
<tabstop>makeFlipCheckBox</tabstop> |
|
1279 |
<tabstop>checkBoxChange</tabstop> |
|
1280 |
<tabstop>pushButtonChange</tabstop> |
|
1281 |
</tabstops> |
|
1226 | 1282 |
<resources> |
1227 | 1283 |
<include location="../res/MainWindow.qrc"/> |
1228 | 1284 |
</resources> |
DTI_PID/DTI_PID/tesseract_ocr_module.py | ||
---|---|---|
155 | 155 |
for merged_box in merged_boxes: |
156 | 156 |
bottom = merged_box.bottom() |
157 | 157 |
top = merged_box.top() |
158 |
if (abs(miny - top) <= (bottom - top) * 0.2 or abs(maxy - bottom) <= (bottom - top) * 0.2) or (
|
|
159 |
miny <= top and maxy >= bottom) or (
|
|
160 |
miny >= top and maxy <= bottom): |
|
158 |
if (abs(miny - top) <= (bottom - top) * 0.2 or abs(maxy - bottom) <= (bottom - top) * 0.2) or \
|
|
159 |
(miny <= top and maxy >= bottom) or \
|
|
160 |
(miny >= top and maxy <= bottom):
|
|
161 | 161 |
find_box = merged_box |
162 | 162 |
|
163 | 163 |
if find_box: |
내보내기 Unified diff