再谈表格数据合成与GOT-OCR识别应用
时间:2026-08-18 | 作者:游戏探长 | 阅读:0说到表格数据合成,尤其是基于LaTeX的渲染方案,核心思路其实并不复杂。
但这里面有几个关键问题必须解决。今天就结合GOT-OCR这条路子,把整个流程拆开来聊清楚。
先说明一点:环境得先搭好。不然下面这些操作都没法继续。
基本效果复现
准备工作很简单。用下面这个LaTeX模板就够了。
这次我们只合成表格,所以模板不需要太复杂。
documentclass[10pt]{article}
usepackage[top=.5in,bottom=1in,left=.5in,right=.5in]{geometry}
usepackage[UTF8]{ctex}
usepackage[pagebackref=true,breaklinks=true,colorlinks,bookmarks=false]{hyperref}
usepackage{amsmath,amsfonts,mathrsfs,amssymb}
% 设置中文字体
usepackage{multirow}
renewcommand{normalsize}{fontsize{6pt}{6pt}selectfont}
pagestyle{empty} % 去掉页码
setCJKmainfont{SimSun}[BoldFont=KaiTi, ItalicFont=SimHei]
begin{document}
begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|}
hline
& & multicolumn{3}{|c|}{textbf{参考情景}} & multicolumn{3}{|c|}{textbf{情景1}} & multicolumn{3}{|c|}{textbf{情景2}} & multicolumn{3}{|c|}{textbf{情景3}} & multicolumn{3}{|c|}{textbf{情景4}}
hline
品种 & G & textbf{BV} & textbf{Add} & textbf{Dom} & textbf{BV} & textbf{Add} & textbf{Dom} & textbf{BV} & textbf{Add} & textbf{Dom} & textbf{BV} & textbf{Add} & textbf{Dom} & textbf{BV} & textbf{Add} & textbf{Dom}
hline
& 1 & 0.86 & 0.81 & 0.53 & 0.73 & 0.80 & 0.22 & 0.69 & 0.80 & 0.15 & 0.70 & 0.78 & 0.26 & 0.72 & 0.76 & 0.31
cline{2-17}
& 2 & 0.64 & 0.69 & 0.56 & 0.57 & 0.65 & 0.20 & 0.46 & 0.69 & 0.19 & 0.59 & 0.69 & 0.27 & 0.54 & 0.65 & 0.22
cline{2-17}
& 3 & 0.48 & 0.63 & 0.57 & 0.48 & 0.50 & 0.23 & 0.39 & 0.63 & 0.20 & 0.47 & 0.61 & 0.21 & 0.47 & 0.61 & 0.22
cline{2-17}
& 4 & 0.37 & 0.59 & 0.60 & 0.42 & 0.52 & 0.24 & 0.33 & 0.57 & 0.21 & 0.34 & 0.54 & 0.18 & 0.40 & 0.58 & 0.24
cline{2-17}
& 5 & 0.31 & 0.56 & 0.61 & 0.36 & 0.47 & 0.23 & 0.25 & 0.52 & 0.20 & 0.28 & 0.48 & 0.20 & 0.32 & 0.52 & 0.26
hline
& & multicolumn{3}{|c|}{textbf{参考情景}} & multicolumn{3}{|c|}{textbf{情景1}} & multicolumn{3}{|c|}{textbf{情景2}} & multicolumn{3}{|c|}{textbf{情景3}} & multicolumn{3}{|c|}{textbf{情景4}}
hline
品种 & G & textbf{BV} & textbf{Add} & textbf{Dom} & textbf{BV} & textbf{Add} & textbf{Dom} & textbf{BV} & textbf{Add} & textbf{Dom} & textbf{BV} & textbf{Add} & textbf{Dom} & textbf{BV} & textbf{Add} & textbf{Dom}
hline
& 1 & 0.85 & 0.77 & 0.47 & 0.87 & 0.81 & 0.56 & 0.74 & 0.81 & 0.13 & 0.88 & 0.85 & 0.60 & 0.72 & 0.82 & 0.19
cline{2-17}
& 2 & 0.64 & 0.65 & 0.43 & 0.60 & 0.64 & 0.55 & 0.55 & 0.68 & 0.16 & 0.71 & 0.76 & 0.59 & 0.54 & 0.69 & 0.18
cline{2-17}
& 3 & 0.50 & 0.58 & 0.49 & 0.42 & 0.59 & 0.55 & 0.45 & 0.59 & 0.18 & 0.59 & 0.70 & 0.63 & 0.40 & 0.62 & 0.16
cline{2-17}
& 4 & 0.38 & 0.58 & 0.53 & 0.37 & 0.56 & 0.54 & 0.37 & 0.54 & 0.19 & 0.49 & 0.65 & 0.68 & 0.36 & 0.56 & 0.15
cline{2-17}
& 5 & 0.30 & 0.55 & 0.56 & 0.24 & 0.54 & 0.58 & 0.32 & 0.49 & 0.18 & 0.35 & 0.60 & 0.68 & 0.28 & 0.48 & 0.14
hline
end{tabular}
end{document}
生成 PDF
把上面的内容存成tmp.tex文件,然后运行下面这条命令:
lualatex -output-directory=./tmp -interaction=nonstopmode --shell-escape tmp_copy.tex
执行后,就能得到渲染后的PDF文件。
效果大致如下:
相关问题
先别急着往下看。这里可以先想几个问题:
- 问题 1:表格的多样性都体现在哪些方面?这些多样性又怎么通过渲染拿到?
- 问题 2:PDF渲染出来后,怎么才能精准定位到表格的位置,把它截取下来?
- 问题 3:整个渲染过程,能不能实现自动化?
后面的内容,就围绕这三个核心问题展开。
表格的多样性
最直接能想到的多样性,主要有下面几类:
- 表格线框的多样性;
- 表格内容的多样性;
- 表格字体的多样性;
- 表格形状的多样性;
- 表格颜色的多样性;
哪些部分由原始 LaTeX 决定
表格线框、内容、形状这几类多样性,主要依赖原始LaTeX文本内容的生成。
这部分可以参考“表格数据合成—GOT_OCR数据合成”那部分内容。核心就是如何利用大模型生成格式各异的表格数据。
字体多样性怎么做
表格字体和颜色的多样性,则更依赖对LaTeX语法的熟悉程度。
刚才代码里这一句很关键:
setCJKmainfont{SimSun}[BoldFont=KaiTi, ItalicFont=SimHei]
这就是设置字体的核心位置。
想让字体更丰富,最直接的方法就是在系统里安装更多字体,然后在这里指定。
颜色是否必须处理
颜色这块,如果只在文档场景下使用,可以先不考虑。
因为训练的时候,直接把图片灰度化就能解决问题。
pdf 表格获取
最直接的办法,是先把PDF转成图片,再用二值化方法把表格提取出来。
OpenCV里提供了多种二值化方法,比如:
- 简单阈值化:适合需求简单的场景。
- 自适应阈值化:对付光照不均的图像很有效。
- Otsu's 二值化:适合直方图有明显双峰的情况。
- 三角形法二值化:处理单峰直方图有一手。
- 双阈值化:用来搞定特定像素值范围的二值化。
实际操作下来,自适应阈值化基本够用。
下面是一个代码示例:
import fitz # PyMuPDF
import numpy as np
import matplotlib.pyplot as plt
import cv2
def pdf_to_images_with_bbox(pdf_path):
# 打开PDF文件
pdf_document = fitz.open(pdf_path)
for page_num in range(len(pdf_document)):
# 获取当前页
page = pdf_document.load_page(page_num)
# 将页面转换为PIL图像
pix = page.get_pixmap(dpi=288)
img = np.frombuffer(buffer=pix.samples, dtype=np.uint8).reshape((pix.height, pix.width, 3))
image = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
# 应用自适应阈值化
max_value = 255
adaptive_method = cv2.ADAPTIVE_THRESH_MEAN_C # 或 cv2.ADAPTIVE_THRESH_GAUSSIAN_C
block_size = 11
C = 2
binary_image = cv2.adaptiveThreshold(image, max_value, adaptive_method, cv2.THRESH_BINARY, block_size, C)
print(binary_image.shape)
y = np.sum(255 - binary_image, axis=-1)
x = np.sum(255 - binary_image, axis=0)
x = np.where(x>=1)[0]
y = np.where(y >= 1)[0]
x_min, x_max = x[0], x[-1]
y_min, y_max = y[0], y[-1]
print([x_min, y_min, y_min, y_max])
cv2.rectangle(img, (x_min, y_min), (x_max, y_max), (0,0, 255), 3)
plt.imshow(img)
plt.show()
# 示例用法
pdf_path = "./tmp.pdf"
pdf_to_images_with_bbox(pdf_path)
注:截图的时候,建议四边随机往外扩一点。贴着边把图截下来,效果其实不太好。
怎么自动化的生成
理解了上面这些,自动化就比较自然了。
可以把LaTeX代码拆成三段来看。
第一段:固定不变的
documentclass[10pt]{article}
usepackage[top=.5in,bottom=1in,left=.5in,right=.5in]{geometry}
usepackage[UTF8]{ctex}
usepackage[pagebackref=true,breaklinks=true,colorlinks,bookmarks=false]{hyperref}
usepackage{amsmath,amsfonts,mathrsfs,amssymb}
% 设置中文字体
usepackage{multirow}
renewcommand{normalsize}{fontsize{6pt}{6pt}selectfont}
pagestyle{empty} % 去掉页码
这里的字体大小,可以通过后处理图像时的dpi来控制,所以这部分直接固定不变就好。
第二段:可变的
setCJKmainfont{SimSun}[BoldFont=KaiTi, ItalicFont=SimHei]
这里只给出了字体设置的全局变量。
如果对LaTeX很熟,可以把所有可变的部分都放在这里。
为了配合Python代码,可以这么改写:
fonts = ["字体1","字体2","字体3",..., "字体n"]
temp = f"setCJKmainfont{{{font1}}}[BoldFont={font2}, ItalicFont={font3}]"
set_font = temp.format(font1=random.choice(fonts),
font2=random.choice(fonts),
font3=random.choice(fonts),)
这样一来,set_font就有了随机性。
第三段: 表格多样性
temp = f"""begin{{document}}
{tabular}
end{{document}}
"""
tabular_text = r"""
begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|}
hline
& & multicolumn{3}{|c|}{textbf{参考情景}} & multicolumn{3}{|c|}{textbf{情景1}} & multicolumn{3}{|c|}{textbf{情景2}} & multicolumn{3}{|c|}{textbf{情景3}} & multicolumn{3}{|c|}{textbf{情景4}}
hline
品种 & G & textbf{BV} & textbf{Add} & textbf{Dom} & textbf{BV} & textbf{Add} & textbf{Dom} & textbf{BV} & textbf{Add} & textbf{Dom} & textbf{BV} & textbf{Add} & textbf{Dom} & textbf{BV} & textbf{Add} & textbf{Dom}
hline
& 1 & 0.86 & 0.81 & 0.53 & 0.73 & 0.80 & 0.22 & 0.69 & 0.80 & 0.15 & 0.70 & 0.78 & 0.26 & 0.72 & 0.76 & 0.31
cline{2-17}
& 2 & 0.64 & 0.69 & 0.56 & 0.57 & 0.65 & 0.20 & 0.46 & 0.69 & 0.19 & 0.59 & 0.69 & 0.27 & 0.54 & 0.65 & 0.22
cline{2-17}
& 3 & 0.48 & 0.63 & 0.57 & 0.48 & 0.50 & 0.23 & 0.39 & 0.63 & 0.20 & 0.47 & 0.61 & 0.21 & 0.47 & 0.61 & 0.22
cline{2-17}
& 4 & 0.37 & 0.59 & 0.60 & 0.42 & 0.52 & 0.24 & 0.33 & 0.57 & 0.21 & 0.34 & 0.54 & 0.18 & 0.40 & 0.58 & 0.24
cline{2-17}
& 5 & 0.31 & 0.56 & 0.61 & 0.36 & 0.47 & 0.23 & 0.25 & 0.52 & 0.20 & 0.28 & 0.48 & 0.20 & 0.32 & 0.52 & 0.26
hline
& & multicolumn{3}{|c|}{textbf{参考情景}} & multicolumn{3}{|c|}{textbf{情景1}} & multicolumn{3}{|c|}{textbf{情景2}} & multicolumn{3}{|c|}{textbf{情景3}} & multicolumn{3}{|c|}{textbf{情景4}}
hline
品种 & G & textbf{BV} & textbf{Add} & textbf{Dom} & textbf{BV} & textbf{Add} & textbf{Dom} & textbf{BV} & textbf{Add} & textbf{Dom} & textbf{BV} & textbf{Add} & textbf{Dom} & textbf{BV} & textbf{Add} & textbf{Dom}
hline
& 1 & 0.85 & 0.77 & 0.47 & 0.87 & 0.81 & 0.56 & 0.74 & 0.81 & 0.13 & 0.88 & 0.85 & 0.60 & 0.72 & 0.82 & 0.19
cline{2-17}
& 2 & 0.64 & 0.65 & 0.43 & 0.60 & 0.64 & 0.55 & 0.55 & 0.68 & 0.16 & 0.71 & 0.76 & 0.59 & 0.54 & 0.69 & 0.18
cline{2-17}
& 3 & 0.50 & 0.58 & 0.49 & 0.42 & 0.59 & 0.55 & 0.45 & 0.59 & 0.18 & 0.59 & 0.70 & 0.63 & 0.40 & 0.62 & 0.16
cline{2-17}
& 4 & 0.38 & 0.58 & 0.53 & 0.37 & 0.56 & 0.54 & 0.37 & 0.54 & 0.19 & 0.49 & 0.65 & 0.68 & 0.36 & 0.56 & 0.15
cline{2-17}
& 5 & 0.30 & 0.55 & 0.56 & 0.24 & 0.54 & 0.58 & 0.32 & 0.49 & 0.18 & 0.35 & 0.60 & 0.68 & 0.28 & 0.48 & 0.14
hline
end{tabular}
"""
table_text = temp.format(tabular=tabular_text)
完成这三段的拼接,也就是:第一段 + 第二段 + 第三段。
这样就能得到一个完整的、可渲染的LaTeX文本。
总结
以上就是自动生成多样化表格数据集的一个基础流程。
整体思路并不复杂,关键在于把几个环节打通:
- 先生成有多样性的LaTeX表格内容;
- 再完成PDF渲染;
- 接着定位并截取表格区域;
- 最后把整个流程串成自动化程序。
当然,实际渲染过程中还有很多细节需要自己去摸索处理。比如:
- 渲染的表格超出了PDF边界怎么办?
- PDF渲染不出来怎么处理?
- 特殊字体渲染不出来怎么办?
等等。
遇到问题动手去调,才能真正把这条路走通。
免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。
相关文章
更多-
- 字节跳动发布豆包工作 与飞书深度打通构建企业级Agent
- 时间:2026-08-25
-
- AI通话录音手机续航实测能用多长时间
- 时间:2026-08-23
-
- Adobe Photoshop 27.7桌面版发布 移除工具支持端侧AI运行 苹果Mac需24GB内存
- 时间:2026-08-23
-
- 育碧远哭7测试AI生成画面效果 知情者评价其表现不佳
- 时间:2026-08-23
-
- AMD锐龙9 PRO 9965X3D及锐龙AI PRO 400商用台式机2026Q3上市
- 时间:2026-08-22
-
- 思必驰冲刺上市,AI语音行业护城河为何消失
- 时间:2026-08-21
-
- 道题看懂AI商业趋势与未来发展方向
- 时间:2026-08-21
-
- AI清理500GB空间实测:Agent暂时还替代不了电脑管家
- 时间:2026-08-21
精选合集
更多大家都在玩
大家都在看
更多-
- 为什么湿头发更容易断裂 蚂蚁庄园今日答案9.15
- 时间:2026-09-14
-
- 蚂蚁庄园今天答题答案2026年9月15日
- 时间:2026-09-14
-
- 蚂蚁庄园答题今日答案2026年9月15日
- 时间:2026-09-14
-
- 蚂蚁庄园小课堂2026年9月15日最新题目答案
- 时间:2026-09-14
-
- 小鸡答题今天的答案是什么2026年9月15日
- 时间:2026-09-14
-
- 蚂蚁庄园每日答题答案2026年9月15日
- 时间:2026-09-14
-
- 糖尿病患者禁食所有含糖食物吗 蚂蚁庄园今日答案9月15日
- 时间:2026-09-14
-
- 2026年9月14日蚂蚁新村答案
- 时间:2026-09-14
