资讯详情

基于RapidOCR的Python OCR源码:识别并返回HTML结构

📅 2026/10/12 8:28:14 | 华诺云谱 👁 阅读
基于RapidOCR的Python OCR源码:识别并返回HTML结构
简介这是一套基于 rapidOCR 改造的完整 OCR 图片识别源码面向需要将图片文字提取并结构化输出的 Python 开发者与项目集成者。它解决了传统 OCR 只返回纯文本、难以直接嵌入页面的问题通过内置 /engine/ocr 接口接收 http 链接、本地文件或文件流等多种图片形式并返回带标记的 HTML 结构可直接嵌入其他页面或复制使用。资源包共 46 个文件以 23 个 py 源码与 17 个 pyc 编译文件为主体另含 3 个 onnx 模型文件、1 个 yaml 配置、1 个 html 页面及 1 个 txt 依赖说明压缩包约 14.26MB目录涵盖 rapid_ocr 核心模块、web_service 服务入口与 common 工具封装结构清晰便于二次开发。目前已有 1739 人学习下载适合希望快速落地图片转文字、文本识别功能的开发者参考与集成。1. 从一张发票截图到结构化 HTML这套 OCR 源码到底解决了什么很多做业务系统的开发者都遇到过这种需求用户上传一张发票、身份证或合同截图后台不仅要识别出文字还要把文字按版面位置还原成带标签的 HTML 结构方便前端直接渲染或做字段抽取。市面上现成的 OCR 接口要么只返回纯文本要么返回一堆坐标框需要自己拼装真正能直接吐出语义化 HTML 的少之又少。标题里这套「已用 Python 实现 OCR 功能并返回 HTML 结构」的源码核心思路是基于 RapidOCR 做二次改造——RapidOCR 本身是一个推理速度快、依赖轻量的开源 OCR 工具链但它默认输出的是文本框坐标加文本内容离「HTML 结构」还差一层版面分析和标签映射。这套源码的价值就在于把这层补齐了检测、识别、方向分类走 RapidOCR后处理阶段做行合并、段落归组、表格区域判定最后按语义标签输出 HTML。适合谁适合需要私有化部署 OCR、又不想从零训练模型的中小团队也适合想研究版面还原逻辑的个人开发者。下面我按「先跑通、再拆解、后调优」的顺序把这套方案的落地路径讲清楚。2. 环境搭建与 RapidOCR 最小可跑通示例2.1 依赖选型为什么是 RapidOCR 而不是 PaddleOCR 原生RapidOCR 本质上是把 PaddleOCR 的模型做了 ONNX 转换和推理层重写好处是推理时不依赖 PaddlePaddle 框架装包体积小、启动快在 CPU 上也能跑到可用的速度。原生 PaddleOCR 功能更全但依赖链重部署到一些受限环境里经常卡在框架安装上。这套源码选 RapidOCR 作为底座说明作者更看重部署轻量化和跨平台一致性。常见做法是先用 RapidOCR 的rapidocr_onnxruntime包跑通检测加识别确认模型文件齐全再往上叠版面分析逻辑。需要注意RapidOCR 有三个模型文件——检测模型、识别模型、方向分类模型缺一不可方向分类模型负责把旋转 180 度的文本纠正过来很多识别不准的案例其实是漏了这一步。2.2 最小可跑通代码三行核心调用加结果解析先装依赖再跑一个最小示例确认环境没问题# 安装 rapidocr_onnxruntime它会自动拉取 onnxruntime 和 opencv pip install rapidocr_onnxruntimefrom rapidocr_onnxruntime import RapidOCR # 初始化引擎默认加载内置的检测、识别、方向分类三个模型 engine RapidOCR() # 传入图片路径返回 (文本框坐标, 文本内容, 置信度) 的列表 result, elapse engine(invoice_sample.png) # result 为 None 表示没检测到任何文本 if result: for box, text, score in result: # box 是四个点的坐标text 是识别出的字符串 print(box, text, round(score, 3)) else: print(未检测到文本检查图片是否过暗或分辨率过低)这段代码的逻辑说明RapidOCR()初始化时会去默认缓存目录找模型文件第一次运行会自动下载。engine()返回两个值第一个是识别结果列表第二个是各阶段耗时。每个结果元素是三元组box是四点多边形坐标顺序是左上、右上、右下、左下。参数方面如果图片是扫描件且文字水平可以在初始化时传use_angle_clsFalse关掉方向分类省一点推理时间如果图片分辨率很高建议先缩放到长边 1600 像素左右再送入否则检测阶段会非常慢。置信度低于 0.5 的结果建议直接丢弃这类多半是噪点误检。2.3 从识别结果到 HTML坐标排序与行合并策略拿到result之后不能直接拼 HTML因为 OCR 返回的顺序是按检测框的某种内部排序不保证阅读顺序。需要先按纵坐标聚类成行再按横坐标排序。核心逻辑是计算每个 box 的中心点 y 坐标把 y 差值小于某个阈值通常是行高的 0.5 倍的框归为同一行行内按 x 坐标升序排列。行与行之间按 y 升序。这样得到的顺序才符合人眼阅读习惯。合并成行之后再判断哪些行属于同一个段落——如果相邻两行的左边界 x 差值很小且行间距均匀就归为同一段。这一步是后续生成p标签的基础。表格区域则更复杂需要检测是否存在多列对齐的框常见做法是用 x 坐标的分布做列切分再按行列交叉填充td。3. 版面分析把文本框还原成 HTML 语义标签3.1 行、段、块的三级归组逻辑版面分析的核心是把零散的文本框组织成有层次的块。我一般会分三级处理第一级是行归组按 y 坐标聚类第二级是段归组把行间距小于阈值且左边界对齐的行合并成段第三级是块归组把段按垂直间距和字体高度差异分成不同区块比如标题块、正文块、表格块。阈值怎么定行归组的 y 阈值建议取所有框高度的中位数乘以 0.6段归组的行间距阈值取行高中位数的 1.5 倍块归组的垂直间距阈值取段间距中位数的 2 倍。这些参数没有万能值需要根据实际文档类型微调。发票类文档行距紧凑阈值要调小合同类文档段落分明阈值可以放宽。3.2 表格区域判定与 td 填充表格是 HTML 结构里最难还原的部分。这套源码的思路是先通过框的 x 坐标分布找出列边界再通过 y 坐标分布找出行边界构建一个二维网格然后把每个框的文本填入对应的单元格。具体做法是对所有框的左右边界 x 坐标做一维聚类聚类中心就是列边界同理对上下边界 y 坐标聚类得到行边界。聚类时用简单的间隔阈值法即可不需要上 DBSCAN 这类重型算法。填充时判断框的中心点落在哪个行列区间内。如果某个单元格没有框落入就填空字符串。这里有个坑合并单元格在纯坐标分析下无法直接识别需要额外判断某个框是否跨越了多个列区间如果是就设置colspan属性。这个逻辑写起来不复杂但边界情况多建议先用简单表格测试。3.3 生成 HTML 的模板与转义处理生成 HTML 时不要用字符串拼接容易出转义问题。推荐用html.escape()对识别文本做转义防止文本里的、、破坏结构。模板可以用简单的 f-string 或 Jinja2。段落用p标题根据字体高度判断用h2或h3表格用table加tr、td。字体高度怎么来OCR 结果里没有直接给字号但可以用 box 的高度近似代替。如果某行的 box 高度明显大于正文行高中位数就判定为标题。这个启发式规则在大多数文档上够用。输出时建议保留一个>import html def build_html(paragraphs): # paragraphs 是已经归组好的段落列表每段包含文本和类型 parts [] for para in paragraphs: text html.escape(para[text]) # 转义防止 XSS 和结构破坏 if para[type] title: parts.append(fh2 style="width:16px;margin-left:4px;vertical-align:text-bottom;cursor:text;" />
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑