Java 版文档解析系统,支持图片和pdf的json和markdown解析:
1.ocr文字识别
2.公式识别
3.表格识别
模型来自UniRec-0.1B 是一个统一识别模型,专门针对:
纯文本识别:字符、单词、行、段落级别
数学公式识别:单行公式、多行公式
混合内容:文本、表格与公式混排的场景
最关键的是,它只有 0.1B(1亿)参数,但在多个基准测试中,其准确率与动辄 1-10B 参数的视觉语言大模型相当甚至更优,同时推理速度快 2-9 倍!
- 版面检测 (Layout Detection):基于 PP-DocLayoutV2 ONNX 模型,支持 25 种文档元素检测
- 通用识别 (UniRec):基于 UniRec VLM 模型,支持图像到文本的生成
- 文档 OCR (Doc Pipeline):完整的文档分析流水线,包含版面检测 + VLM 识别 + Markdown 转换
- OTSL 表格解析:支持 OTSL (Open Table Structure Language) 格式到 HTML 表格的转换
- PDF 支持:使用 Apache PDFBox 支持 PDF 文件输入
- 并行推理:支持多线程并行处理文档块
openocr4j/
├── pom.xml # Maven 项目配置
├── src/main/java/com/openocr4j/
│ ├── MainT.java # 使用示例
│ ├── OpenOCR.java # 统一接口(任务调度)
│ ├── util/
│ │ ├── BboxUtils.java # 边界框计算工具
│ │ ├── ImageUtils.java # 图像处理工具
│ │ ├── ContentUtils.java # 内容处理工具(重复检测等)
│ │ └── FileUtils.java # 文件处理工具
│ ├── otsl/
│ │ ├── OTSLParser.java # OTSL 解析器 + HTML 导出
│ │ ├── TableCell.java # 表格单元格
│ │ └── TableData.java # 表格数据
│ ├── model/
│ │ ├── UniRecONNX.java # UniRec ONNX 推理(编码器-解码器 + KV Cache)
│ │ ├── LayoutDetectorONNX.java # 版面检测 ONNX 推理
│ │ ├── SimpleTokenizer.java # 独立分词器
│ │ └── SimpleImageProcessor.java # 图像预处理器
│ ├── pipeline/
│ │ └── OpenDocONNX.java # 完整文档 OCR 流水线
│ └── markdown/
│ └── MarkdownConverter.java # Markdown 转换器
└──
- Java: JDK 11+
- Maven: 3.6+
- ONNX 模型文件:
PP-DoclayoutV2.onnx(版面检测模型)unirec_encoder.onnx(UniRec 编码器)unirec_decoder.onnx(UniRec 解码器)unirec_tokenizer_mapping.json(分词器映射)
从以下地址下载所需模型文件:
- Layout 模型: https://modelscope.cn/models/jiangnanboy/PP_DoclayoutV2_onnx
- UniRec 模型: https://modelscope.cn/models/jiangnanboy/unirec_0_1b_onnx
下载后放置到默认缓存目录或指定路径:
~/.cache/openocr4j/
├── PP_DoclayoutV2_onnx/
│ └── PP-DoclayoutV2.onnx
└── unirec_0_1b_onnx/
├── unirec_encoder.onnx
├── unirec_decoder.onnx
└── unirec_tokenizer_mapping.json
为了方便使用,我已打成jar包,调用即可,右侧 releases 页面下载jar包。
// === UniRec 通用识别 ===
public static void parseOCR() throws OrtException {
OpenOCR ocr = new OpenOCR(
"unirec", // task
"false", // useGpu
null, // layoutModelPath,可以给确定模型路径;或者设置为null,程序会首次自动下载模型
null, // unirecEncoderPath,可以给确定模型路径;或者设置为null,程序会首次自动下载模型
null, // unirecDecoderPath,可以给确定模型路径;或者设置为null,程序会首次自动下载模型
null, // tokenizerMappingPath,可以给确定模型路径;或者设置为null,程序会首次自动下载模型
0.5, // layoutThreshold
false, // useLayoutDetection
true, // useChartRecognition
4, // maxParallelBlocks
2048 // maxLength
);
// 单张图片
Object result = ocr.call("test1.jpg");
if (result instanceof String[]) {
String text = ((String[]) result)[0];
System.out.println(text);
}
}
// === pdf文档 解析 完整流水线 ===
public static void parseDoc() throws OrtException {
try (OpenOCR ocr = new OpenOCR(
"doc", // task
"false", // useGpu
null, // layoutModelPath,可以给确定模型路径;或者设置为null,程序会首次自动下载模型
null, // unirecEncoderPath,可以给确定模型路径;或者设置为null,程序会首次自动下载模型
null, // unirecDecoderPath,可以给确定模型路径;或者设置为null,程序会首次自动下载模型
null, // tokenizerMappingPath,可以给确定模型路径;或者设置为null,程序会首次自动下载模型
0.5, // layoutThreshold
true, // useLayoutDetection
true, // useChartRecognition
4, // maxParallelBlocks
2048 // maxLength
)) {
// pdf文件
Object result = ocr.call("test2.pdf");
// 保存结果
ocr.saveToMarkdown(result, "./output");
ocr.saveToJson(result, "./output");
}
}
// === 文档图片 解析 完整流水线 ===
public static void parseDoc() throws OrtException {
try (OpenOCR ocr = new OpenOCR(
"doc", // task
"false", // useGpu
null, // layoutModelPath
null, // unirecEncoderPath
null, // unirecDecoderPath
null, // tokenizerMappingPath
0.5, // layoutThreshold
true, // useLayoutDetection
true, // useChartRecognition
4, // maxParallelBlocks
2048 // maxLength
)) {
// 单张图片
Object result = ocr.call("test.jpg");
// 保存结果
ocr.saveToMarkdown(result, "./output");
ocr.saveToJson(result, "./output");
ocr.saveVisualization(result, "./output");
// 针对单张获取 Markdown 字符串
String markdown = ocr.toMarkdown(result);
System.out.println(markdown);
}
}专题四 曲线运动
241
$C$ 是第一级台阶水平面的中点。弹射器沿水平方向弹射小球, 弹射器高度 $h$ 和小球的初速度 $v_{0}$ 可调节, 小球被弹出前与 $A$ 的水平距离也为 $L$。某次弹射时, 小球恰好没有擦到 $A$ 而击中 $B$, 为了能击中 $C$ 点, 需调整 $h$ 为 $h'$, 调整 $v_{0}$ 为 $v_{0}'$, 下列判断正确的是 ( )
<img src="imgs/img_in_image_box_152_322_400_468.jpg" alt="Image" width="80%" />
A. $h'$ 的最大值为 $2h$
B. $h'$ 的最小值为 $2h$
C. $v_{0}'$ 的最大值为 $\frac{\sqrt{15}}{6}v_{0}$
D. $v_{0}'$ 的最小值为 $\frac{\sqrt{15}}{6}v_{0}$
解析 小球做平抛运动, 有 $y=\frac{1}{2}gt^{2}$ , $x=v_{0}t$ , 联立解得 $v_{0}=x\sqrt{\frac{g}{2y}}$ , $y=\frac{gx^{2}}{2v_{0}^{2}}\propto x^{2}$ (点拨: 将水平距离之比和高度之比建立关联是关键), 则调整前 $\frac{h}{h+H}=\left(\frac{L}{2L}\right)^{2}$ , 得 $h=\frac{1}{3}H$ , 调整后考虑临界情况, 小球恰好没有擦到 A 而击中 C, 则 $\frac{h^{\prime}}{h^{\prime}+H}=\left(\frac{2}{3}\right)^{2}$ , 即 $h^{\prime}=\frac{4}{5}H$ , 所以 $h^{\prime}=\frac{12}{5}h$ , 从越高处抛出而击中 C 点, 抛物线越陡, 越不容易擦到 A 点, 所以 $h^{\prime}=\frac{12}{5}h$ 是满足条件的 $h^{\prime}$ 的最小值, A、B 错误。 $v_{0}=x\sqrt{\frac{g}{2y}}$ , 且两次平抛从抛出到 A 点过程, x 都为 L, 所以 $\frac{v_{0}^{\prime}}{v_{0}}=\sqrt{\frac{h}{h^{\prime}}}=\frac{\sqrt{15}}{6}$ , 即 $v_{0}^{\prime}=\frac{\sqrt{15}}{6}v_{0}$ , 由 $v_{0}^{\prime}=$
$$ L\sqrt{\frac{g}{2h^{\prime}}} 知 v_{0}^{\prime}=\frac{\sqrt{15}}{6}v_{0} 是满足条件的 v_{0}^{\prime} 的最大值 ,C 正确 ,D 错误。 $$
## 答案 C
## 四、斜抛运动
1.分析思路:对斜上抛运动,从抛出点到最高点的运动可应用逆向思维分析,其逆过程为平抛运动;对于完整的斜上抛运动,还可根据对称性求解某些问题。
2.斜抛运动中的几个常用结论
<img src="imgs/img_in_image_box_661_456_823_560.jpg" alt="Image" width="80%" />
(1)运动到最高点的时间 $t=\frac{v_{0} \sin \theta}{g}$ ;
运动的总时间 $t_{总}=\frac{2v_{0} \sin \theta}{g}$ 。
(2) 射高 $y_{m}=\frac{v_{0}^{2}\sin^{2}\theta}{2g}$
(3) 射程 $x_{\mathrm{m}}=\frac{v_{0}^{2} \sin 2\theta}{g}$。当 $\theta=45^{\circ}$ 时, 射程最大。
## 题型(7)圆周运动中的临界极值问题
## 一、水平面内的圆周运动的两种模型
<table>
<tr>
<td></td>
<td>与弹力有关 的临界问题</td>
<td>与摩擦力有关 的临界问题</td>
</tr>
<tr>
<td>情境 图示</td>
<td><img src="imgs/img_in_image_box_620_1017_774_1169.jpg" ></td>
<td><img src="imgs/img_in_image_box_822_1031_942_1152.jpg" ></td>
</tr>
<tr>
<td>受力 示意图</td>
<td><img src="imgs/img_in_image_box_614_1176_776_1330.jpg" ></td>
<td><img src="imgs/img_in_image_box_815_1181_952_1327.jpg" ></td>
</tr>
</table>
| ID | 标签 | 说明 |
|---|---|---|
| 0 | abstract | 摘要 |
| 1 | algorithm | 算法 |
| 2 | aside_text | 旁注文本 |
| 3 | chart | 图表 |
| 4 | content | 内容 |
| 5 | display_formula | 展示公式 |
| 6 | doc_title | 文档标题 |
| 7 | figure_title | 图片标题 |
| 8 | footer | 页脚 |
| 9 | footer_image | 页脚图片 |
| 10 | footnote | 脚注 |
| 11 | formula_number | 公式编号 |
| 12 | header | 页眉 |
| 13 | header_image | 页眉图片 |
| 14 | image | 图片 |
| 15 | inline_formula | 行内公式 |
| 16 | number | 编号 |
| 17 | paragraph_title | 段落标题 |
| 18 | reference | 参考文献 |
| 19 | reference_content | 参考文献内容 |
| 20 | seal | 印章 |
| 21 | table | 表格 |
| 22 | text | 文本 |
| 23 | vertical_text | 竖排文本 |
| 24 | vision_footnote | 图注 |
- ONNX Runtime Java:跨平台 ONNX 模型推理引擎
- OpenCV Java:图像处理(裁剪、缩放、边距裁剪、文字绘制)
- Apache PDFBox:PDF 文件读取与页面渲染
- Encoder-Decoder 架构:UniRec 模型支持 KV Cache 高效自回归生成
- 并行推理:使用线程池并行处理多个文档块
如有想法或问题,可联系我:
- github:https://github.com/jiangnanboy
- QQ:2229029156
Apache License 2.0
