修复PPStructureV3多表格问题
相关 Issue
https://github.com/PaddlePaddle/PaddleOCR/issues/17133
问题描述
使用 PPStructureV3 处理包含多个表格的图片时,单元格检测结果会出现混乱。问题原因如下:
-
后处理 NMS 排序问题:当多个表格裁剪区域在单个批次中处理时,NMS 后检测结果的排序可能会发生变化,导致单元格分配不再与其原始表格对齐。
-
错误的分组逻辑:原代码依赖扁平化预测结果的顺序(使用
box_nums切片),而不是使用批次索引(batch_inds)将检测结果分组回其源表格。 -
单表格正常,多表格失败:单个表格时一切正常,但一旦多个裁剪区域被批处理在一起,就会出现单元格混合。
解决方案
将分组逻辑改为依赖每个检测结果的 batch_idx(batch_inds),而不是依赖扁平化预测结果的顺序。这确保了即使在 NMS 后重新排序的情况下也能正确分组。
实现细节
-
优先级 1:从原始 RT-DETR 输出中提取 batch_inds
- 检查所有模型输出以识别
batch_inds(与 boxes 长度匹配的 1D 整数数组) - 区分
batch_inds和 masks(Instance Segmentation 中通常是 3D 数组)
- 检查所有模型输出以识别
-
优先级 2:从 box_nums 构造 batch_inds(回退方案)
- 仅在
len(boxes) == sum(box_nums)时构造batch_inds(boxes 未被 NMS 重新排序) - 这为
batch_inds不可用的情况提供了回退方案
- 仅在
-
优先级 3:使用 batch_inds 进行分组
- 使用布尔掩码按
batch_idx分组检测结果,而不是顺序切片 - 这确保了无论 NMS 后如何排序都能正确分组
- 使用布尔掩码按
-
回退:原始方法
- 如果无法确定
batch_inds,则回退到原始的box_nums切片方法以保持向后兼容性
- 如果无法确定
修改内容
修改的文件
paddlex/inference/models/object_detection/predictor.py- 修改
_format_output()方法,使用batch_inds对检测结果进行分组 - 添加从 RT-DETR 模型输出中检测/提取
batch_inds的逻辑 - 添加在可能时从
box_nums构造batch_inds的回退机制 - 保持与原始切片方法的向后兼容性
- 修改
关键代码变更
# 修改前:基于 box_nums 的顺序切片
for idx in range(len(pred[1])):
np_boxes_num = pred[1][idx]
box_idx_end = box_idx_start + np_boxes_num
np_boxes = pred[0][box_idx_start:box_idx_end] # 假设 boxes 有序
pred_box.append(np_boxes)
box_idx_start = box_idx_end
# 修改后:使用 batch_idx 通过布尔掩码分组
if batch_inds is not None:
for batch_id in np.unique(batch_inds):
mask = batch_inds == batch_id
np_boxes = pred[0][mask] # 即使在 NMS 重新排序后也能正确分组
pred_box.append(np_boxes)
Thanks for your contribution!
@scyyh11 请问你那复现出 issue #17133的问题结果了吗?我这边跑用户给的 demo 图如下是没问题的?也请提供一下复现的环境!
@scyyh11 请问你那复现出 issue #17133的问题结果了吗?我这边跑用户给的 demo 图如下是没问题的?也请提供一下复现的环境!
您好,我这边也没有复现成功issue里的问题,这个pr做的是预防性的修改。
那能提供一下能触发你修改逻辑的 case 吗?谢谢
@leo-q8 我在本地测试时候没有遇到过这个问题,在原issue下有其他用户提供了自己的解决方案,我调查后认为可行,就做了实现。
