개정판 c7c1b458
issue #655 : add chart beta
DTI_PID/DTI_PID/TrainingImageListDialog.py | ||
---|---|---|
7 | 7 |
from PyQt5.QtCore import * |
8 | 8 |
from PyQt5.QtGui import * |
9 | 9 |
from PyQt5.QtWidgets import * |
10 |
from PyQt5.QtChart import * |
|
10 | 11 |
from AppDocData import AppDocData, Source |
11 | 12 |
import pytesseract |
12 | 13 |
import TrainingImageList_UI |
... | ... | |
25 | 26 |
cntraining_cmd = os.path.join(dataPath, 'Tesseract-OCR', 'cntraining.exe') |
26 | 27 |
combine_tessdata_cmd = os.path.join(dataPath, 'Tesseract-OCR', 'combine_tessdata.exe') |
27 | 28 |
|
29 |
# for reset chart |
|
30 |
defaultCharList = [['0',0],['1',0],['2',0],['3',0],['4',0],['5',0],['6',0],['7',0],['8',0],['9',0],['a',0],['b',0],['c',0],['d',0],['e',0],['f',0],['g',0],['h',0],['i',0],['j',0],['k',0],['l',0],['m',0],['n',0],['o',0],['p',0],['q',0],['r',0],['s',0],['t',0],['u',0],['w',0],['x',0],['y',0],['z',0],['A',0],['B',0],['C',0],['D',0],['E',0],['F',0],['G',0],['H',0],['I',0],['J',0],['K',0],['L',0],['M',0],['N',0],['O',0],['P',0],['Q',0],['R',0],['S',0],['T',0],['U',0],['V',0],['W',0],['X',0],['Y',0],['Z',0]] |
|
31 |
|
|
28 | 32 |
class EmittingStream(QObject): |
29 | 33 |
""" |
30 | 34 |
This is EmittingStream class |
... | ... | |
47 | 51 |
self.ui = TrainingImageList_UI.Ui_TraingingImageListDialog() |
48 | 52 |
self.ui.setupUi(self) |
49 | 53 |
self.ui.progressBar.setValue(0) |
54 |
self.charList = defaultCharList |
|
50 | 55 |
|
51 | 56 |
# for List |
52 | 57 |
self.ui.tableWidgetList.setSelectionMode(QAbstractItemView.SingleSelection) |
... | ... | |
232 | 237 |
dataList = appDocData.getTrainingFileList() |
233 | 238 |
listHasBox = [] |
234 | 239 |
|
235 |
charList = [['0',0],['1',0],['2',0],['3',0],['4',0],['5',0],['6',0],['7',0],['8',0],['9',0],['a',0],['b',0],['c',0],['d',0],['e',0],['f',0],['g',0],['h',0],['i',0],['j',0],['k',0],['l',0],['m',0],['n',0],['o',0],['p',0],['q',0],['r',0],['s',0],['t',0],['u',0],['w',0],['x',0],['y',0],['z',0],['A',0],['B',0],['C',0],['D',0],['E',0],['F',0],['G',0],['H',0],['I',0],['J',0],['K',0],['L',0],['M',0],['N',0],['O',0],['P',0],['Q',0],['R',0],['S',0],['T',0],['U',0],['V',0],['W',0],['X',0],['Y',0],['Z',0]] |
|
236 |
|
|
237 | 240 |
images = {} |
238 | 241 |
boxes = [] |
239 | 242 |
for data in dataList: |
... | ... | |
248 | 251 |
fw = open(boxPath, 'r', encoding='utf8') |
249 | 252 |
boxContent = fw.read() |
250 | 253 |
lines = boxContent.split('\n') |
254 |
self.charList = defaultCharList |
|
251 | 255 |
for line in lines: |
252 | 256 |
if not line: continue |
253 | 257 |
char,min_x,min_y,max_x,max_y = line.split(' ') |
254 | 258 |
boxes.append([char,int(min_x),int(min_y),int(max_x)-int(min_x),int(max_y)-int(min_y),os.path.splitext(os.path.basename(boxPath))[0]]) |
255 | 259 |
|
256 |
matches = [_char for _char in charList if _char[0] == char] |
|
260 |
matches = [_char for _char in self.charList if _char[0] == char]
|
|
257 | 261 |
if matches: |
258 | 262 |
matches[0][1] = matches[0][1] + 1 |
259 | 263 |
else: |
260 |
charList.append([char, 1]) |
|
264 |
self.charList.append([char, 1])
|
|
261 | 265 |
fw.close() |
262 | 266 |
|
263 | 267 |
grid_size = [None, None] |
... | ... | |
411 | 415 |
boxes = outBox.split('\n') |
412 | 416 |
boxes = boxes[:-1] |
413 | 417 |
maxBoxWidth, maxBoxHeight = 0, 0 |
414 |
charList = [['0',0],['1',0],['2',0],['3',0],['4',0],['5',0],['6',0],['7',0],['8',0],['9',0],['a',0],['b',0],['c',0],['d',0],['e',0],['f',0],['g',0],['h',0],['i',0],['j',0],['k',0],['l',0],['m',0],['n',0],['o',0],['p',0],['q',0],['r',0],['s',0],['t',0],['u',0],['w',0],['x',0],['y',0],['z',0],['A',0],['B',0],['C',0],['D',0],['E',0],['F',0],['G',0],['H',0],['I',0],['J',0],['K',0],['L',0],['M',0],['N',0],['O',0],['P',0],['Q',0],['R',0],['S',0],['T',0],['U',0],['V',0],['W',0],['X',0],['Y',0],['Z',0]] |
|
418 |
self.charList = [['0',0],['1',0],['2',0],['3',0],['4',0],['5',0],['6',0],['7',0],['8',0],['9',0],['a',0],['b',0],['c',0],['d',0],['e',0],['f',0],['g',0],['h',0],['i',0],['j',0],['k',0],['l',0],['m',0],['n',0],['o',0],['p',0],['q',0],['r',0],['s',0],['t',0],['u',0],['w',0],['x',0],['y',0],['z',0],['A',0],['B',0],['C',0],['D',0],['E',0],['F',0],['G',0],['H',0],['I',0],['J',0],['K',0],['L',0],['M',0],['N',0],['O',0],['P',0],['Q',0],['R',0],['S',0],['T',0],['U',0],['V',0],['W',0],['X',0],['Y',0],['Z',0]]
|
|
415 | 419 |
for box in boxes: |
416 | 420 |
boxComponent = box.split(' ') |
417 | 421 |
boxWidth = abs(int(boxComponent[3]) - int(boxComponent[1])) |
... | ... | |
421 | 425 |
if boxHeight > maxBoxHeight: |
422 | 426 |
maxBoxHeight = boxHeight |
423 | 427 |
|
424 |
for index in range(len(charList)): |
|
425 |
if charList[index][0] == boxComponent[0]: |
|
426 |
charList[index][1] += 1 |
|
428 |
for index in range(len(self.charList)):
|
|
429 |
if self.charList[index][0] == boxComponent[0]:
|
|
430 |
self.charList[index][1] += 1
|
|
427 | 431 |
break |
428 |
elif index is len(charList) - 1: |
|
429 |
charList.append([boxComponent[0], 1]) |
|
430 |
for index in range(len(charList)): |
|
431 |
charList[index][1] = int(charList[index][1] / 4)
|
|
432 |
elif index is len(self.charList) - 1:
|
|
433 |
self.charList.append([boxComponent[0], 1])
|
|
434 |
for index in range(len(self.charList)):
|
|
435 |
self.charList[index][1] = int(self.charList[index][1] / 4)
|
|
432 | 436 |
|
433 | 437 |
maxBoxWidth += 1 |
434 | 438 |
maxBoxHeight += 3 |
... | ... | |
587 | 591 |
os.rename(os.path.join(dataPath, self.oCRLang + '.traineddata'), os.path.join(tesseractPath, self.oCRLang + '.traineddata')) |
588 | 592 |
|
589 | 593 |
self.deleteMidProcessFile() |
594 |
print(self.charList) |
|
595 |
self.makeChart() |
|
590 | 596 |
QMessageBox.about(self, "알림", '성공적으로 적용하였습니다.') |
591 |
|
|
592 |
print(charList) ## sung |
|
593 | 597 |
except Exception as ex: |
594 | 598 |
from App import App |
595 | 599 |
from AppDocData import MessageType |
... | ... | |
600 | 604 |
self.deleteMidProcessFile() |
601 | 605 |
os.chdir(originPath) |
602 | 606 |
|
607 |
def makeChart(self): |
|
608 |
''' |
|
609 |
@brief make chart for trained charaters |
|
610 |
@author euisung |
|
611 |
@date 2018.11.19 |
|
612 |
''' |
|
613 |
barList = [] |
|
614 |
categories = [] |
|
615 |
chart = QChart() |
|
616 |
bar = QBarSet('char') |
|
617 |
axis = QBarCategoryAxis() |
|
618 |
series = QBarSeries() |
|
619 |
for char in self.charList: |
|
620 |
categories.append(char[0]) |
|
621 |
barList.append(char[1]) |
|
622 |
bar.append(barList) |
|
623 |
series.append(bar) |
|
624 |
chart.addSeries(series) |
|
625 |
axis.append(categories) |
|
626 |
|
|
627 |
chart.setTitle('Trained Characters') |
|
628 |
chart.createDefaultAxes() |
|
629 |
chart.setAxisX(axis, series) |
|
630 |
chart.legend().setAlignment(Qt.AlignBottom) |
|
631 |
|
|
632 |
chartView = QChartView(chart) |
|
633 |
if self.ui.splitter.replaceWidget(1, chartView) is None: |
|
634 |
self.ui.splitter.addWidget(chartView) |
|
635 |
|
|
603 | 636 |
''' |
604 | 637 |
@brief delete Mid Process File |
605 | 638 |
@author euisung |
... | ... | |
660 | 693 |
docData = AppDocData.instance() |
661 | 694 |
oCRLang = docData.getCurrentProject().getName() if TOCR.existTrainedData() else 'eng' |
662 | 695 |
whiteCharList = docData.getConfigs('Text Recognition', 'White Character List') |
663 |
if len(whiteCharList) is 0: |
|
696 |
if len(whiteCharList.charList) is 0:
|
|
664 | 697 |
boundaryOcrData = pytesseract.image_to_boxes(drawing, config=TOCR.DEFAULT_CONF, lang=oCRLang) |
665 | 698 |
else: |
666 |
boundaryOcrData = pytesseract.image_to_boxes(drawing, config=TOCR.DEFAULT_CONF[:40] + whiteCharList[0].value, lang=oCRLang) |
|
699 |
boundaryOcrData = pytesseract.image_to_boxes(drawing, config=TOCR.DEFAULT_CONF[:40] + whiteCharList.charList[0].value, lang=oCRLang)
|
|
667 | 700 |
|
668 | 701 |
except Exception as ex: |
669 | 702 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
DTI_PID/DTI_PID/TrainingImageList_UI.py | ||
---|---|---|
1 | 1 |
# -*- coding: utf-8 -*- |
2 | 2 |
|
3 |
# Form implementation generated from reading ui file '.\UI\TrainingImageList.ui'
|
|
3 |
# Form implementation generated from reading ui file './UI/TrainingImageList.ui'
|
|
4 | 4 |
# |
5 | 5 |
# Created by: PyQt5 UI code generator 5.11.3 |
6 | 6 |
# |
... | ... | |
11 | 11 |
class Ui_TraingingImageListDialog(object): |
12 | 12 |
def setupUi(self, TraingingImageListDialog): |
13 | 13 |
TraingingImageListDialog.setObjectName("TraingingImageListDialog") |
14 |
TraingingImageListDialog.resize(943, 625)
|
|
14 |
TraingingImageListDialog.resize(1556, 708)
|
|
15 | 15 |
font = QtGui.QFont() |
16 | 16 |
font.setFamily("맑은 고딕") |
17 | 17 |
font.setBold(True) |
... | ... | |
86 | 86 |
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) |
87 | 87 |
self.horizontalLayout_3.addItem(spacerItem1) |
88 | 88 |
self.gridLayout.addLayout(self.horizontalLayout_3, 1, 0, 1, 1) |
89 |
self.splitter = QtWidgets.QSplitter(TraingingImageListDialog) |
|
90 |
self.splitter.setOrientation(QtCore.Qt.Vertical) |
|
91 |
self.splitter.setObjectName("splitter") |
|
92 |
self.tableWidgetList = QtWidgets.QTableWidget(self.splitter) |
|
93 |
self.tableWidgetList.setColumnCount(1) |
|
94 |
self.tableWidgetList.setObjectName("tableWidgetList") |
|
95 |
self.tableWidgetList.setRowCount(0) |
|
96 |
self.tableWidgetList.horizontalHeader().setSortIndicatorShown(True) |
|
97 |
self.tableWidgetList.verticalHeader().setVisible(False) |
|
98 |
self.widget = QtWidgets.QWidget(self.splitter) |
|
99 |
self.widget.setObjectName("widget") |
|
100 |
self.gridLayout.addWidget(self.splitter, 2, 0, 1, 1) |
|
101 | 89 |
self.horizontalLayout = QtWidgets.QHBoxLayout() |
102 | 90 |
self.horizontalLayout.setObjectName("horizontalLayout") |
103 | 91 |
self.pushButtonBox = QtWidgets.QPushButton(TraingingImageListDialog) |
... | ... | |
117 | 105 |
self.pushButtonClose.setObjectName("pushButtonClose") |
118 | 106 |
self.horizontalLayout.addWidget(self.pushButtonClose) |
119 | 107 |
self.gridLayout.addLayout(self.horizontalLayout, 3, 0, 1, 1) |
108 |
self.splitter = QtWidgets.QSplitter(TraingingImageListDialog) |
|
109 |
self.splitter.setOrientation(QtCore.Qt.Vertical) |
|
110 |
self.splitter.setObjectName("splitter") |
|
111 |
self.tableWidgetList = QtWidgets.QTableWidget(self.splitter) |
|
112 |
self.tableWidgetList.setColumnCount(1) |
|
113 |
self.tableWidgetList.setObjectName("tableWidgetList") |
|
114 |
self.tableWidgetList.setRowCount(0) |
|
115 |
self.tableWidgetList.horizontalHeader().setSortIndicatorShown(True) |
|
116 |
self.tableWidgetList.verticalHeader().setVisible(False) |
|
117 |
self.gridLayout.addWidget(self.splitter, 2, 0, 1, 1) |
|
120 | 118 |
|
121 | 119 |
self.retranslateUi(TraingingImageListDialog) |
122 | 120 |
QtCore.QMetaObject.connectSlotsByName(TraingingImageListDialog) |
... | ... | |
132 | 130 |
self.checkBoxFixed.setText(_translate("TraingingImageListDialog", "fixed")) |
133 | 131 |
self.checkBoxSerif.setText(_translate("TraingingImageListDialog", "serif")) |
134 | 132 |
self.checkBoxFraktur.setText(_translate("TraingingImageListDialog", "fraktur")) |
135 |
self.tableWidgetList.setSortingEnabled(True) |
|
136 | 133 |
self.pushButtonBox.setText(_translate("TraingingImageListDialog", "문자 영역 수정")) |
137 | 134 |
self.pushButtonMakeTrainingData.setText(_translate("TraingingImageListDialog", "학습 데이터 생성")) |
138 | 135 |
self.pushButtonClose.setText(_translate("TraingingImageListDialog", "닫기")) |
136 |
self.tableWidgetList.setSortingEnabled(True) |
|
137 |
|
|
138 |
|
|
139 |
if __name__ == "__main__": |
|
140 |
import sys |
|
141 |
app = QtWidgets.QApplication(sys.argv) |
|
142 |
TraingingImageListDialog = QtWidgets.QDialog() |
|
143 |
ui = Ui_TraingingImageListDialog() |
|
144 |
ui.setupUi(TraingingImageListDialog) |
|
145 |
TraingingImageListDialog.show() |
|
146 |
sys.exit(app.exec_()) |
|
139 | 147 |
|
DTI_PID/DTI_PID/UI/TrainingImageList.ui | ||
---|---|---|
6 | 6 |
<rect> |
7 | 7 |
<x>0</x> |
8 | 8 |
<y>0</y> |
9 |
<width>943</width>
|
|
10 |
<height>625</height>
|
|
9 |
<width>1556</width>
|
|
10 |
<height>708</height>
|
|
11 | 11 |
</rect> |
12 | 12 |
</property> |
13 | 13 |
<property name="font"> |
... | ... | |
192 | 192 |
</item> |
193 | 193 |
</layout> |
194 | 194 |
</item> |
195 |
<item row="2" column="0"> |
|
196 |
<widget class="QSplitter" name="splitter"> |
|
197 |
<property name="orientation"> |
|
198 |
<enum>Qt::Vertical</enum> |
|
199 |
</property> |
|
200 |
<widget class="QTableWidget" name="tableWidgetList"> |
|
201 |
<property name="sortingEnabled"> |
|
202 |
<bool>true</bool> |
|
203 |
</property> |
|
204 |
<property name="columnCount"> |
|
205 |
<number>1</number> |
|
206 |
</property> |
|
207 |
<attribute name="horizontalHeaderShowSortIndicator" stdset="0"> |
|
208 |
<bool>true</bool> |
|
209 |
</attribute> |
|
210 |
<attribute name="verticalHeaderVisible"> |
|
211 |
<bool>false</bool> |
|
212 |
</attribute> |
|
213 |
<column/> |
|
214 |
</widget> |
|
215 |
<widget class="QWidget" name="widget" native="true"/> |
|
216 |
</widget> |
|
217 |
</item> |
|
218 | 195 |
<item row="3" column="0"> |
219 | 196 |
<layout class="QHBoxLayout" name="horizontalLayout"> |
220 | 197 |
<item> |
... | ... | |
256 | 233 |
</item> |
257 | 234 |
</layout> |
258 | 235 |
</item> |
236 |
<item row="2" column="0"> |
|
237 |
<widget class="QSplitter" name="splitter"> |
|
238 |
<property name="orientation"> |
|
239 |
<enum>Qt::Vertical</enum> |
|
240 |
</property> |
|
241 |
<widget class="QTableWidget" name="tableWidgetList"> |
|
242 |
<property name="sortingEnabled"> |
|
243 |
<bool>true</bool> |
|
244 |
</property> |
|
245 |
<property name="columnCount"> |
|
246 |
<number>1</number> |
|
247 |
</property> |
|
248 |
<attribute name="horizontalHeaderShowSortIndicator" stdset="0"> |
|
249 |
<bool>true</bool> |
|
250 |
</attribute> |
|
251 |
<attribute name="verticalHeaderVisible"> |
|
252 |
<bool>false</bool> |
|
253 |
</attribute> |
|
254 |
<column/> |
|
255 |
</widget> |
|
256 |
</widget> |
|
257 |
</item> |
|
259 | 258 |
</layout> |
260 | 259 |
</widget> |
261 | 260 |
<resources/> |
내보내기 Unified diff