Merge pull request #1656 from Evezerest/develop
Keep the develop branch of PPOCRLabel in sync with the dygraph branch
This commit is contained in:
commit
0275354c93
|
@ -106,7 +106,7 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||
getStr = lambda strId: self.stringBundle.getString(strId)
|
||||
|
||||
self.defaultSaveDir = defaultSaveDir
|
||||
self.ocr = PaddleOCR(use_pdserving=False, use_angle_cls=True, det=True, cls=True, use_gpu=True, lang=lang)
|
||||
self.ocr = PaddleOCR(use_pdserving=False, use_angle_cls=True, det=True, cls=True, use_gpu=False, lang=lang)
|
||||
|
||||
if os.path.exists('./data/paddle.png'):
|
||||
result = self.ocr.ocr('./data/paddle.png', cls=True, det=True)
|
||||
|
@ -257,9 +257,6 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||
self.imgsliderDock.setObjectName(getStr('IR'))
|
||||
self.imgsliderDock.setWidget(self.imgsplider)
|
||||
self.imgsliderDock.setFeatures(QDockWidget.DockWidgetFloatable)
|
||||
# op = QGraphicsOpacityEffect()
|
||||
# op.setOpacity(0.2)
|
||||
# self.imgsliderDock.setGraphicsEffect(op)
|
||||
self.imgsliderDock.setAttribute(Qt.WA_TranslucentBackground)
|
||||
self.addDockWidget(Qt.RightDockWidgetArea, self.imgsliderDock)
|
||||
|
||||
|
@ -277,6 +274,7 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||
self.preButton.setIconSize(QSize(40, 100))
|
||||
self.preButton.clicked.connect(self.openPrevImg)
|
||||
self.preButton.setStyleSheet('border: none;')
|
||||
self.preButton.setShortcut('a')
|
||||
self.iconlist = QListWidget()
|
||||
self.iconlist.setViewMode(QListView.IconMode)
|
||||
self.iconlist.setFlow(QListView.TopToBottom)
|
||||
|
@ -292,20 +290,16 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||
self.nextButton.setIconSize(QSize(40, 100))
|
||||
self.nextButton.setStyleSheet('border: none;')
|
||||
self.nextButton.clicked.connect(self.openNextImg)
|
||||
self.nextButton.setShortcut('d')
|
||||
|
||||
hlayout.addWidget(self.preButton)
|
||||
hlayout.addWidget(self.iconlist)
|
||||
hlayout.addWidget(self.nextButton)
|
||||
|
||||
# self.setLayout(hlayout)
|
||||
|
||||
iconListContainer = QWidget()
|
||||
iconListContainer.setLayout(hlayout)
|
||||
iconListContainer.setFixedHeight(100)
|
||||
# iconListContainer.setFixedWidth(530)
|
||||
# op = QGraphicsOpacityEffect()
|
||||
# op.setOpacity(0.5)
|
||||
# iconListContainer.setGraphicsEffect(op)
|
||||
|
||||
########### Canvas ###########
|
||||
self.canvas = Canvas(parent=self)
|
||||
|
@ -366,14 +360,6 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||
opendir = action(getStr('openDir'), self.openDirDialog,
|
||||
'Ctrl+u', 'open', getStr('openDir'))
|
||||
|
||||
openNextImg = action(getStr('nextImg'), self.openNextImg,
|
||||
'd', 'next', getStr('nextImgDetail'))
|
||||
|
||||
openPrevImg = action(getStr('prevImg'), self.openPrevImg,
|
||||
'a', 'prev', getStr('prevImgDetail'))
|
||||
|
||||
# verify = action(getStr('verifyImg'), self.verifyImg,
|
||||
# 'space', 'verify', getStr('verifyImgDetail'))
|
||||
|
||||
save = action(getStr('save'), self.saveFile,
|
||||
'Ctrl+V', 'verify', getStr('saveDetail'), enabled=False)
|
||||
|
@ -381,7 +367,7 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||
alcm = action(getStr('choosemodel'), self.autolcm,
|
||||
'Ctrl+M', 'next', getStr('tipchoosemodel'))
|
||||
|
||||
deleteImg = action(getStr('deleteImg'), self.deleteImg, 'Ctrl+D', 'close', getStr('deleteImgDetail'),
|
||||
deleteImg = action(getStr('deleteImg'), self.deleteImg, 'Ctrl+Shift+D', 'close', getStr('deleteImgDetail'),
|
||||
enabled=True)
|
||||
|
||||
resetAll = action(getStr('resetAll'), self.resetAll, None, 'resetall', getStr('resetAllDetail'))
|
||||
|
@ -398,7 +384,7 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||
'w', 'new', getStr('crtBoxDetail'), enabled=False)
|
||||
|
||||
delete = action(getStr('delBox'), self.deleteSelectedShape,
|
||||
'Delete', 'delete', getStr('delBoxDetail'), enabled=False)
|
||||
'backspace', 'delete', getStr('delBoxDetail'), enabled=False)
|
||||
copy = action(getStr('dupBox'), self.copySelectedShape,
|
||||
'Ctrl+C', 'copy', getStr('dupBoxDetail'),
|
||||
enabled=False)
|
||||
|
@ -456,8 +442,11 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||
reRec = action(getStr('reRecognition'), self.reRecognition,
|
||||
'Ctrl+Shift+R', 'reRec', getStr('reRecognition'), enabled=False)
|
||||
|
||||
singleRere = action(getStr('singleRe'), self.singleRerecognition,
|
||||
'Ctrl+R', 'reRec', getStr('singleRe'), enabled=False)
|
||||
|
||||
createpoly = action(getStr('creatPolygon'), self.createPolygon,
|
||||
'p', 'new', 'Creat Polygon', enabled=True)
|
||||
'q', 'new', 'Creat Polygon', enabled=True)
|
||||
|
||||
saveRec = action(getStr('saveRec'), self.saveRecResult,
|
||||
'', 'save', getStr('saveRec'), enabled=False)
|
||||
|
@ -501,9 +490,6 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||
icon='color', tip=getStr('shapeFillColorDetail'),
|
||||
enabled=False)
|
||||
|
||||
# labels = self.dock.toggleViewAction()
|
||||
# labels.setText(getStr('showHide'))
|
||||
# labels.setShortcut('Ctrl+Shift+L')
|
||||
|
||||
# Label list context menu.
|
||||
labelMenu = QMenu()
|
||||
|
@ -515,7 +501,6 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||
|
||||
# Draw squares/rectangles
|
||||
self.drawSquaresOption = QAction(getStr('drawSquares'), self)
|
||||
self.drawSquaresOption.setShortcut('Ctrl+Shift+R')
|
||||
self.drawSquaresOption.setCheckable(True)
|
||||
self.drawSquaresOption.setChecked(settings.get(SETTING_DRAW_SQUARE, False))
|
||||
self.drawSquaresOption.triggered.connect(self.toogleDrawSquare)
|
||||
|
@ -523,7 +508,7 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||
# Store actions for further handling.
|
||||
self.actions = struct(save=save, open=open, resetAll=resetAll, deleteImg=deleteImg,
|
||||
lineColor=color1, create=create, delete=delete, edit=edit, copy=copy,
|
||||
saveRec=saveRec,
|
||||
saveRec=saveRec, singleRere=singleRere,AutoRec=AutoRec,reRec=reRec,
|
||||
createMode=createMode, editMode=editMode,
|
||||
shapeLineColor=shapeLineColor, shapeFillColor=shapeFillColor,
|
||||
zoom=zoom, zoomIn=zoomIn, zoomOut=zoomOut, zoomOrg=zoomOrg,
|
||||
|
@ -532,9 +517,9 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||
fileMenuActions=(
|
||||
open, opendir, saveLabel, resetAll, quit),
|
||||
beginner=(), advanced=(),
|
||||
editMenu=(createpoly, edit, copy, delete,
|
||||
editMenu=(createpoly, edit, copy, delete,singleRere,
|
||||
None, color1, self.drawSquaresOption),
|
||||
beginnerContext=(create, edit, copy, delete),
|
||||
beginnerContext=(create, edit, copy, delete, singleRere),
|
||||
advancedContext=(createMode, editMode, edit, copy,
|
||||
delete, shapeLineColor, shapeFillColor),
|
||||
onLoadActive=(
|
||||
|
@ -576,7 +561,7 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||
zoomIn, zoomOut, zoomOrg, None,
|
||||
fitWindow, fitWidth))
|
||||
|
||||
addActions(self.menus.autolabel, (alcm, None, help)) #
|
||||
addActions(self.menus.autolabel, (AutoRec, reRec, alcm, None, help)) #
|
||||
|
||||
self.menus.file.aboutToShow.connect(self.updateFileMenu)
|
||||
|
||||
|
@ -586,16 +571,6 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||
action('&Copy here', self.copyShape),
|
||||
action('&Move here', self.moveShape)))
|
||||
|
||||
# self.tools = self.toolbar('Tools')
|
||||
|
||||
# self.actions.beginner = (
|
||||
# open, opendir, openNextImg, openPrevImg, verify, save, None, create, copy, delete, None,
|
||||
# zoomIn, zoom, zoomOut, fitWindow, fitWidth)
|
||||
#
|
||||
# self.actions.advanced = (
|
||||
# open, opendir, openNextImg, openPrevImg, save, None,
|
||||
# createMode, editMode, None,
|
||||
# hideAll, showAll)
|
||||
|
||||
self.statusBar().showMessage('%s started.' % __appname__)
|
||||
self.statusBar().show()
|
||||
|
@ -944,6 +919,7 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||
self.actions.edit.setEnabled(selected)
|
||||
self.actions.shapeLineColor.setEnabled(selected)
|
||||
self.actions.shapeFillColor.setEnabled(selected)
|
||||
self.actions.singleRere.setEnabled(selected)
|
||||
|
||||
def addLabel(self, shape):
|
||||
shape.paintLabel = self.displayLabelOption.isChecked()
|
||||
|
@ -1013,6 +989,19 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||
self.updateComboBox()
|
||||
self.canvas.loadShapes(s)
|
||||
|
||||
def singleLabel(self, shape):
|
||||
if shape is None:
|
||||
# print('rm empty label')
|
||||
return
|
||||
item = self.shapesToItems[shape]
|
||||
item.setText(shape.label)
|
||||
self.updateComboBox()
|
||||
|
||||
# ADD:
|
||||
item = self.shapesToItemsbox[shape]
|
||||
item.setText(str([(int(p.x()), int(p.y())) for p in shape.points]))
|
||||
self.updateComboBox()
|
||||
|
||||
def updateComboBox(self):
|
||||
# Get the unique labels and add them to the Combobox.
|
||||
itemsTextList = [str(self.labelList.item(i).text()) for i in range(self.labelList.count())]
|
||||
|
@ -1466,6 +1455,8 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||
self.haveAutoReced = False
|
||||
self.AutoRecognition.setEnabled(True)
|
||||
self.reRecogButton.setEnabled(True)
|
||||
self.actions.AutoRec.setEnabled(True)
|
||||
self.actions.reRec.setEnabled(True)
|
||||
self.actions.saveLabel.setEnabled(True)
|
||||
|
||||
|
||||
|
@ -1780,6 +1771,7 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||
self.loadFile(self.filePath) # ADD
|
||||
self.haveAutoReced = True
|
||||
self.AutoRecognition.setEnabled(False)
|
||||
self.actions.AutoRec.setEnabled(False)
|
||||
self.setDirty()
|
||||
self.saveCacheLabel()
|
||||
|
||||
|
@ -1819,6 +1811,27 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||
else:
|
||||
QMessageBox.information(self, "Information", "Draw a box!")
|
||||
|
||||
def singleRerecognition(self):
|
||||
img = cv2.imread(self.filePath)
|
||||
shape = self.canvas.selectedShape
|
||||
box = [[int(p.x()), int(p.y())] for p in shape.points]
|
||||
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
|
||||
result = self.ocr.ocr(img_crop, cls=True, det=False)
|
||||
if result[0][0] is not '':
|
||||
result.insert(0, box)
|
||||
print('result in reRec is ', result)
|
||||
if result[1][0] == shape.label:
|
||||
print('label no change')
|
||||
else:
|
||||
shape.label = result[1][0]
|
||||
self.singleLabel(shape)
|
||||
self.setDirty()
|
||||
print(box)
|
||||
|
||||
def autolcm(self):
|
||||
vbox = QVBoxLayout()
|
||||
|
@ -1850,6 +1863,7 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||
self.dialog.exec_()
|
||||
if self.filePath:
|
||||
self.AutoRecognition.setEnabled(True)
|
||||
self.actions.AutoRec.setEnabled(True)
|
||||
|
||||
|
||||
def modelChoose(self):
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
[English](README.md) | 简体中文
|
||||
|
||||
# PPOCRLabel
|
||||
|
||||
PPOCRLabel是一款适用于OCR领域的半自动化图形标注工具,使用python3和pyqt5编写,支持矩形框标注和四点标注模式,导出格式可直接用于PPOCR检测和识别模型的训练。
|
||||
|
||||
<img src="./data/gif/steps.gif" width="100%"/>
|
||||
|
||||
#### 近期更新
|
||||
|
||||
- 2020.12.18: 支持对单个标记框进行重新识别(by [ninetailskim](https://github.com/ninetailskim) ),完善快捷键。
|
||||
|
||||
## 安装
|
||||
|
||||
### 1. 安装PaddleOCR
|
||||
|
@ -43,7 +49,7 @@ python3 PPOCRLabel.py --lang ch
|
|||
1. 安装与运行:使用上述命令安装与运行程序。
|
||||
2. 打开文件夹:在菜单栏点击 “文件” - "打开目录" 选择待标记图片的文件夹<sup>[1]</sup>.
|
||||
3. 自动标注:点击 ”自动标注“,使用PPOCR超轻量模型对图片文件名前图片状态<sup>[2]</sup>为 “X” 的图片进行自动标注。
|
||||
4. 手动标注:点击 “矩形标注”(推荐直接在英文模式下点击键盘中的 “W”),用户可对当前图片中模型未检出的部分进行手动绘制标记框。点击键盘P,则使用四点标注模式(或点击“编辑” - “四点标注”),用户依次点击4个点后,双击左键表示标注完成。
|
||||
4. 手动标注:点击 “矩形标注”(推荐直接在英文模式下点击键盘中的 “W”),用户可对当前图片中模型未检出的部分进行手动绘制标记框。点击键盘Q,则使用四点标注模式(或点击“编辑” - “四点标注”),用户依次点击4个点后,双击左键表示标注完成。
|
||||
5. 标记框绘制完成后,用户点击 “确认”,检测框会先被预分配一个 “待识别” 标签。
|
||||
6. 重新识别:将图片中的所有检测画绘制/调整完成后,点击 “重新识别”,PPOCR模型会对当前图片中的**所有检测框**重新识别<sup>[3]</sup>。
|
||||
7. 内容更改:双击识别结果,对不准确的识别结果进行手动更改。
|
||||
|
@ -70,6 +76,26 @@ python3 PPOCRLabel.py --lang ch
|
|||
| crop_img | 识别数据。按照检测框切割后的图片。与rec_gt.txt同时产生。 |
|
||||
|
||||
## 说明
|
||||
|
||||
### 快捷键
|
||||
|
||||
| 快捷键 | 说明 |
|
||||
| ---------------- | ---------------------------- |
|
||||
| Ctrl + shift + A | 自动标注所有未确认过的图片 |
|
||||
| Ctrl + shift + R | 对当前图片的所有标记重新识别 |
|
||||
| W | 新建矩形框 |
|
||||
| Q | 新建四点框 |
|
||||
| Ctrl + E | 编辑所选框标签 |
|
||||
| Ctrl + R | 重新识别所选标记 |
|
||||
| Backspace | 删除所选框 |
|
||||
| Ctrl + V | 确认本张图片标记 |
|
||||
| Ctrl + Shift + d | 删除本张图片 |
|
||||
| D | 下一张图片 |
|
||||
| A | 上一张图片 |
|
||||
| Ctrl++ | 缩小 |
|
||||
| Ctrl-- | 放大 |
|
||||
| ↑→↓← | 移动标记框 |
|
||||
|
||||
### 内置模型
|
||||
|
||||
- 默认模型:PPOCRLabel默认使用PaddleOCR中的中英文超轻量OCR模型,支持中英文与数字识别,多种语言检测。
|
||||
|
@ -86,15 +112,23 @@ python3 PPOCRLabel.py --lang ch
|
|||
|
||||
### 错误提示
|
||||
- 如果同时使用whl包安装了paddleocr,其优先级大于通过paddleocr.py调用PaddleOCR类,whl包未更新时会导致程序异常。
|
||||
|
||||
- PPOCRLabel**不支持对中文文件名**的图片进行自动标注。
|
||||
- 对于Linux用户,如果您在打开软件过程中出现**objc[XXXXX]**开头的错误,证明您的opencv版本太高,建议安装4.2版本:
|
||||
```
|
||||
pip install opencv-python==4.2.0.32
|
||||
```
|
||||
- 如果出现''Missing string id '开头的错误,需要重新编译资源:
|
||||
```
|
||||
pyrcc5 -o libs/resources.py resources.qrc
|
||||
```
|
||||
|
||||
- 针对Linux用户::如果您在打开软件过程中出现**objc[XXXXX]**开头的错误,证明您的opencv版本太高,建议安装4.2版本:
|
||||
```
|
||||
pip install opencv-python==4.2.0.32
|
||||
```
|
||||
|
||||
- 如果出现 ```Missing string id``` 开头的错误,需要重新编译资源:
|
||||
```
|
||||
pyrcc5 -o libs/resources.py resources.qrc
|
||||
```
|
||||
|
||||
- 如果出现``` module 'cv2' has no attribute 'INTER_NEAREST'```错误,需要首先删除所有opencv相关包,然后重新安装headless版本的opencv
|
||||
```
|
||||
pip install opencv-contrib-python-headless
|
||||
```
|
||||
### 参考资料
|
||||
|
||||
1.[Tzutalin. LabelImg. Git code (2015)](https://github.com/tzutalin/labelImg)
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
English | [简体中文](README_ch.md)
|
||||
|
||||
# PPOCRLabel
|
||||
|
||||
PPOCRLabel is a semi-automatic graphic annotation tool suitable for OCR field. It is written in python3 and pyqt5, supporting rectangular box annotation and four-point annotation modes. Annotations can be directly used for the training of PPOCR detection and recognition models.
|
||||
|
||||
<img src="./data/gif/steps_en.gif" width="100%"/>
|
||||
|
||||
### Recent Update
|
||||
|
||||
- 2020.12.18: Support re-recognition of a single label box (by [ninetailskim](https://github.com/ninetailskim) ), perfect shortcut keys.
|
||||
|
||||
## Installation
|
||||
|
||||
### 1. Install PaddleOCR
|
||||
|
@ -54,7 +60,7 @@ python3 PPOCRLabel.py
|
|||
|
||||
4.1 Click 'Create RectBox' or press 'W' in English keyboard mode to draw a new rectangle detection box. Click and release left mouse to select a region to annotate the text area.
|
||||
|
||||
4.2 Press 'P' to enter four-point labeling mode which enables you to create any four-point shape by clicking four points with the left mouse button in succession and DOUBLE CLICK the left mouse as the signal of labeling completion.
|
||||
4.2 Press 'Q' to enter four-point labeling mode which enables you to create any four-point shape by clicking four points with the left mouse button in succession and DOUBLE CLICK the left mouse as the signal of labeling completion.
|
||||
|
||||
5. After the marking frame is drawn, the user clicks "OK", and the detection frame will be pre-assigned a "TEMPORARY" label.
|
||||
|
||||
|
@ -90,6 +96,25 @@ Therefore, if the recognition result has been manually changed before, it may ch
|
|||
|
||||
## Explanation
|
||||
|
||||
### Shortcut keys
|
||||
|
||||
| Shortcut keys | Description |
|
||||
| ---------------- | ------------------------------------------------ |
|
||||
| Ctrl + shift + A | Automatically label all unchecked images |
|
||||
| Ctrl + shift + R | Re-recognize all the labels of the current image |
|
||||
| W | Create a rect box |
|
||||
| Q | Create a four-points box |
|
||||
| Ctrl + E | Edit label of the selected box |
|
||||
| Ctrl + R | Re-recognize the selected box |
|
||||
| Backspace | Delete the selected box |
|
||||
| Ctrl + V | Check image |
|
||||
| Ctrl + Shift + d | Delete image |
|
||||
| D | Next image |
|
||||
| A | Previous image |
|
||||
| Ctrl++ | Zoom in |
|
||||
| Ctrl-- | Zoom out |
|
||||
| ↑→↓← | Move selected box |
|
||||
|
||||
### Built-in Model
|
||||
|
||||
- Default model: PPOCRLabel uses the Chinese and English ultra-lightweight OCR model in PaddleOCR by default, supports Chinese, English and number recognition, and multiple language detection.
|
||||
|
@ -111,13 +136,18 @@ For some data that are difficult to recognize, the recognition results will not
|
|||
|
||||
- For Linux users, if you get an error starting with **objc[XXXXX]** when opening the software, it proves that your opencv version is too high. It is recommended to install version 4.2:
|
||||
|
||||
```
|
||||
pip install opencv-python==4.2.0.32
|
||||
```
|
||||
```
|
||||
pip install opencv-python==4.2.0.32
|
||||
```
|
||||
- If you get an error starting with **Missing string id **,you need to recompile resources:
|
||||
```
|
||||
pyrcc5 -o libs/resources.py resources.qrc
|
||||
```
|
||||
pyrcc5 -o libs/resources.py resources.qrc
|
||||
```
|
||||
- If you get an error ``` module 'cv2' has no attribute 'INTER_NEAREST'```, you need to delete all opencv related packages first, and then reinstall the headless version of opencv
|
||||
```
|
||||
pip install opencv-contrib-python-headless
|
||||
```
|
||||
|
||||
### Related
|
||||
|
||||
1.[Tzutalin. LabelImg. Git code (2015)](https://github.com/tzutalin/labelImg)
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 3.9 MiB After Width: | Height: | Size: 4.8 MiB |
|
@ -46,9 +46,10 @@ class Worker(QThread):
|
|||
chars = res[1][0]
|
||||
cond = res[1][1]
|
||||
posi = res[0]
|
||||
strs += "Transcription: " + chars + " Probability: " + str(cond) + " Location: " + json.dumps(posi)
|
||||
strs += "Transcription: " + chars + " Probability: " + str(cond) + \
|
||||
" Location: " + json.dumps(posi) +'\n'
|
||||
# Sending large amounts of data repeatedly through pyqtSignal may affect the program efficiency
|
||||
# self.listValue.emit(strs) # It is better to remove this line
|
||||
self.listValue.emit(strs)
|
||||
self.mainThread.result_dic = self.result_dic
|
||||
self.mainThread.filePath = Imgpath
|
||||
# 保存
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -94,4 +94,5 @@ ok=确认
|
|||
autolabeling=自动标注中
|
||||
hideBox=隐藏所有标注
|
||||
showBox=显示所有标注
|
||||
saveLabel=保存标记结果
|
||||
saveLabel=保存标记结果
|
||||
singleRe=重识别此区块
|
|
@ -94,4 +94,5 @@ ok=OK
|
|||
autolabeling=Automatic Labeling
|
||||
hideBox=Hide All Box
|
||||
showBox=Show All Box
|
||||
saveLabel=Save Label
|
||||
saveLabel=Save Label
|
||||
singleRe=Re-recognition RectBox
|
Loading…
Reference in New Issue