使用table_recognition_v2产线,关键参数use_wired_table_cells_trans_to_html: use_wired_table_cells_trans_to_html:启用有线表单元格直转HTML模式,启用时直接基于有线表单元格检测模型预测的各单元格位置排布与几何关系构建HTML结构。此模式在不同场景下效果不同,请根据实际情况选择。一般来说,建议在有线表单元格检测非常准确的场景下开启此模式,以获得更加准确的端到端表格识别结果。
不启用表格结构识别模块预测得到表格的HTML结构
去掉其他干扰模型
outputs = pipeline.predict(
img_path,
use_doc_orientation_classify=False,
use_doc_unwarping=False,
use_layout_detection=True,
use_ocr_results_with_table_cells=True,
use_table_orientation_classify=False,
use_wired_table_cells_trans_to_html=True,
# 新增:关闭单元格内拆分,整格识别以保留折行文本,
# 修改paddlex/inference/pipelines/table_recognition/pipeline_v2.py
# get_table_recognition_res传入参数self.cells_split_ocr=False,保证单元格内换行不被拆分
use_table_cells_split_ocr=False,
)
正在收集工作区信息正在筛选到最相关的信息看起来不是“表格结构定位”问题,而是表格内容填充阶段把同一单元格里的折行文本做了“分段重识别/分裂”,只保留了其中一段(常见为最后一行“款”),导致“扫二维码付”被丢弃。
原因定位
_TableRecognitionPipelineV2.predict 和单元格内容合成逻辑:get_table_recognition_res。关闭“单元格内拆分重识别”,直接对整格做一次OCR,再把同格内多行按阅读顺序拼接。为此给 table_recognition_v2 暴露一个开关 use_table_cells_split_ocr,并传到后处理。
修改1:在管线里增加开关并传给后处理
# ...existing code...
class _TableRecognitionPipelineV2(BasePipeline):
# ...existing code...
def predict(
self,
input: Union[str, List[str], np.ndarray, List[np.ndarray]],
use_doc_orientation_classify: Optional[bool] = None,
use_doc_unwarping: Optional[bool] = None,
use_layout_detection: Optional[bool] = None,
use_ocr_model: Optional[bool] = None,
overall_ocr_res: Optional[OCRResult] = None,
layout_det_res: Optional[DetResult] = None,
text_det_limit_side_len: Optional[int] = None,
text_det_limit_type: Optional[str] = None,
text_det_thresh: Optional[float] = None,
text_det_box_thresh: Optional[float] = None,
text_det_unclip_ratio: Optional[float] = None,
text_rec_score_thresh: Optional[float] = None,
use_e2e_wired_table_rec_model: bool = False,
use_e2e_wireless_table_rec_model: bool = False,
use_wired_table_cells_trans_to_html: bool = False,
use_wireless_table_cells_trans_to_html: bool = False,
use_table_orientation_classify: bool = True,
use_ocr_results_with_table_cells: bool = True,
**kwargs,
) -> TableRecognitionResult:
# 新增:允许外部控制单元格内是否拆分重识别(默认保持兼容 True)
use_table_cells_split_ocr = kwargs.get("use_table_cells_split_ocr", None)
self.cells_split_ocr = (
bool(use_table_cells_split_ocr) if use_table_cells_split_ocr is not None else True
)
# ...existing code...
def predict_single_table_recognition_res(
self,
image_array: np.ndarray,
overall_ocr_res: OCRResult,
table_box: list,
use_e2e_wired_table_rec_model: bool = False,
use_e2e_wireless_table_rec_model: bool = False,
use_wired_table_cells_trans_to_html: bool = False,
use_wireless_table_cells_trans_to_html: bool = False,
use_ocr_results_with_table_cells: bool = True,
flag_find_nei_text: bool = True,
) -> SingleTableRecognitionResult:
# ...existing code,完成 table_structure_result / table_cells_result / table_ocr_pred / cells_texts_list 的产生后...
single_table_recognition_res = get_table_recognition_res(
table_box,
table_structure_result,
table_cells_result,
overall_ocr_res,
table_ocr_pred,
cells_texts_list,
use_ocr_results_with_table_cells,
self.cells_split_ocr, # 传递新增开关
)
# ...existing code...
说明
get_table_recognition_res 已有 use_table_cells_split_ocr 参数,传 True 时走“拆分重识别”,传 False 时用整格OCR结果,不会丢掉折行。修改2:调用处传入开关(你的脚本)
# ...existing code...
outputs = pipeline.predict(
img_path,
use_doc_orientation_classify=False,
use_doc_unwarping=False,
use_layout_detection=True,
use_ocr_results_with_table_cells=True,
use_table_orientation_classify=False,
use_wired_table_cells_trans_to_html=True,
# 新增:关闭单元格内拆分,整格识别以保留折行文本
use_table_cells_split_ocr=False,
)
# ...existing code...
正在收集工作区信息正在筛选到最相关的信息基于你的想法,使用 BeautifulSoup 生成表格树然后填充内容确实是一个很好的改进方案。让我比较一下两种方式:
td_global、row_idx、col_idx 等指针colspan/rowspan 会很困难def generate_table_from_cells(table_cells_result, ocr_texts_res, table_cells_flag):
"""
基于检测到的单元格坐标生成 BeautifulSoup 表格树并填充内容
"""
from bs4 import BeautifulSoup
# 计算表格行列数
num_rows = len(table_cells_flag) - 1
max_cols = max(table_cells_flag[i+1] - table_cells_flag[i] for i in range(num_rows)) if num_rows > 0 else 0
# 创建基础表格结构
html_template = f"""
<html>
<body>
<table>
{''.join(f'<tr>{"<td></td>" * max_cols}</tr>' for _ in range(num_rows))}
</table>
</body>
</html>
"""
soup = BeautifulSoup(html_template, 'html.parser')
table = soup.find('table')
rows = table.find_all('tr')
# 填充单元格内容
for row_idx in range(num_rows):
row = rows[row_idx]
cells = row.find_all('td')
# 获取当前行的单元格范围
start_cell = table_cells_flag[row_idx]
end_cell = table_cells_flag[row_idx + 1]
for col_idx in range(end_cell - start_cell):
if col_idx < len(cells):
cell_global_idx = start_cell + col_idx
# 查找匹配的 OCR 内容
cell_content = ""
if cell_global_idx < len(ocr_texts_res):
cell_content = ocr_texts_res[cell_global_idx] or ""
cells[col_idx].string = cell_content
return str(soup)
# ...existing code...
def generate_table_with_beautifulsoup(
table_cells_result: list,
ocr_texts_res: list,
matched_index: dict,
table_cells_flag: list
) -> str:
"""
使用 BeautifulSoup 生成表格并填充 OCR 内容
Args:
table_cells_result: 单元格坐标列表
ocr_texts_res: OCR 识别文本列表
matched_index: 单元格与 OCR 的匹配关系
table_cells_flag: 行边界标记
Returns:
str: 生成的 HTML 表格字符串
"""
try:
from bs4 import BeautifulSoup, Tag
except ImportError:
# 如果没有 BeautifulSoup,回退到原方法
return get_html_result_fallback(matched_index, ocr_texts_res, table_cells_flag)
# 计算表格维度
num_rows = len(table_cells_flag) - 1
if num_rows <= 0:
return "<html><body><table></table></body></html>"
# 创建表格结构
soup = BeautifulSoup("<html><body><table></table></body></html>", 'html.parser')
table = soup.find('table')
# 为每行添加单元格
for row_idx in range(num_rows):
tr = soup.new_tag('tr')
table.append(tr)
# 当前行的单元格数量
num_cols = table_cells_flag[row_idx + 1] - table_cells_flag[row_idx]
for col_idx in range(num_cols):
td = soup.new_tag('td')
tr.append(td)
# 填充单元格内容
if row_idx < len(matched_index) and col_idx in matched_index[row_idx]:
content_parts = []
for ocr_idx in matched_index[row_idx][col_idx]:
if ocr_idx < len(ocr_texts_res):
content = ocr_texts_res[ocr_idx].strip()
if content:
content_parts.append(content)
# 合并多个 OCR 结果
if content_parts:
td.string = " ".join(content_parts)
return str(soup)
def get_table_recognition_res(
table_box: list,
table_structure_result: list,
table_cells_result: list,
overall_ocr_res: OCRResult,
table_ocr_pred: dict,
cells_texts_list: list,
use_table_cells_ocr_results: bool,
use_table_cells_split_ocr: bool,
) -> SingleTableRecognitionResult:
# ...existing code above...
# 使用 BeautifulSoup 生成表格(推荐)
pred_html = generate_table_with_beautifulsoup(
table_cells_result, ocr_texts_res, matched_index, table_cells_flag
)
# ...existing code below...
推荐使用 BeautifulSoup 方案,原因:
但需要:
这种方案特别适合有线表格场景,因为单元格检测通常很准确,可以直接基于检测结果构建表格结构。
上期发生额”ocr后的文字bbox是在表格检测单元框内,为什么没有显示出来 还需查找原因
# A用户_单元格扫描流水
python table_recognition_v2_single_process.py \
--input_dir "/Users/zhch158/workspace/data/流水分析/A用户_单元格扫描流水.img" \
--output_dir "/Users/zhch158/workspace/data/流水分析/A用户_单元格扫描流水/table_recognition_v2_Results" \
--pipeline "./my_config/table_recognition_v2.yaml" \
--device "cpu"
# 至远彩色印刷工业有限公司_2023年度报告母公司
python table_recognition_v2_single_process.py \
--input_dir "/Users/zhch158/workspace/data/至远彩色印刷工业有限公司/2023年度报告母公司.img" \
--output_dir "/Users/zhch158/workspace/data/至远彩色印刷工业有限公司/table_recognition_v2_Results" \
--pipeline "./my_config/table_recognition_v2.yaml" \
--device "cpu"