Skip to content

Commit 6bb0480

Browse files
Remove difficult flag (#257)
1 parent 2862734 commit 6bb0480

6 files changed

Lines changed: 12 additions & 37 deletions

File tree

PPOCRLabel.py

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,8 +1229,6 @@ def get_str(str_id):
12291229
self.fillColor = None
12301230
self.zoom_level = 100
12311231
self.fit_window = False
1232-
# Add Chris
1233-
self.difficult = False
12341232

12351233
# Fix the compatible issue for qt4 and qt5. Convert the QStringList to python list
12361234
if settings.get(SETTING_RECENT_FILES):
@@ -1265,8 +1263,6 @@ def get_str(str_id):
12651263
settings.get(SETTING_FILL_COLOR, DEFAULT_FILL_COLOR)
12661264
)
12671265
self.canvas.setDrawingColor(self.lineColor)
1268-
# Add chris
1269-
Shape.difficult = self.difficult
12701266

12711267
# ADD:
12721268
# Populate the File menu dynamically.
@@ -1834,11 +1830,7 @@ def addLabel(self, shape):
18341830
shape.paintIdx = self.displayIndexOption.isChecked()
18351831

18361832
item = HashableQListWidgetItem(shape.label)
1837-
# current difficult checkbox is disable
1838-
# item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
1839-
# item.setCheckState(Qt.Unchecked) if shape.difficult else item.setCheckState(Qt.Checked)
18401833

1841-
# Checked means difficult is False
18421834
# item.setBackground(generateColorByText(shape.label))
18431835
self.itemsToShapes[item] = shape
18441836
self.shapesToItems[shape] = item
@@ -1891,7 +1883,7 @@ def remLabels(self, shapes):
18911883
def loadLabels(self, shapes):
18921884
s = []
18931885
shape_index = 0
1894-
for label, points, line_color, key_cls, difficult in shapes:
1886+
for label, points, line_color, key_cls in shapes:
18951887
shape = Shape(
18961888
label=label,
18971889
line_color=line_color,
@@ -1905,7 +1897,6 @@ def loadLabels(self, shapes):
19051897
self.setDirty()
19061898

19071899
shape.addPoint(QPointF(x, y))
1908-
shape.difficult = difficult
19091900
shape.idx = shape_index
19101901
shape_index += 1
19111902
# shape.locked = False
@@ -1962,7 +1953,6 @@ def format_shape(s):
19621953
line_color=s.line_color.getRgb(),
19631954
fill_color=s.fill_color.getRgb(),
19641955
points=[(int(p.x()), int(p.y())) for p in s.points], # QPonitF
1965-
difficult=s.difficult,
19661956
key_cls=s.key_cls,
19671957
) # bool
19681958

@@ -1976,7 +1966,7 @@ def format_shape(s):
19761966
]
19771967
# Can add different annotation formats here
19781968
for box in self.result_dic:
1979-
trans_dic = {"label": box[1][0], "points": box[0], "difficult": False}
1969+
trans_dic = {"label": box[1][0], "points": box[0]}
19801970
if self.kie_mode:
19811971
if len(box) == 3:
19821972
trans_dic.update({"key_cls": box[2]})
@@ -1992,7 +1982,7 @@ def format_shape(s):
19921982
trans_dict = {
19931983
"transcription": box["label"],
19941984
"points": box["points"],
1995-
"difficult": box["difficult"],
1985+
"difficult": False,
19961986
}
19971987
if self.kie_mode:
19981988
trans_dict.update({"key_cls": box["key_cls"]})
@@ -2070,14 +2060,6 @@ def labelItemChanged(self, item):
20702060
shape.label = item.text()
20712061
# shape.line_color = generateColorByText(shape.label)
20722062
self.setDirty()
2073-
elif not ((item.checkState() == Qt.Unchecked) ^ (not shape.difficult)):
2074-
shape.difficult = True if item.checkState() == Qt.Unchecked else False
2075-
self.setDirty()
2076-
else: # User probably changed item visibility
2077-
self.canvas.setShapeVisible(
2078-
shape, True
2079-
) # item.checkState() == Qt.Checked
2080-
# self.actions.save.setEnabled(True)
20812063
else:
20822064
logger.warning(
20832065
"enter labelItemChanged slot with unhashable item: %s %s",
@@ -2425,7 +2407,6 @@ def showBoundingBoxFromPPlabel(self, filePath):
24252407
[[s[0] * width, s[1] * height] for s in box["ratio"]],
24262408
DEFAULT_LOCK_COLOR,
24272409
key_cls,
2428-
box["difficult"],
24292410
)
24302411
)
24312412
else:
@@ -2435,7 +2416,6 @@ def showBoundingBoxFromPPlabel(self, filePath):
24352416
[[s[0] * width, s[1] * height] for s in box["ratio"]],
24362417
DEFAULT_LOCK_COLOR,
24372418
key_cls,
2438-
box["difficult"],
24392419
)
24402420
)
24412421
if img_idx in self.PPlabel.keys():
@@ -2447,7 +2427,6 @@ def showBoundingBoxFromPPlabel(self, filePath):
24472427
box["points"],
24482428
None,
24492429
key_cls,
2450-
box.get("difficult", False),
24512430
)
24522431
)
24532432

@@ -3333,7 +3312,6 @@ def TableRecognition(self):
33333312
# If not, fix them.
33343313
x, y, _ = self.canvas.snapPointToCanvas(x, y)
33353314
shape.addPoint(QPointF(x, y))
3336-
shape.difficult = False
33373315
shape.idx = order_index
33383316
order_index += 1
33393317
# shape.locked = False
@@ -3703,8 +3681,6 @@ def saveRecResult(self):
37033681
np.fromfile(img_path, dtype=np.uint8), cv2.IMREAD_COLOR
37043682
)
37053683
for i, label in enumerate(self.PPlabel[idx]):
3706-
if label["difficult"]:
3707-
continue
37083684
img_crop = get_rotate_crop_image(
37093685
img, np.array(label["points"], np.float32)
37103686
)
@@ -3818,7 +3794,6 @@ def format_shape(s):
38183794
ratio=[
38193795
[int(p.x()) / width, int(p.y()) / height] for p in s.points
38203796
], # QPonitF
3821-
difficult=s.difficult, # bool
38223797
key_cls=s.key_cls, # bool
38233798
)
38243799

@@ -3833,7 +3808,7 @@ def format_shape(s):
38333808
trans_dict = {
38343809
"transcription": box["label"],
38353810
"ratio": box["ratio"],
3836-
"difficult": box["difficult"],
3811+
"difficult": False,
38373812
}
38383813
if self.kie_mode:
38393814
trans_dict.update({"key_cls": box["key_cls"]})

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ PPOCRLabel.exe --lang ch
168168

169169
6. Click 're-Recognition', model will rewrite ALL recognition results in ALL detection box<sup>[3]</sup>.
170170

171-
7. Single click the result in 'recognition result' list to manually change inaccurate recognition results.
171+
7. Single click the result in 'recognition result' list to manually change inaccurate recognition results. **Note:** If the text is illegible or extremely blurry, it is recommended to change the label to `###`. The PaddleOCR training pipeline will treat these as "ignore" regions, ensuring they don't negatively impact your model's fine-tuning.
172172

173173
8. **Click "Check", the image status will switch to "√",then the program automatically jump to the next.**
174174

@@ -177,6 +177,8 @@ PPOCRLabel.exe --lang ch
177177
10. Labeling result: the user can export the label result manually through the menu "File - Export Label", while the program will also export automatically if "File - Auto export Label Mode" is selected. The manually checked label will be stored in *Label.txt* under the opened picture folder. Click "File"-"Export Recognition Results" in the menu bar, the recognition training data of such pictures will be saved in the *crop_img* folder, and the recognition label will be saved in *rec_gt.txt*<sup>[4]</sup>.
178178

179179
11. Additional Feature Description
180+
- **The "###" vs "*":** The core **PaddleOCR detection training pipeline** ignores boolean flags and specifically looks for the transcription string `###` or `*` to identify regions that should be ignored. For maximum compatibility with all fine-tuning stages (both Detection and Recognition), always use `###` for unreadable text.
181+
- **The "difficult" flag:** You may notice a `difficult` field in the exported `Label.txt`. This is a legacy field from the original `labelImg` tool. In this version of PPOCRLabel, this field is **hardcoded to `False`** for all exported labels to ensure backward compatibility with third-party data pipelines and older versions of the application while preventing unintended data exclusion during training exports.
180182
- `File` -> `Re-recognition`: After checking, the newly annotated box content will automatically trigger the `Re-recognition` function of the current annotation box, eliminating the need to click the Re-identify button. This is suitable for scenarios where you do not want to use Automatic Annotation but prefer manual annotation, such as license plate recognition. In a single image with only one license plate, using Automatic Annotation would require deleting many additional recognized text boxes, which is less efficient than directly re-annotating.
181183
- `File` -> `Auto Save Unsaved changes`: By default, you need to press the `Check` button to complete the marking confirmation for the current box, which can be cumbersome. After checking, when switching to the next image (by pressing the shortcut key `D`), a prompt box asking to confirm whether to save unconfirmed markings will no longer appear. The current markings will be automatically saved and the next image will be switched, making it convenient for quick marking.
182184
- After selecting the bounding box, there are 5 shortcut keys available to individually control the movement of the four vertices of the bounding box, suitable for scenarios that require precise control over the positions of the bounding box vertices:

README_ch.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,14 @@ PPOCRLabel.exe --lang ch
155155
4. 手动标注:点击 “矩形标注”(推荐直接在英文模式下点击键盘中的 “W”),用户可对当前图片中模型未检出的部分进行手动绘制标记框。点击键盘Q,则使用四点标注模式(或点击“编辑” - “四点标注”),用户依次点击4个点后,双击左键表示标注完成。
156156
5. 标记框绘制完成后,用户点击 “确认”,检测框会先被预分配一个 “待识别” 标签。
157157
6. 重新识别:将图片中的所有检测画绘制/调整完成后,点击 “重新识别”,PP-OCR模型会对当前图片中的**所有检测框**重新识别<sup>[3]</sup>。
158-
7. 内容更改:单击识别结果,对不准确的识别结果进行手动更改。
158+
7. 内容更改:单击识别结果,对不准确的识别结果进行手动更改。**注意:** 如果文字无法辨认或非常模糊,建议将标签修改为 `###`。PaddleOCR 训练流程会将其视为“忽略”区域,避免其对模型微调产生负面影响。
159+
159160
8. **确认标记:点击 “确认”,图片状态切换为 “√”,跳转至下一张。**
160161
9. 删除:点击 “删除图像”,图片将会被删除至回收站。
161162
10. 导出结果:用户可以通过菜单中“文件-导出标记结果”手动导出,同时也可以点击“文件 - 自动导出标记结果”开启自动导出。手动确认过的标记将会被存放在所打开图片文件夹下的*Label.txt*中。在菜单栏点击 “文件” - "导出识别结果"后,会将此类图片的识别训练数据保存在*crop_img*文件夹下,识别标签保存在*rec_gt.txt*中<sup>[4]</sup>。
162-
11. 补充功能说明
163+
11. 其他功能说明
164+
- **“###” 与 “*” 的区别:** 核心的 **PaddleOCR 检测训练流程** 会忽略布尔标志,并专门查找转录字符串 `###``*` 来识别应忽略的区域。因此,为了最大限度地兼容所有微调阶段(检测和识别),对于无法辨认的文字,请始终使用 `###`
165+
- **“difficult” 标志:** 您可能会在导出的 `Label.txt` 中注意到 `difficult` 字段。这是一个源自原始 `labelImg` 工具的遗留字段。在此版本的 PPOCRLabel 中,此字段已 **硬编码为 `False`**,以确保与第三方数据流水线和旧版本应用程序的后向兼容性,同时防止在训练导出期间意外排除数据。
163166
- `文件` -> `自动重新识别` : 勾选后,对于新标注的框内容会自动触发当前标注框的重新识别功能,不需要再去点击`重新识别`按钮,适合各种原因不想使用`自动标注`只想手动标注的场景,例如车牌识别,一张图里只有一个车牌,如果使用`自动标注`,需要删除很多额外识别出来的文字框,不如直接重新标注
164167
- `文件` -> `自动保存未提交变更` : 默认是按`确认`按钮完成当前框的标记确认,有点繁琐,勾选后,切换下一张图(按快捷键`D`)的时候,不再弹出提示框确认是否保存未确认的标记,自动保存当前标记并切换下一张图,方便快速标记
165168
- 选中标记框后,5个可以控制标记框四个顶点单独移动的快捷键,适合需要精确控制标记框四个顶点位置的场景

libs/shape.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ def __init__(
5353
self,
5454
label=None,
5555
line_color=None,
56-
difficult=False,
5756
key_cls="None",
5857
paintLabel=False,
5958
paintIdx=False,
@@ -64,7 +63,6 @@ def __init__(
6463
self.points = []
6564
self.fill = False
6665
self.selected = False
67-
self.difficult = difficult
6866
self.key_cls = key_cls
6967
self.paintLabel = paintLabel
7068
self.paintIdx = paintIdx
@@ -268,7 +266,6 @@ def copy(self):
268266
shape.line_color = self.line_color
269267
if self.fill_color != Shape.fill_color:
270268
shape.fill_color = self.fill_color
271-
shape.difficult = self.difficult
272269
shape.key_cls = self.key_cls
273270
return shape
274271

resources/strings/strings-en.properties

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ shapeFillColor=Shape Fill Color
5757
shapeFillColorDetail=Change the fill color for this specific shape
5858
showHide=Show/Hide Label Panel
5959
useDefaultLabel=Use default label
60-
useDifficult=Difficult
6160
boxLabelText=Box Labels
6261
labels=Labels
6362
autoSaveMode=Auto Save mode

resources/strings/strings-zh-CN.properties

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ focusAndZoom=聚焦缩放
5757
focusAndZoomDetail=聚焦并缩放至所选框
5858
nextImg=下一张
5959
useDefaultLabel=使用预设标签
60-
useDifficult=有难度的
6160
boxLabelText=区块的标签
6261
labels=标签
6362
autoSaveMode=自动保存模式

0 commit comments

Comments
 (0)