摘要学生证、借书证、校园卡、图书馆读者证这类证件在学校信息化系统中非常常见。教务处、图书馆、实验室、二级学院在整理学生档案、借阅权限、门禁白名单或活动报名信息时经常会遇到一个重复问题纸质证件、拍照图片、截图材料中有很多结构化字段但人工录入速度慢且容易把学号、姓名、学院或有效期录错。本文围绕一个完整可运行项目展开项目名称为基于 PaddleOCR Flask 的学生证/借书证信息识别与档案录入系统。它不是单纯演示一段 OCR 代码而是把“证件图片上传、OCR 文本识别、字段结构化解析、档案入库、人工复核、CSV/Excel 导出、Web 管理界面”串成一个可以交付的系统。项目内置 4 张脱敏样例证件图片方便读者离线跑通本文的正式结果则使用公开学生卡和公开借书卡实物图片通过 PaddleOCR 真实识别生成文本框、结构化字段、入库记录和 Web 页面截图。项目关键词PaddleOCR 学生证识别、借书证识别、OCR 档案录入系统、Flask Web 系统、证件信息结构化、学生档案管理、Python OCR 项目实战。一、项目背景为什么要做证件 OCR 档案录入系统在很多校园场景里证件信息并不只存在数据库中。新生报到、图书馆借阅注册、实验室准入申请、社团活动报名、竞赛信息核验、实习材料归档时管理员经常会收到学生证照片、借书证照片或校园卡截图。看似只是“把图片上的信息抄进表格”但实际做起来会出现几个明显痛点。第一人工录入效率低。一个学生证通常包含姓名、性别、学号、学院、专业、班级、有效期等字段借书证还可能包含读者证号、可借册数、联系电话。几十张图片还能人工处理几百张、上千张时就会变成重复劳动。第二人工录入容易出错。学号一般是连续数字借书证号可能包含字母和数字少输一位、把 0 看成 O、把 1 看成 l都可能造成后续查询失败。特别是图书馆、实验室这类业务证号错误会直接影响借阅或准入。第三普通 OCR 只能输出文本不能直接变成可用档案。很多 OCR 示例会把图片识别成几行文字但业务系统需要的是结构化字段比如name、student_id、library_id、college、valid_until。如果没有字段解析、校验和入库OCR 结果仍然需要人工整理。第四项目交付时只给命令行脚本不够直观。课程设计、实践项目、CSDN 源码资源或项目展示通常需要一个可操作界面让用户上传图片后看到识别结果、入库记录和导出文件。因此本项目选用 Flask 实现 Web 管理界面而不是停留在单文件脚本。证件 OCR 系统的输入通常来自校园卡、学生卡、借书证、读者卡等实体卡片或拍照图片。下图展示的是公开学生卡实物样例卡面字段、卡片边缘、拍摄角度和背景干扰都提示我们真实业务不能只停留在“识别几行文字”还要把识别内容转为可复核、可导出的档案数据。PaddleOCR 官方项目本身面向图片和 PDF 文档 OCR并强调将视觉文档转换为结构化数据适合做文档解析、RAG、智能体等下游应用。本项目没有直接使用复杂的版式大模型而是采用“PaddleOCR 文本识别 规则字段解析 Web 档案管理”的轻量方案适合 CPU 环境、课程实践和二次开发。参考资料PaddleOCR GitHubhttps://github.com/PaddlePaddle/PaddleOCRPaddleOCR KIE 文档https://github.com/PaddlePaddle/PaddleOCR/blob/main/ppstructure/kie/README.mdFlask 文件上传文档https://flask.palletsprojects.com/en/stable/patterns/fileuploads/公开学生卡样例图https://commons.wikimedia.org/wiki/File:Student_OMNY_Card.jpg公开借书卡样例图https://commons.wikimedia.org/wiki/File:Library_Card_(early_2000%27s).jpg二、项目效果预览系统运行后会完成图片上传、OCR 识别、字段解析、档案入库、人工复核和导出。整体处理流程如下。借书证和读者卡通常包含条码、证号、机构名称和借阅权限等信息字段形态和学生证并不完全一样。系统把这类卡片统一抽象为“证件图片 OCR 文本行 结构化字段”后续通过字段别名和规则校验适配更多版式。OCR 识别结果会保留原始文本行和文本框位置同时把关键信息整理为字段。下图使用公开借书卡实物图片真实运行红框是 PaddleOCR 检测到的文本行区域右侧是系统解析出的结构化字段。可以看到借书证号29305000004507被抽取出来同时因为卡面没有姓名字段记录会自动进入人工复核状态。档案入库后可以在 Web 页面中查看最近识别记录、按姓名或学号检索并导出 CSV/Excel 文件。下图是 Flask 页面在真实入库数据上的截图表格中包含 3 条公开证件图片识别记录。档案管理页的真实运行截图如下。系统把借书证号、证件类型、平均置信度和复核状态写入 SQLite并在页面中提供导出入口。单条详情页会展示原始图片、结构化字段、OCR 引擎、置信度、复核提示和原始 OCR 文本方便管理员确认低信息量或字段缺失的证件。证件类型统计图如下。本次正式运行使用 3 张公开实物图片其中 1 张识别为学生证、1 张识别为借书证另有 1 张因有效字段过少被标记为类型待确认3 条记录均进入复核队列平均置信度约为 0.9564。三、技术选型PaddleOCR、Flask 与 SQLite 如何配合这个项目的技术栈并不复杂但每一层都对应真实业务中的一个环节。PaddleOCR 负责文本识别。真实运行时系统通过src/ocr_engine.py中的PaddleOCREngine加载 PaddleOCR并调用 OCR 接口获取文本行、置信度和文本框。由于 OCR 权重下载、PaddlePaddle 安装与 Python 版本有关为了保证项目包开箱可跑我额外实现了DemoOCREngine。它只用于内置脱敏样例图片会读取demo_data/sample_cards/expected_fields.json中的元数据模拟 OCR 输出。这样即使用户没有网络、没有 GPU、没有安装 PaddleOCR也可以先完整体验系统流程。Flask 负责 Web 管理界面。系统实现了首页看板、识别录入、档案管理、详情复核、删除记录、导出文件和 API 上传接口。Flask 官方文件上传模式中会使用multipart/form-data、request.files和werkzeug.utils.secure_filename()保存文件同时建议限制允许上传的扩展名和最大上传体积。项目中也按这个思路做了上传安全控制只允许png、jpg、jpeg、bmp、webp等图片格式。SQLite 负责本地档案库。课程设计和单机项目中SQLite 比 MySQL 更容易交付不需要额外服务。系统会自动创建data/db/card_archive.sqlite3识别后的字段会写入card_records表。后续如果要扩展为多人协同系统可以把src/database.py换成 MySQL、PostgreSQL 或 SQLAlchemy ORM。Pandas 与 openpyxl 负责导出。档案记录通过src/export_utils.py转为 DataFrame然后导出为 CSV 和 Excel方便管理员继续整理或导入其他系统。Pillow 用于生成脱敏样例图片和结果图。为了避免真实学生证隐私问题公开演示时不建议使用包含个人信息的真实证件图片项目样例中的姓名、学号和学院均为虚构数据适合博客截图、课程实践和交付演示。四、项目目录结构项目目录如下student_card_paddleocr_flask/ ├── app.py ├── main.py ├── run_demo.py ├── blog.md ├── README.md ├── requirements.txt ├── requirements_ocr_full.txt ├── configs/ │ └── config.json ├── src/ │ ├── config.py │ ├── data_generator.py │ ├── database.py │ ├── export_utils.py │ ├── field_parser.py │ ├── ocr_engine.py │ ├── pipeline.py │ ├── utils.py │ └── visualization.py ├── templates/ ├── static/ ├── demo_data/ │ └── sample_cards/ ├── data/ │ ├── db/ │ └── uploads/ ├── outputs/ ├── images/ │ ├── figures/ │ └── results/ ├── docs/ ├── logs/ ├── weights/ │ └── README_WEIGHTS.md ├── run.bat └── run.sh其中最重要的是app.py、src/ocr_engine.py、src/field_parser.py、src/database.py和src/pipeline.py。app.py是 Flask 入口负责页面路由和上传逻辑。用户通过/recognize上传图片系统保存文件后调用recognize_card()完成识别和入库。/records提供档案列表和搜索/records/id提供单条记录详情和人工复核/export/csv与/export/xlsx用于导出文件。src/ocr_engine.py封装 OCR 引擎。这个文件中有三个类PaddleOCREngine、DemoOCREngine和HybridOCREngine。HybridOCREngine是默认入口在auto模式下先尝试 PaddleOCR如果运行机器没有安装 PaddleOCR则对内置样例使用 demo 回退。这样做的好处是项目既能体现 PaddleOCR 的真实接入方式又不会因为权重或环境问题导致整个项目不能运行。src/field_parser.py负责把 OCR 文本转成结构化字段。OCR 的输出一般是文本行例如姓名张明 学号2023100101 学院信息工程学院 专业人工智能 班级AI2301 有效期2027-07-01解析器会识别“姓名、学号、借书证号、学院、专业、班级、有效期、电话”等字段标签并用规则清洗值。比如学号只保留数字借书证号保留字母和数字有效期统一转为YYYY-MM-DD格式。解析完成后还会检查是否缺少姓名、学号或借书证号并给出已结构化或需复核状态。src/database.py负责 SQLite 表创建、插入、查询、删除和统计。src/export_utils.py负责导出 CSV/Excel。src/visualization.py负责生成博客中使用的架构图、流程图、OCR 框图、档案表格预览和看板预览。五、配置文件说明项目配置集中在configs/config.json{project_name:student_card_paddleocr_flask,app:{port:5000,debug:false,secret_key:change-this-secret-key,max_upload_mb:8},paths:{database:data/db/card_archive.sqlite3,upload_dir:data/uploads,sample_dir:demo_data/sample_cards,output_dir:outputs,result_image_dir:images/results,figure_dir:images/figures},ocr:{engine:auto,language:ch,use_angle_cls:true,min_confidence:0.45,enable_demo_fallback:true}}其中ocr.engine有三个常用值auto是默认模式。系统先尝试 PaddleOCR如果没有安装 PaddleOCR会在内置样例图片上使用 demo 回退。paddleocr是真实 OCR 模式。用户需要先安装requirements_ocr_full.txt中的依赖并确保 PaddleOCR 能正常下载或读取模型权重。demo是纯样例模式。这个模式只适合项目演示和离线跑通不能识别用户随意上传的真实图片。路径配置可以按需修改。例如如果要把数据库放到其他目录只需要改paths.database。如果要把上传图片目录改到独立磁盘也可以修改paths.upload_dir。六、核心代码解析OCR 引擎适配OCR 引擎是本项目的第一层核心。真实环境中PaddleOCR 输出通常包含文本框、识别文本和置信度。项目中将这些内容统一封装为OCRLine和OCRResult后续字段解析器不需要关心 PaddleOCR 的具体版本差异。核心思路如下dataclassclassOCRLine:text:strconfidence:float1.0bbox:Optional[List[List[int]]]NonedataclassclassOCRResult:image_path:strengine:strlines:List[OCRLine]ok:boolTruemessage:strPaddleOCREngine的作用是把 PaddleOCR 的返回结果转成这些统一结构。PaddleOCR 2.x 常见调用方式是frompaddleocrimportPaddleOCR ocrPaddleOCR(langch,use_angle_clsTrue)resultocr.ocr(card.png,clsTrue)不同版本的 PaddleOCR 返回格式可能略有差异因此项目中写了_parse_v2_result()和_parse_generic_result()两个解析方法尽量兼容常见输出结构。对于 demo 模式DemoOCREngine会读取样例图片对应的元数据返回与 PaddleOCR 类似的文本行结果。这样设计还有一个好处如果后续想替换 OCR 引擎比如 EasyOCR、Tesseract、RapidOCR、PaddleOCR-VL 或云端 OCR只需要新增一个 Engine 类最终仍然返回OCRResult即可。七、核心代码解析字段结构化解析OCR 只能告诉我们图片上有哪些文字但业务系统需要的是字段。比如 OCR 结果里有“姓名张明”档案库中应该保存name张明。因此本项目把字段解析单独放在src/field_parser.py中。字段别名配置如下FIELD_ALIASES{name:[姓名,名字,Name],gender:[性别,Gender],student_id:[学号,学生编号,Student ID,StudentID,ID],library_id:[借书证号,读者证号,图书证号,Library ID,LibraryID,证号],college:[学院,院系,系部,College,Department],major:[专业,Major],class_name:[班级,Class],valid_until:[有效期,有效日期,Valid Until,Validity],phone:[联系电话,手机号,电话,Phone],borrow_limit:[可借册数,借阅额度,Borrow Limit],}这部分写成别名表是为了后续扩展方便。不同学校证件版式可能写“院系”而不是“学院”图书馆证件可能写“读者证号”而不是“借书证号”英文版证件可能写 “Student ID”。只要在别名表中补充标签解析器就能支持更多样式。字段解析完成后系统会执行简单校验。姓名、学号或借书证号是核心字段如果缺少这些信息记录会被标记为需复核。这个逻辑很适合真实项目因为 OCR 不可能保证所有图片都识别正确档案系统必须允许人工确认。八、核心代码解析Flask 上传与档案页面Flask 部分主要在app.py中。上传路由/recognize的基本流程是检查请求中是否包含图片文件检查文件名是否为空检查扩展名是否为允许的图片格式使用secure_filename()处理文件名保存到data/uploads/调用recognize_card()根据识别结果跳转到详情页。相关逻辑简化如下ifcard_imagenotinrequest.files:flash(没有找到上传文件。,warning)returnredirect(request.url)filerequest.files[card_image]iffile.filename:flash(请选择图片文件。,warning)returnredirect(request.url)ifnotallowed_file(file.filename):flash(仅支持 png、jpg、jpeg、bmp、webp 图片格式。,danger)returnredirect(request.url)filenamef{timestamp_slug()}_{secure_filename(file.filename)}save_pathupload_dir/filenamefile.save(save_path)resultrecognize_card(save_path,cfgcfg,save_to_dbTrue)档案管理页/records支持关键词查询可以按姓名、学号、借书证号、学院或证件类型检索。详情页/records/id展示证件图片、结构化字段、OCR 原文、置信度、状态和备注。管理员可以把状态从需复核改成已人工复核也可以删除错误记录。为了方便接口调用项目还提供/api/recognize。用户可以用 curl 或其他程序上传图片接口会返回 JSON其中包含 OCR 文本、结构化字段、校验结果和数据库记录 ID。九、数据库设计card_records表是系统核心表。字段设计如下字段说明idSQLite 自增主键file_name原始图片文件名image_path图片相对路径card_type学生证或借书证name姓名gender性别student_id学号library_id借书证号college学院major专业class_name班级valid_until有效期phone联系电话borrow_limit可借册数raw_textOCR 原始文本confidenceOCR 平均置信度engineOCR 引擎status识别状态warnings字段校验提示remark人工备注或 OCR 消息created_at入库时间SQLite 文件位于data/db/card_archive.sqlite3导出文件位于outputs/student_card_records.csv outputs/student_card_records.xlsx离线 demo 运行后会入库 4 条脱敏样例记录分别对应 2 张学生证和 2 张借书证。启用 PaddleOCR 后用户可以直接上传真实图片也可以扩展批量上传接口。本文最终截图使用公开证件实物图片验证真实 OCR 路径结果会根据字段完整度自动进入结构化或复核状态。十、运行方式建议使用 Python 3.10 或 3.11。先安装轻量依赖pipinstall-rrequirements.txt运行离线 demopython main.py--modedemo这个命令会完成以下事情生成内置样例证件图片初始化 SQLite 数据库执行 OCR 识别流程解析字段并写入数据库导出 CSV 和 Excel生成博客中的结果图保存outputs/demo_summary.json。启动 Web 系统python main.py--modeapp启动后按终端提示打开本地 Web 页面即可进入证件识别、档案管理和导出功能。十一、启用真实 PaddleOCR默认项目不把 PaddleOCR 作为强制依赖是为了保证代码包可以快速运行。真实识别任意上传图片时需要安装完整 OCR 依赖pipinstall-rrequirements_ocr_full.txt然后把配置改为ocr:{engine:paddleocr,language:ch,use_angle_cls:true}首次运行 PaddleOCR 时系统可能会下载文本检测、文本识别和方向分类模型。不同平台的 PaddlePaddle 安装命令可能不同尤其是 GPU 环境需要按官方文档选择对应 CUDA 版本。如果是在课程设计或普通 CPU 电脑上运行建议先使用 CPU 版本跑通。如果无法下载权重可以参考weights/README_WEIGHTS.md手动把 PaddleOCR 模型放到weights/paddleocr/目录并在src/ocr_engine.py中补充模型路径参数。十二、为什么要保留 demo OCR 回退很多 OCR 项目交付失败并不是业务逻辑写错而是模型依赖太重。PaddleOCR 需要 PaddlePaddlePaddlePaddle 又和 Python 版本、操作系统、CPU/GPU 环境相关。对于 CSDN 源码资源、课程实践项目或普通 Windows 用户来说如果一开始就要求安装完整深度学习环境很容易卡在依赖安装上。因此本项目采用“双模式”demo 模式保证项目包下载后能直接跑通PaddleOCR 模式用于真实图片识别和二次开发。demo 模式并不是替代真实 OCR而是降低上手门槛。用户先看到 Web 页面、字段解析、入库和导出效果再按需要安装 PaddleOCR。这样的交付体验更稳定也更适合教学和项目展示。十三、真实业务中的扩展方向第一个扩展方向是批量上传。当前页面支持单张图片上传适合演示和少量录入。真实业务中可以增加批量上传页面将多张证件图片依次识别生成批量复核列表。字段完整的记录自动入库字段缺失或置信度偏低的记录进入复核队列。第二个扩展方向是登录和权限。管理员、普通录入员、复核员可以拥有不同权限。录入员只能上传图片复核员可以修改状态和备注管理员可以删除记录和导出全量档案。第三个扩展方向是更强的信息抽取模型。当前项目主要通过规则解析字段适合版式比较稳定的学生证和借书证。如果要处理复杂表单、申请表、票据、扫描件可以考虑接入 PaddleOCR PP-Structure 的 KIE 模块或使用 LayoutXLM、PaddleOCR-VL 等文档理解模型。第四个扩展方向是数据库升级。SQLite 适合单机项目如果要多人访问可以改成 MySQL 或 PostgreSQL。表结构基本可以复用只需要替换数据库访问层。第五个扩展方向是错误样本回流。系统可以保存识别失败的图片和人工修正字段后续用于优化字段解析规则或作为自定义 KIE 模型训练数据。第六个扩展方向是接入学校业务系统。比如识别结果可以通过 API 写入图书馆读者系统、实验室门禁系统、活动报名系统或学生信息管理系统。十四、项目适用场景这个项目适合以下几类使用场景。第一类是课程设计和实践项目。项目包含 OCR、Web、数据库、数据导出、可视化结果功能完整度比普通单脚本更高适合 Python Web、人工智能应用开发、软件工程实践课程。第二类是 CSDN 技术博客和源码资源。文章可以围绕 PaddleOCR、Flask 文件上传、OCR 结构化解析、SQLite 档案管理展开读者下载代码后可以直接运行 demo。第三类是校园管理工具原型。虽然内置样例使用脱敏数据但系统结构可以迁移到真实场景。管理员可以上传学生证或借书证图片系统自动提取字段并入库减少重复录入。第四类是 OCR 项目二次开发模板。很多 OCR 业务都不是“识别文字”这么简单而是“识别文字后进入业务流程”。本项目的 OCR 引擎适配、字段解析、数据库入库、Web 查询和导出都可以复用到票据识别、表单录入、快递面单识别、证书信息提取等项目中。十五、运行结果说明本文的正式截图来自真实 PaddleOCR 模式。使用 3 张公开证件实物图片运行后可以得到下面这些结果文件和统计信息公开实物图片数量3 档案入库数量3 证件类型学生证 1 条借书证 1 条类型待确认 1 条 平均置信度0.9564 借书证号抽取结果29305000004507 复核队列3 条 导出文件student_card_records.csv、student_card_records.xlsx公开学生卡和公开借书卡不一定包含姓名、学院、专业等校园档案字段因此真实 OCR 结果中会出现“识别到了可见文字但核心字段不完整”的情况。系统不会把这类记录直接当作成功档案而是保留 OCR 原文、置信度和结构化字段并标记为需复核。这比只展示全字段样例更接近实际业务因为真实上传图片经常会存在遮挡、版式不匹配或字段缺失。在未安装 PaddleOCR 的机器上demo 运行时会使用内置样例回退模式。代码中已经保留 PaddleOCR 真实识别接口安装requirements_ocr_full.txt后即可切换真实 OCR。十六、总结本文完成了一个围绕校园证件识别的完整项目基于 PaddleOCR Flask 的学生证/借书证信息识别与档案录入系统。它解决的不只是 OCR 文本识别问题而是把证件图片中的文字转换为可检索、可复核、可导出的档案数据。从工程角度看项目把 OCR 引擎、字段解析、数据库、Web 页面和导出功能拆成独立模块后续维护和扩展比较方便。从交付角度看项目提供了离线 demo、样例图片、结果截图、运行脚本和说明文档适合 CSDN 发布、课程设计展示和二次开发。从业务角度看系统可以扩展到更多校园档案录入场景也可以迁移到票据、表单、证书、面单等结构化 OCR 任务。如果你需要一个既能运行、又能展示、还能扩展的 OCR 项目这个系统可以作为一个比较稳妥的基础模板。
基于 PaddleOCR 和 Flask 的学生证借书证识别与档案录入系统实战
发布时间:2026/6/2 19:06:30
摘要学生证、借书证、校园卡、图书馆读者证这类证件在学校信息化系统中非常常见。教务处、图书馆、实验室、二级学院在整理学生档案、借阅权限、门禁白名单或活动报名信息时经常会遇到一个重复问题纸质证件、拍照图片、截图材料中有很多结构化字段但人工录入速度慢且容易把学号、姓名、学院或有效期录错。本文围绕一个完整可运行项目展开项目名称为基于 PaddleOCR Flask 的学生证/借书证信息识别与档案录入系统。它不是单纯演示一段 OCR 代码而是把“证件图片上传、OCR 文本识别、字段结构化解析、档案入库、人工复核、CSV/Excel 导出、Web 管理界面”串成一个可以交付的系统。项目内置 4 张脱敏样例证件图片方便读者离线跑通本文的正式结果则使用公开学生卡和公开借书卡实物图片通过 PaddleOCR 真实识别生成文本框、结构化字段、入库记录和 Web 页面截图。项目关键词PaddleOCR 学生证识别、借书证识别、OCR 档案录入系统、Flask Web 系统、证件信息结构化、学生档案管理、Python OCR 项目实战。一、项目背景为什么要做证件 OCR 档案录入系统在很多校园场景里证件信息并不只存在数据库中。新生报到、图书馆借阅注册、实验室准入申请、社团活动报名、竞赛信息核验、实习材料归档时管理员经常会收到学生证照片、借书证照片或校园卡截图。看似只是“把图片上的信息抄进表格”但实际做起来会出现几个明显痛点。第一人工录入效率低。一个学生证通常包含姓名、性别、学号、学院、专业、班级、有效期等字段借书证还可能包含读者证号、可借册数、联系电话。几十张图片还能人工处理几百张、上千张时就会变成重复劳动。第二人工录入容易出错。学号一般是连续数字借书证号可能包含字母和数字少输一位、把 0 看成 O、把 1 看成 l都可能造成后续查询失败。特别是图书馆、实验室这类业务证号错误会直接影响借阅或准入。第三普通 OCR 只能输出文本不能直接变成可用档案。很多 OCR 示例会把图片识别成几行文字但业务系统需要的是结构化字段比如name、student_id、library_id、college、valid_until。如果没有字段解析、校验和入库OCR 结果仍然需要人工整理。第四项目交付时只给命令行脚本不够直观。课程设计、实践项目、CSDN 源码资源或项目展示通常需要一个可操作界面让用户上传图片后看到识别结果、入库记录和导出文件。因此本项目选用 Flask 实现 Web 管理界面而不是停留在单文件脚本。证件 OCR 系统的输入通常来自校园卡、学生卡、借书证、读者卡等实体卡片或拍照图片。下图展示的是公开学生卡实物样例卡面字段、卡片边缘、拍摄角度和背景干扰都提示我们真实业务不能只停留在“识别几行文字”还要把识别内容转为可复核、可导出的档案数据。PaddleOCR 官方项目本身面向图片和 PDF 文档 OCR并强调将视觉文档转换为结构化数据适合做文档解析、RAG、智能体等下游应用。本项目没有直接使用复杂的版式大模型而是采用“PaddleOCR 文本识别 规则字段解析 Web 档案管理”的轻量方案适合 CPU 环境、课程实践和二次开发。参考资料PaddleOCR GitHubhttps://github.com/PaddlePaddle/PaddleOCRPaddleOCR KIE 文档https://github.com/PaddlePaddle/PaddleOCR/blob/main/ppstructure/kie/README.mdFlask 文件上传文档https://flask.palletsprojects.com/en/stable/patterns/fileuploads/公开学生卡样例图https://commons.wikimedia.org/wiki/File:Student_OMNY_Card.jpg公开借书卡样例图https://commons.wikimedia.org/wiki/File:Library_Card_(early_2000%27s).jpg二、项目效果预览系统运行后会完成图片上传、OCR 识别、字段解析、档案入库、人工复核和导出。整体处理流程如下。借书证和读者卡通常包含条码、证号、机构名称和借阅权限等信息字段形态和学生证并不完全一样。系统把这类卡片统一抽象为“证件图片 OCR 文本行 结构化字段”后续通过字段别名和规则校验适配更多版式。OCR 识别结果会保留原始文本行和文本框位置同时把关键信息整理为字段。下图使用公开借书卡实物图片真实运行红框是 PaddleOCR 检测到的文本行区域右侧是系统解析出的结构化字段。可以看到借书证号29305000004507被抽取出来同时因为卡面没有姓名字段记录会自动进入人工复核状态。档案入库后可以在 Web 页面中查看最近识别记录、按姓名或学号检索并导出 CSV/Excel 文件。下图是 Flask 页面在真实入库数据上的截图表格中包含 3 条公开证件图片识别记录。档案管理页的真实运行截图如下。系统把借书证号、证件类型、平均置信度和复核状态写入 SQLite并在页面中提供导出入口。单条详情页会展示原始图片、结构化字段、OCR 引擎、置信度、复核提示和原始 OCR 文本方便管理员确认低信息量或字段缺失的证件。证件类型统计图如下。本次正式运行使用 3 张公开实物图片其中 1 张识别为学生证、1 张识别为借书证另有 1 张因有效字段过少被标记为类型待确认3 条记录均进入复核队列平均置信度约为 0.9564。三、技术选型PaddleOCR、Flask 与 SQLite 如何配合这个项目的技术栈并不复杂但每一层都对应真实业务中的一个环节。PaddleOCR 负责文本识别。真实运行时系统通过src/ocr_engine.py中的PaddleOCREngine加载 PaddleOCR并调用 OCR 接口获取文本行、置信度和文本框。由于 OCR 权重下载、PaddlePaddle 安装与 Python 版本有关为了保证项目包开箱可跑我额外实现了DemoOCREngine。它只用于内置脱敏样例图片会读取demo_data/sample_cards/expected_fields.json中的元数据模拟 OCR 输出。这样即使用户没有网络、没有 GPU、没有安装 PaddleOCR也可以先完整体验系统流程。Flask 负责 Web 管理界面。系统实现了首页看板、识别录入、档案管理、详情复核、删除记录、导出文件和 API 上传接口。Flask 官方文件上传模式中会使用multipart/form-data、request.files和werkzeug.utils.secure_filename()保存文件同时建议限制允许上传的扩展名和最大上传体积。项目中也按这个思路做了上传安全控制只允许png、jpg、jpeg、bmp、webp等图片格式。SQLite 负责本地档案库。课程设计和单机项目中SQLite 比 MySQL 更容易交付不需要额外服务。系统会自动创建data/db/card_archive.sqlite3识别后的字段会写入card_records表。后续如果要扩展为多人协同系统可以把src/database.py换成 MySQL、PostgreSQL 或 SQLAlchemy ORM。Pandas 与 openpyxl 负责导出。档案记录通过src/export_utils.py转为 DataFrame然后导出为 CSV 和 Excel方便管理员继续整理或导入其他系统。Pillow 用于生成脱敏样例图片和结果图。为了避免真实学生证隐私问题公开演示时不建议使用包含个人信息的真实证件图片项目样例中的姓名、学号和学院均为虚构数据适合博客截图、课程实践和交付演示。四、项目目录结构项目目录如下student_card_paddleocr_flask/ ├── app.py ├── main.py ├── run_demo.py ├── blog.md ├── README.md ├── requirements.txt ├── requirements_ocr_full.txt ├── configs/ │ └── config.json ├── src/ │ ├── config.py │ ├── data_generator.py │ ├── database.py │ ├── export_utils.py │ ├── field_parser.py │ ├── ocr_engine.py │ ├── pipeline.py │ ├── utils.py │ └── visualization.py ├── templates/ ├── static/ ├── demo_data/ │ └── sample_cards/ ├── data/ │ ├── db/ │ └── uploads/ ├── outputs/ ├── images/ │ ├── figures/ │ └── results/ ├── docs/ ├── logs/ ├── weights/ │ └── README_WEIGHTS.md ├── run.bat └── run.sh其中最重要的是app.py、src/ocr_engine.py、src/field_parser.py、src/database.py和src/pipeline.py。app.py是 Flask 入口负责页面路由和上传逻辑。用户通过/recognize上传图片系统保存文件后调用recognize_card()完成识别和入库。/records提供档案列表和搜索/records/id提供单条记录详情和人工复核/export/csv与/export/xlsx用于导出文件。src/ocr_engine.py封装 OCR 引擎。这个文件中有三个类PaddleOCREngine、DemoOCREngine和HybridOCREngine。HybridOCREngine是默认入口在auto模式下先尝试 PaddleOCR如果运行机器没有安装 PaddleOCR则对内置样例使用 demo 回退。这样做的好处是项目既能体现 PaddleOCR 的真实接入方式又不会因为权重或环境问题导致整个项目不能运行。src/field_parser.py负责把 OCR 文本转成结构化字段。OCR 的输出一般是文本行例如姓名张明 学号2023100101 学院信息工程学院 专业人工智能 班级AI2301 有效期2027-07-01解析器会识别“姓名、学号、借书证号、学院、专业、班级、有效期、电话”等字段标签并用规则清洗值。比如学号只保留数字借书证号保留字母和数字有效期统一转为YYYY-MM-DD格式。解析完成后还会检查是否缺少姓名、学号或借书证号并给出已结构化或需复核状态。src/database.py负责 SQLite 表创建、插入、查询、删除和统计。src/export_utils.py负责导出 CSV/Excel。src/visualization.py负责生成博客中使用的架构图、流程图、OCR 框图、档案表格预览和看板预览。五、配置文件说明项目配置集中在configs/config.json{project_name:student_card_paddleocr_flask,app:{port:5000,debug:false,secret_key:change-this-secret-key,max_upload_mb:8},paths:{database:data/db/card_archive.sqlite3,upload_dir:data/uploads,sample_dir:demo_data/sample_cards,output_dir:outputs,result_image_dir:images/results,figure_dir:images/figures},ocr:{engine:auto,language:ch,use_angle_cls:true,min_confidence:0.45,enable_demo_fallback:true}}其中ocr.engine有三个常用值auto是默认模式。系统先尝试 PaddleOCR如果没有安装 PaddleOCR会在内置样例图片上使用 demo 回退。paddleocr是真实 OCR 模式。用户需要先安装requirements_ocr_full.txt中的依赖并确保 PaddleOCR 能正常下载或读取模型权重。demo是纯样例模式。这个模式只适合项目演示和离线跑通不能识别用户随意上传的真实图片。路径配置可以按需修改。例如如果要把数据库放到其他目录只需要改paths.database。如果要把上传图片目录改到独立磁盘也可以修改paths.upload_dir。六、核心代码解析OCR 引擎适配OCR 引擎是本项目的第一层核心。真实环境中PaddleOCR 输出通常包含文本框、识别文本和置信度。项目中将这些内容统一封装为OCRLine和OCRResult后续字段解析器不需要关心 PaddleOCR 的具体版本差异。核心思路如下dataclassclassOCRLine:text:strconfidence:float1.0bbox:Optional[List[List[int]]]NonedataclassclassOCRResult:image_path:strengine:strlines:List[OCRLine]ok:boolTruemessage:strPaddleOCREngine的作用是把 PaddleOCR 的返回结果转成这些统一结构。PaddleOCR 2.x 常见调用方式是frompaddleocrimportPaddleOCR ocrPaddleOCR(langch,use_angle_clsTrue)resultocr.ocr(card.png,clsTrue)不同版本的 PaddleOCR 返回格式可能略有差异因此项目中写了_parse_v2_result()和_parse_generic_result()两个解析方法尽量兼容常见输出结构。对于 demo 模式DemoOCREngine会读取样例图片对应的元数据返回与 PaddleOCR 类似的文本行结果。这样设计还有一个好处如果后续想替换 OCR 引擎比如 EasyOCR、Tesseract、RapidOCR、PaddleOCR-VL 或云端 OCR只需要新增一个 Engine 类最终仍然返回OCRResult即可。七、核心代码解析字段结构化解析OCR 只能告诉我们图片上有哪些文字但业务系统需要的是字段。比如 OCR 结果里有“姓名张明”档案库中应该保存name张明。因此本项目把字段解析单独放在src/field_parser.py中。字段别名配置如下FIELD_ALIASES{name:[姓名,名字,Name],gender:[性别,Gender],student_id:[学号,学生编号,Student ID,StudentID,ID],library_id:[借书证号,读者证号,图书证号,Library ID,LibraryID,证号],college:[学院,院系,系部,College,Department],major:[专业,Major],class_name:[班级,Class],valid_until:[有效期,有效日期,Valid Until,Validity],phone:[联系电话,手机号,电话,Phone],borrow_limit:[可借册数,借阅额度,Borrow Limit],}这部分写成别名表是为了后续扩展方便。不同学校证件版式可能写“院系”而不是“学院”图书馆证件可能写“读者证号”而不是“借书证号”英文版证件可能写 “Student ID”。只要在别名表中补充标签解析器就能支持更多样式。字段解析完成后系统会执行简单校验。姓名、学号或借书证号是核心字段如果缺少这些信息记录会被标记为需复核。这个逻辑很适合真实项目因为 OCR 不可能保证所有图片都识别正确档案系统必须允许人工确认。八、核心代码解析Flask 上传与档案页面Flask 部分主要在app.py中。上传路由/recognize的基本流程是检查请求中是否包含图片文件检查文件名是否为空检查扩展名是否为允许的图片格式使用secure_filename()处理文件名保存到data/uploads/调用recognize_card()根据识别结果跳转到详情页。相关逻辑简化如下ifcard_imagenotinrequest.files:flash(没有找到上传文件。,warning)returnredirect(request.url)filerequest.files[card_image]iffile.filename:flash(请选择图片文件。,warning)returnredirect(request.url)ifnotallowed_file(file.filename):flash(仅支持 png、jpg、jpeg、bmp、webp 图片格式。,danger)returnredirect(request.url)filenamef{timestamp_slug()}_{secure_filename(file.filename)}save_pathupload_dir/filenamefile.save(save_path)resultrecognize_card(save_path,cfgcfg,save_to_dbTrue)档案管理页/records支持关键词查询可以按姓名、学号、借书证号、学院或证件类型检索。详情页/records/id展示证件图片、结构化字段、OCR 原文、置信度、状态和备注。管理员可以把状态从需复核改成已人工复核也可以删除错误记录。为了方便接口调用项目还提供/api/recognize。用户可以用 curl 或其他程序上传图片接口会返回 JSON其中包含 OCR 文本、结构化字段、校验结果和数据库记录 ID。九、数据库设计card_records表是系统核心表。字段设计如下字段说明idSQLite 自增主键file_name原始图片文件名image_path图片相对路径card_type学生证或借书证name姓名gender性别student_id学号library_id借书证号college学院major专业class_name班级valid_until有效期phone联系电话borrow_limit可借册数raw_textOCR 原始文本confidenceOCR 平均置信度engineOCR 引擎status识别状态warnings字段校验提示remark人工备注或 OCR 消息created_at入库时间SQLite 文件位于data/db/card_archive.sqlite3导出文件位于outputs/student_card_records.csv outputs/student_card_records.xlsx离线 demo 运行后会入库 4 条脱敏样例记录分别对应 2 张学生证和 2 张借书证。启用 PaddleOCR 后用户可以直接上传真实图片也可以扩展批量上传接口。本文最终截图使用公开证件实物图片验证真实 OCR 路径结果会根据字段完整度自动进入结构化或复核状态。十、运行方式建议使用 Python 3.10 或 3.11。先安装轻量依赖pipinstall-rrequirements.txt运行离线 demopython main.py--modedemo这个命令会完成以下事情生成内置样例证件图片初始化 SQLite 数据库执行 OCR 识别流程解析字段并写入数据库导出 CSV 和 Excel生成博客中的结果图保存outputs/demo_summary.json。启动 Web 系统python main.py--modeapp启动后按终端提示打开本地 Web 页面即可进入证件识别、档案管理和导出功能。十一、启用真实 PaddleOCR默认项目不把 PaddleOCR 作为强制依赖是为了保证代码包可以快速运行。真实识别任意上传图片时需要安装完整 OCR 依赖pipinstall-rrequirements_ocr_full.txt然后把配置改为ocr:{engine:paddleocr,language:ch,use_angle_cls:true}首次运行 PaddleOCR 时系统可能会下载文本检测、文本识别和方向分类模型。不同平台的 PaddlePaddle 安装命令可能不同尤其是 GPU 环境需要按官方文档选择对应 CUDA 版本。如果是在课程设计或普通 CPU 电脑上运行建议先使用 CPU 版本跑通。如果无法下载权重可以参考weights/README_WEIGHTS.md手动把 PaddleOCR 模型放到weights/paddleocr/目录并在src/ocr_engine.py中补充模型路径参数。十二、为什么要保留 demo OCR 回退很多 OCR 项目交付失败并不是业务逻辑写错而是模型依赖太重。PaddleOCR 需要 PaddlePaddlePaddlePaddle 又和 Python 版本、操作系统、CPU/GPU 环境相关。对于 CSDN 源码资源、课程实践项目或普通 Windows 用户来说如果一开始就要求安装完整深度学习环境很容易卡在依赖安装上。因此本项目采用“双模式”demo 模式保证项目包下载后能直接跑通PaddleOCR 模式用于真实图片识别和二次开发。demo 模式并不是替代真实 OCR而是降低上手门槛。用户先看到 Web 页面、字段解析、入库和导出效果再按需要安装 PaddleOCR。这样的交付体验更稳定也更适合教学和项目展示。十三、真实业务中的扩展方向第一个扩展方向是批量上传。当前页面支持单张图片上传适合演示和少量录入。真实业务中可以增加批量上传页面将多张证件图片依次识别生成批量复核列表。字段完整的记录自动入库字段缺失或置信度偏低的记录进入复核队列。第二个扩展方向是登录和权限。管理员、普通录入员、复核员可以拥有不同权限。录入员只能上传图片复核员可以修改状态和备注管理员可以删除记录和导出全量档案。第三个扩展方向是更强的信息抽取模型。当前项目主要通过规则解析字段适合版式比较稳定的学生证和借书证。如果要处理复杂表单、申请表、票据、扫描件可以考虑接入 PaddleOCR PP-Structure 的 KIE 模块或使用 LayoutXLM、PaddleOCR-VL 等文档理解模型。第四个扩展方向是数据库升级。SQLite 适合单机项目如果要多人访问可以改成 MySQL 或 PostgreSQL。表结构基本可以复用只需要替换数据库访问层。第五个扩展方向是错误样本回流。系统可以保存识别失败的图片和人工修正字段后续用于优化字段解析规则或作为自定义 KIE 模型训练数据。第六个扩展方向是接入学校业务系统。比如识别结果可以通过 API 写入图书馆读者系统、实验室门禁系统、活动报名系统或学生信息管理系统。十四、项目适用场景这个项目适合以下几类使用场景。第一类是课程设计和实践项目。项目包含 OCR、Web、数据库、数据导出、可视化结果功能完整度比普通单脚本更高适合 Python Web、人工智能应用开发、软件工程实践课程。第二类是 CSDN 技术博客和源码资源。文章可以围绕 PaddleOCR、Flask 文件上传、OCR 结构化解析、SQLite 档案管理展开读者下载代码后可以直接运行 demo。第三类是校园管理工具原型。虽然内置样例使用脱敏数据但系统结构可以迁移到真实场景。管理员可以上传学生证或借书证图片系统自动提取字段并入库减少重复录入。第四类是 OCR 项目二次开发模板。很多 OCR 业务都不是“识别文字”这么简单而是“识别文字后进入业务流程”。本项目的 OCR 引擎适配、字段解析、数据库入库、Web 查询和导出都可以复用到票据识别、表单录入、快递面单识别、证书信息提取等项目中。十五、运行结果说明本文的正式截图来自真实 PaddleOCR 模式。使用 3 张公开证件实物图片运行后可以得到下面这些结果文件和统计信息公开实物图片数量3 档案入库数量3 证件类型学生证 1 条借书证 1 条类型待确认 1 条 平均置信度0.9564 借书证号抽取结果29305000004507 复核队列3 条 导出文件student_card_records.csv、student_card_records.xlsx公开学生卡和公开借书卡不一定包含姓名、学院、专业等校园档案字段因此真实 OCR 结果中会出现“识别到了可见文字但核心字段不完整”的情况。系统不会把这类记录直接当作成功档案而是保留 OCR 原文、置信度和结构化字段并标记为需复核。这比只展示全字段样例更接近实际业务因为真实上传图片经常会存在遮挡、版式不匹配或字段缺失。在未安装 PaddleOCR 的机器上demo 运行时会使用内置样例回退模式。代码中已经保留 PaddleOCR 真实识别接口安装requirements_ocr_full.txt后即可切换真实 OCR。十六、总结本文完成了一个围绕校园证件识别的完整项目基于 PaddleOCR Flask 的学生证/借书证信息识别与档案录入系统。它解决的不只是 OCR 文本识别问题而是把证件图片中的文字转换为可检索、可复核、可导出的档案数据。从工程角度看项目把 OCR 引擎、字段解析、数据库、Web 页面和导出功能拆成独立模块后续维护和扩展比较方便。从交付角度看项目提供了离线 demo、样例图片、结果截图、运行脚本和说明文档适合 CSDN 发布、课程设计展示和二次开发。从业务角度看系统可以扩展到更多校园档案录入场景也可以迁移到票据、表单、证书、面单等结构化 OCR 任务。如果你需要一个既能运行、又能展示、还能扩展的 OCR 项目这个系统可以作为一个比较稳妥的基础模板。