PaddleX icon indicating copy to clipboard operation
PaddleX copied to clipboard

修复PPStructureV3多表格问题

Open scyyh11 opened this issue 1 month ago • 5 comments

相关 Issue

https://github.com/PaddlePaddle/PaddleOCR/issues/17133

问题描述

使用 PPStructureV3 处理包含多个表格的图片时,单元格检测结果会出现混乱。问题原因如下:

  1. 后处理 NMS 排序问题:当多个表格裁剪区域在单个批次中处理时,NMS 后检测结果的排序可能会发生变化,导致单元格分配不再与其原始表格对齐。

  2. 错误的分组逻辑:原代码依赖扁平化预测结果的顺序(使用 box_nums 切片),而不是使用批次索引(batch_inds)将检测结果分组回其源表格。

  3. 单表格正常,多表格失败:单个表格时一切正常,但一旦多个裁剪区域被批处理在一起,就会出现单元格混合。

解决方案

将分组逻辑改为依赖每个检测结果的 batch_idx(batch_inds),而不是依赖扁平化预测结果的顺序。这确保了即使在 NMS 后重新排序的情况下也能正确分组。

实现细节

  1. 优先级 1:从原始 RT-DETR 输出中提取 batch_inds

    • 检查所有模型输出以识别 batch_inds(与 boxes 长度匹配的 1D 整数数组)
    • 区分 batch_inds 和 masks(Instance Segmentation 中通常是 3D 数组)
  2. 优先级 2:从 box_nums 构造 batch_inds(回退方案)

    • 仅在 len(boxes) == sum(box_nums) 时构造 batch_inds(boxes 未被 NMS 重新排序)
    • 这为 batch_inds 不可用的情况提供了回退方案
  3. 优先级 3:使用 batch_inds 进行分组

    • 使用布尔掩码按 batch_idx 分组检测结果,而不是顺序切片
    • 这确保了无论 NMS 后如何排序都能正确分组
  4. 回退:原始方法

    • 如果无法确定 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)

scyyh11 avatar Nov 22 '25 01:11 scyyh11

Thanks for your contribution!

paddle-bot[bot] avatar Nov 22 '25 01:11 paddle-bot[bot]

@scyyh11 请问你那复现出 issue #17133的问题结果了吗?我这边跑用户给的 demo 图如下是没问题的?也请提供一下复现的环境! image

leo-q8 avatar Dec 08 '25 07:12 leo-q8

@scyyh11 请问你那复现出 issue #17133的问题结果了吗?我这边跑用户给的 demo 图如下是没问题的?也请提供一下复现的环境! image

您好,我这边也没有复现成功issue里的问题,这个pr做的是预防性的修改。

scyyh11 avatar Dec 08 '25 07:12 scyyh11

那能提供一下能触发你修改逻辑的 case 吗?谢谢

leo-q8 avatar Dec 08 '25 07:12 leo-q8

@leo-q8 我在本地测试时候没有遇到过这个问题,在原issue下有其他用户提供了自己的解决方案,我调查后认为可行,就做了实现。

scyyh11 avatar Dec 08 '25 07:12 scyyh11