Skip to content

Commit c27ef01

Browse files
authored
1、PPOCRLabel现在支持从中文路径导入图片,原本导入含中文路径的图片会导致崩溃。 (#11236)
2、PPOCRLabel现在支持移动被其他框覆盖的锚点,原本无法移动被覆盖的锚点。 3、修复utility.py中误输入字符导致的语法错误。 4、修复setValue()应输入int,实际输入float导致的类型错误。 5、修复paddleocr中未import predict_system的错误。 6、修复canvas.py中部分输入参数类型错误 7、修复了LabelList不兼容搜狗输入法或win11输入法的问题。原本使用搜狗输入法修改标注数据时,仅输入一个字母就会失去焦点并提交数据变更,导致无法输入完整的汉字。现在将处理逻辑改为失去焦点时仍不提交数据变更,直到切换item或按下enter键才提交。 8、新增扩大选框的功能 1、PPOCRLabel now supports importing images from Chinese paths, originally importing images containing Chinese paths would cause a crash. 2、PPOCRLabel now supports moving anchor points that are covered by other boxes, originally it could not move the covered anchor points. 3、Fix the syntax error caused by mistakenly inputting characters in utility.py. 4、Repair the type error caused by inputting int but float in setValue(). 5、Repair the error of not import predict_system in paddleocr. 6、Fix some input parameter type errors in canvas.py. 7、LabelList can't use Sogou Input Method or Win11 Input Method to input text. 8、Add function of expand box.
1 parent 987cc84 commit c27ef01

File tree

5 files changed

+77
-42
lines changed

5 files changed

+77
-42
lines changed

PPOCRLabel.py

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import platform
2222
import subprocess
2323
import sys
24+
import traceback
25+
2426
import xlrd
2527
from functools import partial
2628

@@ -536,6 +538,8 @@ def __init__(self,
536538

537539
lock = action(getStr("lockBox"), self.lockSelectedShape,
538540
None, "lock", getStr("lockBoxDetail"), enabled=False)
541+
expand = action(getStr("expandBox"), self.expandSelectedShape,
542+
"Ctrl+K", "expand", getStr("expandBoxDetail"), enabled=False)
539543

540544
self.editButton.setDefaultAction(edit)
541545
self.newButton.setDefaultAction(create)
@@ -598,14 +602,14 @@ def __init__(self,
598602
fitWindow=fitWindow, fitWidth=fitWidth,
599603
zoomActions=zoomActions, saveLabel=saveLabel, change_cls=change_cls,
600604
undo=undo, undoLastPoint=undoLastPoint, open_dataset_dir=open_dataset_dir,
601-
rotateLeft=rotateLeft, rotateRight=rotateRight, lock=lock, exportJSON=exportJSON,
605+
rotateLeft=rotateLeft, rotateRight=rotateRight, lock=lock, exportJSON=exportJSON,expand=expand,
602606
fileMenuActions=(opendir, open_dataset_dir, saveLabel, exportJSON, resetAll, quit),
603607
beginner=(), advanced=(),
604608
editMenu=(createpoly, edit, copy, delete, singleRere, cellreRec, None, undo, undoLastPoint,
605-
None, rotateLeft, rotateRight, None, color1, self.drawSquaresOption, lock,
609+
None, rotateLeft, rotateRight, None, color1, self.drawSquaresOption, lock,expand,
606610
None, change_cls),
607611
beginnerContext=(
608-
create, createpoly, edit, copy, delete, singleRere, cellreRec, rotateLeft, rotateRight, lock, change_cls),
612+
create, createpoly, edit, copy, delete, singleRere, cellreRec, rotateLeft, rotateRight, lock,expand,change_cls),
609613
advancedContext=(createMode, editMode, edit, copy,
610614
delete, shapeLineColor, shapeFillColor),
611615
onLoadActive=(create, createpoly, createMode, editMode),
@@ -1093,6 +1097,7 @@ def shapeSelectionChanged(self, selected_shapes):
10931097
self.actions.edit.setEnabled(n_selected == 1)
10941098
self.actions.lock.setEnabled(n_selected)
10951099
self.actions.change_cls.setEnabled(n_selected)
1100+
self.actions.expand.setEnabled(n_selected)
10961101

10971102
def addLabel(self, shape):
10981103
shape.paintLabel = self.displayLabelOption.isChecked()
@@ -1259,8 +1264,8 @@ def copySelectedShape(self):
12591264
# self.shapeSelectionChanged(True)
12601265

12611266
def move_scrollbar(self, value):
1262-
self.labelListBar.setValue(value)
1263-
self.indexListBar.setValue(value)
1267+
self.labelListBar.setValue(int(value))
1268+
self.indexListBar.setValue(int(value))
12641269

12651270
def labelSelectionChanged(self):
12661271
if self._noSelectionSlot:
@@ -1405,9 +1410,9 @@ def _update_shape_color(self, shape):
14051410
shape.line_color = QColor(r, g, b)
14061411
shape.vertex_fill_color = QColor(r, g, b)
14071412
shape.hvertex_fill_color = QColor(255, 255, 255)
1408-
shape.fill_color = QColor(r, g, b, 128)
1413+
shape.fill_color = QColor(r, g, b, 32)
14091414
shape.select_line_color = QColor(255, 255, 255)
1410-
shape.select_fill_color = QColor(r, g, b, 155)
1415+
shape.select_fill_color = QColor(r, g, b, 32)
14111416

14121417
def _get_rgb_by_label(self, label, kie_mode):
14131418
shift_auto_shape_color = 2 # use for random color
@@ -1422,17 +1427,17 @@ def _get_rgb_by_label(self, label, kie_mode):
14221427
def scrollRequest(self, delta, orientation):
14231428
units = - delta / (8 * 15)
14241429
bar = self.scrollBars[orientation]
1425-
bar.setValue(bar.value() + bar.singleStep() * units)
1430+
bar.setValue(int(bar.value() + bar.singleStep() * units))
14261431

14271432
def setZoom(self, value):
14281433
self.actions.fitWidth.setChecked(False)
14291434
self.actions.fitWindow.setChecked(False)
14301435
self.zoomMode = self.MANUAL_ZOOM
1431-
self.zoomWidget.setValue(value)
1436+
self.zoomWidget.setValue(int(value))
14321437

14331438
def addZoom(self, increment=10):
1434-
self.setZoom(self.zoomWidget.value() + increment)
1435-
self.imageSlider.setValue(self.zoomWidget.value() + increment) # set zoom slider value
1439+
self.setZoom(int(self.zoomWidget.value() + increment))
1440+
self.imageSlider.setValue(int(self.zoomWidget.value() + increment)) # set zoom slider value
14361441

14371442
def zoomRequest(self, delta):
14381443
# get the current scrollbar positions
@@ -1483,8 +1488,8 @@ def zoomRequest(self, delta):
14831488
new_h_bar_value = h_bar.value() + move_x * d_h_bar_max
14841489
new_v_bar_value = v_bar.value() + move_y * d_v_bar_max
14851490

1486-
h_bar.setValue(new_h_bar_value)
1487-
v_bar.setValue(new_v_bar_value)
1491+
h_bar.setValue(int(new_h_bar_value))
1492+
v_bar.setValue(int(new_v_bar_value))
14881493

14891494
def setFitWindow(self, value=True):
14901495
if value:
@@ -1957,10 +1962,11 @@ def deleteImg(self):
19571962
deleteInfo = self.deleteImgDialog()
19581963
if deleteInfo == QMessageBox.Yes:
19591964
if platform.system() == 'Windows':
1960-
from win32com.shell import shell, shellcon
1961-
shell.SHFileOperation((0, shellcon.FO_DELETE, deletePath, None,
1962-
shellcon.FOF_SILENT | shellcon.FOF_ALLOWUNDO | shellcon.FOF_NOCONFIRMATION,
1963-
None, None))
1965+
# from win32com import shell, shellcon
1966+
# shell.SHFileOperation((0, shellcon.FO_DELETE, deletePath, None,
1967+
# shellcon.FOF_SILENT | shellcon.FOF_ALLOWUNDO | shellcon.FOF_NOCONFIRMATION,
1968+
# None, None))
1969+
os.remove(deletePath)
19641970
# linux
19651971
elif platform.system() == 'Linux':
19661972
cmd = 'trash ' + deletePath
@@ -2659,18 +2665,20 @@ def saveRecResult(self):
26592665
for key in self.fileStatedict:
26602666
idx = self.getImglabelidx(key)
26612667
try:
2662-
img = cv2.imread(key)
2668+
img = cv2.imdecode(np.fromfile(key, dtype=np.uint8), -1)
26632669
for i, label in enumerate(self.PPlabel[idx]):
26642670
if label['difficult']:
26652671
continue
26662672
img_crop = get_rotate_crop_image(img, np.array(label['points'], np.float32))
26672673
img_name = os.path.splitext(os.path.basename(idx))[0] + '_crop_' + str(i) + '.jpg'
2668-
cv2.imwrite(crop_img_dir + img_name, img_crop)
2674+
cv2.imencode(".jpg",img_crop)[1].tofile(crop_img_dir + img_name)
26692675
f.write('crop_img/' + img_name + '\t')
26702676
f.write(label['transcription'] + '\n')
2677+
except KeyError as e:
2678+
pass
26712679
except Exception as e:
26722680
ques_img.append(key)
2673-
print("Can not read image ", e)
2681+
traceback.print_exc()
26742682
if ques_img:
26752683
QMessageBox.information(self,
26762684
"Information",
@@ -2780,6 +2788,23 @@ def format_shape(s):
27802788
self.setDirty()
27812789
self.actions.save.setEnabled(True)
27822790

2791+
def expandSelectedShape(self):
2792+
img = cv2.imdecode(np.fromfile(self.filePath, dtype=np.uint8), 1)
2793+
for shape in self.canvas.selectedShapes:
2794+
box = [[int(p.x()), int(p.y())] for p in shape.points]
2795+
if len(box) > 4:
2796+
box = self.gen_quad_from_poly(np.array(box))
2797+
assert len(box) == 4
2798+
box = boxPad(box, img.shape, 3)
2799+
shape.points = [QPointF(box[0][0], box[0][1]),
2800+
QPointF(box[1][0], box[1][1]),
2801+
QPointF(box[2][0], box[2][1]),
2802+
QPointF(box[3][0], box[3][1])]
2803+
print(shape.points)
2804+
self.updateBoxlist()
2805+
self.setDirty()
2806+
2807+
27832808

27842809
def inverted(color):
27852810
return QColor(*[255 - v for v in color.getRgb()])

libs/canvas.py

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -232,22 +232,24 @@ def mouseMoveEvent(self, ev):
232232
self.setStatusTip(self.toolTip())
233233
self.update()
234234
break
235-
elif shape.containsPoint(pos):
236-
if self.selectedVertex():
237-
self.hShape.highlightClear()
238-
self.hVertex, self.hShape = None, shape
239-
self.setToolTip(
240-
"Click & drag to move shape '%s'" % shape.label)
241-
self.setStatusTip(self.toolTip())
242-
self.overrideCursor(CURSOR_GRAB)
243-
self.update()
244-
break
245-
else: # Nothing found, clear highlights, reset state.
246-
if self.hShape:
247-
self.hShape.highlightClear()
248-
self.update()
249-
self.hVertex, self.hShape = None, None
250-
self.overrideCursor(CURSOR_DEFAULT)
235+
else:
236+
for shape in reversed([s for s in self.shapes if self.isVisible(s)]):
237+
if shape.containsPoint(pos):
238+
if self.selectedVertex():
239+
self.hShape.highlightClear()
240+
self.hVertex, self.hShape = None, shape
241+
self.setToolTip(
242+
"Click & drag to move shape '%s'" % shape.label)
243+
self.setStatusTip(self.toolTip())
244+
self.overrideCursor(CURSOR_GRAB)
245+
self.update()
246+
break
247+
else: # Nothing found, clear highlights, reset state.
248+
if self.hShape:
249+
self.hShape.highlightClear()
250+
self.update()
251+
self.hVertex, self.hShape = None, None
252+
self.overrideCursor(CURSOR_DEFAULT)
251253

252254
def mousePressEvent(self, ev):
253255
pos = self.transformPos(ev.pos())
@@ -593,7 +595,7 @@ def paintEvent(self, event):
593595
p.setPen(self.drawingRectColor)
594596
brush = QBrush(Qt.BDiagPattern)
595597
p.setBrush(brush)
596-
p.drawRect(leftTop.x(), leftTop.y(), rectWidth, rectHeight)
598+
p.drawRect(int(leftTop.x()), int(leftTop.y()), int(rectWidth), int(rectHeight))
597599

598600

599601
# ADD:
@@ -611,8 +613,8 @@ def paintEvent(self, event):
611613

612614
if self.drawing() and not self.prevPoint.isNull() and not self.outOfPixmap(self.prevPoint):
613615
p.setPen(QColor(0, 0, 0))
614-
p.drawLine(int(self.prevPoint.x()), 0, int(self.prevPoint.x()), self.pixmap.height())
615-
p.drawLine(0, int(self.prevPoint.y()), self.pixmap.width(), int(self.prevPoint.y()))
616+
p.drawLine(int(self.prevPoint.x()), 0, int(self.prevPoint.x()), int(self.pixmap.height()))
617+
p.drawLine(0, int(self.prevPoint.y()), int(self.pixmap.width()), int(self.prevPoint.y()))
616618

617619
self.setAutoFillBackground(True)
618620
if self.verified:

libs/editinlist.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ def mouseDoubleClickEvent(self, event):
2424
pass
2525

2626
def leaveEvent(self, event):
27+
pass
28+
29+
def keyPressEvent(self, event) -> None:
2730
# close edit
28-
for i in range(self.count()):
29-
self.closePersistentEditor(self.item(i))
31+
if event.key() in [16777220, 16777221]:
32+
for i in range(self.count()):
33+
self.closePersistentEditor(self.item(i))

resources/strings/strings-en.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,5 @@ keyChange=Change Box Key
114114
TableRecognition=Table Recognition
115115
cellreRecognition=Cell Re-Recognition
116116
exportJSON=Export Table Label
117+
expandBox=Expand Box
118+
expandBoxDetail=Expand Box

resources/strings/strings-zh-CN.properties

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,6 @@ keyDialogTip=请输入类型名称
113113
keyChange=更改Box关键字类别
114114
TableRecognition=表格识别
115115
cellreRecognition=单元格重识别
116-
exportJSON=导出表格标注
116+
exportJSON=导出表格标注
117+
expandBox=扩大框
118+
expandBoxDetail=扩大所选框

0 commit comments

Comments
 (0)