提交 e15cf0d1 编写于 作者: qq_25193841's avatar qq_25193841

Merge remote-tracking branch 'origin/new' into table

...@@ -202,11 +202,8 @@ class MainWindow(QMainWindow): ...@@ -202,11 +202,8 @@ class MainWindow(QMainWindow):
self.reRecogButton.setIcon(newIcon('reRec', 30)) self.reRecogButton.setIcon(newIcon('reRec', 30))
self.reRecogButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.reRecogButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
self.cellreRecButton = QToolButton()
self.cellreRecButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
self.tableRecButton = QToolButton() self.tableRecButton = QToolButton()
self.tableRecButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.tableRecButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
self.newButton = QToolButton() self.newButton = QToolButton()
self.newButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.newButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
...@@ -221,9 +218,9 @@ class MainWindow(QMainWindow): ...@@ -221,9 +218,9 @@ class MainWindow(QMainWindow):
leftTopToolBox = QGridLayout() leftTopToolBox = QGridLayout()
leftTopToolBox.addWidget(self.newButton, 0, 0, 1, 1) leftTopToolBox.addWidget(self.newButton, 0, 0, 1, 1)
leftTopToolBox.addWidget(self.createpolyButton, 0, 1, 1, 1) leftTopToolBox.addWidget(self.createpolyButton, 0, 1, 1, 1)
leftTopToolBox.addWidget(self.reRecogButton, 0, 2, 1, 1) leftTopToolBox.addWidget(self.reRecogButton, 1, 0, 1, 1)
leftTopToolBox.addWidget(self.tableRecButton, 1, 0, 1, 1) leftTopToolBox.addWidget(self.tableRecButton, 1, 1, 1, 1)
leftTopToolBox.addWidget(self.cellreRecButton, 1, 1, 1, 1)
leftTopToolBoxContainer = QWidget() leftTopToolBoxContainer = QWidget()
leftTopToolBoxContainer.setLayout(leftTopToolBox) leftTopToolBoxContainer.setLayout(leftTopToolBox)
listLayout.addWidget(leftTopToolBoxContainer) listLayout.addWidget(leftTopToolBoxContainer)
...@@ -507,7 +504,6 @@ class MainWindow(QMainWindow): ...@@ -507,7 +504,6 @@ class MainWindow(QMainWindow):
self.AutoRecognition.setDefaultAction(AutoRec) self.AutoRecognition.setDefaultAction(AutoRec)
self.reRecogButton.setDefaultAction(reRec) self.reRecogButton.setDefaultAction(reRec)
self.tableRecButton.setDefaultAction(tableRec) self.tableRecButton.setDefaultAction(tableRec)
self.cellreRecButton.setDefaultAction(cellreRec)
# self.preButton.setDefaultAction(openPrevImg) # self.preButton.setDefaultAction(openPrevImg)
# self.nextButton.setDefaultAction(openNextImg) # self.nextButton.setDefaultAction(openNextImg)
...@@ -564,11 +560,11 @@ class MainWindow(QMainWindow): ...@@ -564,11 +560,11 @@ class MainWindow(QMainWindow):
rotateLeft=rotateLeft, rotateRight=rotateRight, lock=lock, exportJSON=exportJSON, rotateLeft=rotateLeft, rotateRight=rotateRight, lock=lock, exportJSON=exportJSON,
fileMenuActions=(opendir, open_dataset_dir, saveLabel, exportJSON, resetAll, quit), fileMenuActions=(opendir, open_dataset_dir, saveLabel, exportJSON, resetAll, quit),
beginner=(), advanced=(), beginner=(), advanced=(),
editMenu=(createpoly, edit, copy, delete, singleRere, None, undo, undoLastPoint, editMenu=(createpoly, edit, copy, delete, singleRere, cellreRec, None, undo, undoLastPoint,
None, rotateLeft, rotateRight, None, color1, self.drawSquaresOption, lock, None, rotateLeft, rotateRight, None, color1, self.drawSquaresOption, lock,
None, change_cls), None, change_cls),
beginnerContext=( beginnerContext=(
create, createpoly, edit, copy, delete, singleRere, rotateLeft, rotateRight, lock, change_cls), create, createpoly, edit, copy, delete, singleRere, cellreRec, rotateLeft, rotateRight, lock, change_cls),
advancedContext=(createMode, editMode, edit, copy, advancedContext=(createMode, editMode, edit, copy,
delete, shapeLineColor, shapeFillColor), delete, shapeLineColor, shapeFillColor),
onLoadActive=(create, createpoly, createMode, editMode), onLoadActive=(create, createpoly, createMode, editMode),
...@@ -1025,6 +1021,7 @@ class MainWindow(QMainWindow): ...@@ -1025,6 +1021,7 @@ class MainWindow(QMainWindow):
self._noSelectionSlot = False self._noSelectionSlot = False
n_selected = len(selected_shapes) n_selected = len(selected_shapes)
self.actions.singleRere.setEnabled(n_selected) self.actions.singleRere.setEnabled(n_selected)
self.actions.cellreRec.setEnabled(n_selected)
self.actions.delete.setEnabled(n_selected) self.actions.delete.setEnabled(n_selected)
self.actions.copy.setEnabled(n_selected) self.actions.copy.setEnabled(n_selected)
self.actions.edit.setEnabled(n_selected == 1) self.actions.edit.setEnabled(n_selected == 1)
...@@ -1690,12 +1687,10 @@ class MainWindow(QMainWindow): ...@@ -1690,12 +1687,10 @@ class MainWindow(QMainWindow):
self.haveAutoReced = False self.haveAutoReced = False
self.AutoRecognition.setEnabled(True) self.AutoRecognition.setEnabled(True)
self.reRecogButton.setEnabled(True) self.reRecogButton.setEnabled(True)
self.cellreRecButton.setEnabled(True)
self.tableRecButton.setEnabled(True) self.tableRecButton.setEnabled(True)
self.actions.AutoRec.setEnabled(True) self.actions.AutoRec.setEnabled(True)
self.actions.reRec.setEnabled(True) self.actions.reRec.setEnabled(True)
self.actions.tableRec.setEnabled(True) self.actions.tableRec.setEnabled(True)
self.actions.cellreRec.setEnabled(True)
self.actions.open_dataset_dir.setEnabled(True) self.actions.open_dataset_dir.setEnabled(True)
self.actions.rotateLeft.setEnabled(True) self.actions.rotateLeft.setEnabled(True)
self.actions.rotateRight.setEnabled(True) self.actions.rotateRight.setEnabled(True)
...@@ -2229,87 +2224,59 @@ class MainWindow(QMainWindow): ...@@ -2229,87 +2224,59 @@ class MainWindow(QMainWindow):
re-recognise text in a cell re-recognise text in a cell
''' '''
img = cv2.imread(self.filePath) img = cv2.imread(self.filePath)
for shape in self.canvas.selectedShapes:
box = [[int(p.x()), int(p.y())] for p in shape.points]
if self.canvas.shapes: if len(box) > 4:
self.result_dic = [] box = self.gen_quad_from_poly(np.array(box))
self.result_dic_locked = [] # result_dic_locked stores the ocr result of self.canvas.lockedShapes assert len(box) == 4
rec_flag = 0
for shape in self.canvas.shapes:
box = [[int(p.x()), int(p.y())] for p in shape.points]
if len(box) > 4: # pad around bbox for better text recognition accuracy
box = self.gen_quad_from_poly(np.array(box)) _box = boxPad(box, img.shape, 6)
assert len(box) == 4 img_crop = get_rotate_crop_image(img, np.array(_box, np.float32))
if img_crop is None:
msg = 'Can not recognise the detection box in ' + self.filePath + '. Please change manually'
QMessageBox.information(self, "Information", msg)
return
# pad around bbox for better text recognition accuracy # merge the text result in the cell
print(box) texts = ''
_box = boxPad(box, img.shape, 6) probs = 0. # the probability of the cell is avgerage prob of every text box in the cell
print(_box) bboxes = self.ocr.ocr(img_crop, det=True, rec=False, cls=False)
img_crop = get_rotate_crop_image(img, np.array(_box, np.float32)) if len(bboxes) > 0:
if img_crop is None: bboxes.reverse() # top row text at first
msg = 'Can not recognise the detection box in ' + self.filePath + '. Please change manually' for _bbox in bboxes:
QMessageBox.information(self, "Information", msg) patch = get_rotate_crop_image(img_crop, np.array(_bbox, np.float32))
return rec_res = self.ocr.ocr(patch, det=False, rec=True, cls=False)
# merge the text result in the cell text = rec_res[0][0]
texts = '' if text != '':
probs = 0. # the probability of the cell is avgerage prob of every text box in the cell texts += text + (' ' if text[0].isalpha() else '') # add space between english word
bboxes = self.ocr.ocr(img_crop, det=True, rec=False, cls=False) probs += rec_res[0][1]
if len(bboxes) > 0: probs = probs / len(bboxes)
bboxes.reverse() # top row text at first result = [(texts.strip(), probs)]
for _bbox in bboxes:
patch = get_rotate_crop_image(img_crop, np.array(_bbox, np.float32))
rec_res = self.ocr.ocr(patch, det=False, rec=True, cls=False)
text = rec_res[0][0]
if text != '':
texts += text + (' ' if text[0].isalpha() else '') # add space between english word
probs += rec_res[0][1]
probs = probs / len(bboxes)
result = [(texts.strip(), probs)]
if result[0][0] != '': if result[0][0] != '':
if shape.line_color == DEFAULT_LOCK_COLOR: result.insert(0, box)
shape.label = result[0][0] print('result in reRec is ', result)
result.insert(0, box) if result[1][0] == shape.label:
self.result_dic_locked.append(result) print('label no change')
else:
result.insert(0, box)
self.result_dic.append(result)
else:
print('Can not recognise the box')
if shape.line_color == DEFAULT_LOCK_COLOR:
shape.label = result[0][0]
self.result_dic_locked.append([box, (self.noLabelText, 0)])
else:
self.result_dic.append([box, (self.noLabelText, 0)])
try:
if self.noLabelText == shape.label or result[1][0] == shape.label:
print('label no change')
else:
rec_flag += 1
except IndexError as e:
print('Can not recognise the box')
if (len(self.result_dic) > 0 and rec_flag > 0) or self.canvas.lockedShapes:
self.canvas.isInTheSameImage = True
self.saveFile(mode='Auto')
self.loadFile(self.filePath)
self.canvas.isInTheSameImage = False
self.setDirty()
elif len(self.result_dic) == len(self.canvas.shapes) and rec_flag == 0:
if self.lang == 'ch':
QMessageBox.information(self, "Information", "识别结果保持一致!")
else: else:
QMessageBox.information(self, "Information", "The recognition result remains unchanged!") shape.label = result[1][0]
else: else:
print('Can not recgonise in ', self.filePath) print('Can not recognise the box')
else: if self.noLabelText == shape.label:
QMessageBox.information(self, "Information", "Draw a box!") print('label no change')
else:
shape.label = self.noLabelText
self.singleLabel(shape)
self.setDirty()
def exportJSON(self): def exportJSON(self):
''' '''
export PPLabel and CSV to JSON (PubTabNet) export PPLabel and CSV to JSON (PubTabNet)
''' '''
import pandas as pd import pandas as pd
from PyQt5.QtWidgets import QInputDialog from libs.dataPartitionDialog import DataPartitionDialog
if self.lang == 'ch': if self.lang == 'ch':
QMessageBox.information(self, "Information", "导出JSON前请保存所有图像的标注且关闭EXCEL!!!!!!!!!!!!") QMessageBox.information(self, "Information", "导出JSON前请保存所有图像的标注且关闭EXCEL!!!!!!!!!!!!")
...@@ -2346,18 +2313,18 @@ class MainWindow(QMainWindow): ...@@ -2346,18 +2313,18 @@ class MainWindow(QMainWindow):
# return # return
# data partition user input # data partition user input
train_split, ok = QInputDialog.getInt(self, "DataPatition", "How many data for Training (%):", 70, 0, 100, 1) partitionDialog = DataPartitionDialog()
if not ok: partitionDialog.exec()
return if partitionDialog.getStatus() == False:
val_split, ok = QInputDialog.getInt(self, "DataPatition", "How many data for Validatiion (%):", 15, 0, 100, 1)
if not ok:
return return
test_split, ok = QInputDialog.getInt(self, "DataPatition", "How many data for Testing (%):", 15, 0, 100, 1)
train_split, val_split, test_split = partitionDialog.getDataPartition()
# check validate
if train_split + val_split + test_split > 100: if train_split + val_split + test_split > 100:
QMessageBox.information(self, "Information", "The sum of training, validation and testing data should be less than 100%") msg = "The sum of training, validation and testing data should be less than 100%"
QMessageBox.information(self, "Information", msg)
return return
print(train_split, val_split, test_split)
train_split, val_split, test_split = float(train_split) / 100., float(val_split) / 100., float(test_split) / 100. train_split, val_split, test_split = float(train_split) / 100., float(val_split) / 100., float(test_split) / 100.
train_id = int(len(labeldict) * train_split) train_id = int(len(labeldict) * train_split)
val_id = int(len(labeldict) * (train_split + val_split)) val_id = int(len(labeldict) * (train_split + val_split))
...@@ -2407,7 +2374,7 @@ class MainWindow(QMainWindow): ...@@ -2407,7 +2374,7 @@ class MainWindow(QMainWindow):
with open("{}/annotation.json".format(self.lastOpenDir), "w") as fid: with open("{}/annotation.json".format(self.lastOpenDir), "w") as fid:
fid.write(json.dumps(json_results)) fid.write(json.dumps(json_results))
msg = 'JSON sucessfully saved in ', "{}/annotation.json".format(self.lastOpenDir) msg = 'JSON sucessfully saved in {}/annotation.json'.format(self.lastOpenDir)
QMessageBox.information(self, "Information", msg) QMessageBox.information(self, "Information", msg)
def autolcm(self): def autolcm(self):
......
try:
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
except ImportError:
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from libs.utils import newIcon
import time
import datetime
import json
import cv2
import numpy as np
BB = QDialogButtonBox
class DataPartitionDialog(QDialog):
def __init__(self):
super().__init__()
self.title = 'DATA PARTITION'
self.train_ratio = 70
self.val_ratio = 15
self.test_ratio = 15
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setWindowModality(Qt.ApplicationModal)
self.flag_accept = True
train_lbl = QLabel('Train split: ', self)
train_lbl.setFont(QFont('Arial', 15))
val_lbl = QLabel('Valid split: ', self)
val_lbl.setFont(QFont('Arial', 15))
test_lbl = QLabel('Test split: ', self)
test_lbl.setFont(QFont('Arial', 15))
self.train_input = QLineEdit(self)
self.train_input.setFont(QFont('Arial', 15))
self.val_input = QLineEdit(self)
self.val_input.setFont(QFont('Arial', 15))
self.test_input = QLineEdit(self)
self.test_input.setFont(QFont('Arial', 15))
self.train_input.setText(str(self.train_ratio))
self.val_input.setText(str(self.val_ratio))
self.test_input.setText(str(self.test_ratio))
validator = QIntValidator(0, 100)
self.train_input.setValidator(validator)
self.val_input.setValidator(validator)
self.test_input.setValidator(validator)
gridlayout = QGridLayout()
gridlayout.addWidget(train_lbl, 0, 0)
gridlayout.addWidget(val_lbl, 1, 0)
gridlayout.addWidget(test_lbl, 2, 0)
gridlayout.addWidget(self.train_input, 0, 1)
gridlayout.addWidget(self.val_input, 1, 1)
gridlayout.addWidget(self.test_input, 2, 1)
bb = BB(BB.Ok | BB.Cancel, Qt.Horizontal, self)
bb.button(BB.Ok).setIcon(newIcon('done'))
bb.button(BB.Cancel).setIcon(newIcon('undo'))
bb.accepted.connect(self.validate)
bb.rejected.connect(self.cancel)
gridlayout.addWidget(bb, 3, 0, 1, 2)
self.setLayout(gridlayout)
self.show()
def validate(self):
self.flag_accept = True
self.accept()
def cancel(self):
self.flag_accept = False
self.reject()
def getStatus(self):
return self.flag_accept
def getDataPartition(self):
self.train_ratio = int(self.train_input.text())
self.val_ratio = int(self.val_input.text())
self.test_ratio = int(self.test_input.text())
return self.train_ratio, self.val_ratio, self.test_ratio
def closeEvent(self, event):
self.flag_accept = False
self.reject()
...@@ -84,7 +84,7 @@ mhelp=Help ...@@ -84,7 +84,7 @@ mhelp=Help
iconList=Icon List iconList=Icon List
detectionBoxposition=Detection box position detectionBoxposition=Detection box position
recognitionResult=Recognition result recognitionResult=Recognition result
creatPolygon=Create Quadrilateral creatPolygon=Create PolygonBox
rotateLeft=Left turn 90 degrees rotateLeft=Left turn 90 degrees
rotateRight=Right turn 90 degrees rotateRight=Right turn 90 degrees
drawSquares=Draw Squares drawSquares=Draw Squares
......
...@@ -84,7 +84,7 @@ mhelp=帮助 ...@@ -84,7 +84,7 @@ mhelp=帮助
iconList=缩略图 iconList=缩略图
detectionBoxposition=检测框位置 detectionBoxposition=检测框位置
recognitionResult=识别结果 recognitionResult=识别结果
creatPolygon=四点标注 creatPolygon=多边形标注
drawSquares=正方形标注 drawSquares=正方形标注
rotateLeft=图片左旋转90度 rotateLeft=图片左旋转90度
rotateRight=图片右旋转90度 rotateRight=图片右旋转90度
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册