# 通用图片表格识别工作流模板 本文档用于把一个空白目录整理成“图片列表 / 图片表格 OCR 识别 -> 结构化归档 -> 人工复核 -> 合并 -> 可选入库”的通用工作流模板。 模板抽象自 `~/Desktop/HIS数据处理/患者列表处理` 的成熟流程,但这里不绑定 HIS、患者列表、UPP 或任何具体业务字段。后续遇到类似“多张图片中包含规则表格,需要批量识别成结构化记录”的任务时,可先复制本模板,再人工补充腾讯云 API、Gitea、PostgreSQL、字段清洗规则和业务校验规则。 ## 1. 适用场景 适合: - 输入是一批或多批图片,图片中包含列表、目录、清单、统计表、检查单、排班表等规则表格。 - 需要保留每条结构化记录的来源图片、图片内行号、批次名等追溯信息。 - OCR 结果需要自动校验,也允许人工复核和人工修正。 - 最终结果既要保存在本地 JSON / CSV,也可能同步到 PostgreSQL 或其他数据库。 - 工作流需要可提交到 Gitea,但不能提交密钥、图片原件、OCR 缓存和识别结果。 不适合直接套用: - 图片完全无表格结构,需要复杂版面理解。 - 每张图片字段位置差异极大,无法用统一列名和统一清洗规则描述。 - 任务要求实时在线处理,而不是批量离线归档。 ## 2. 模板使用方式 新任务开始时,先人工填写本节占位信息。 ```text 项目名称:[填写,例如 PACS UPP 列表处理] 记录对象:[填写,例如 UPP 列表记录 / 检查记录 / 患者记录] 输入图片根目录:[填写,例如 待处理-xxx图片集群/批次文件夹名] 输出结果根目录:[填写,例如 数据处理结果区/已处理-xxx图片集群/批次文件夹名-列表归档结果] 主唯一键:[填写,例如 住院号 / 检查号 / accession_no / 影像号 / 组合键] 业务分类维度:[填写,例如 大科室、子科室;或 设备、项目类型;可为空] 目标数据库表:[填写,例如 "Generic_Image_Table_Records"] Gitea 仓库:[填写,例如 https://gitea.example.com/team/repo.git] ``` 字段定义表: | 序号 | 字段名 | 是否必填 | 清洗规则 | 校验规则 | 备注 | | --- | --- | --- | --- | --- | --- | | 1 | `[字段1]` | 是 / 否 | `[去空格、日期规范化等]` | `[不能为空、格式等]` | `[说明]` | | 2 | `[字段2]` | 是 / 否 | `[待补充]` | `[待补充]` | `[说明]` | | 3 | `[字段3]` | 是 / 否 | `[待补充]` | `[待补充]` | `[说明]` | 建议先明确字段顺序。图片表格 OCR 的后续清洗、CSV 导出、数据库列顺序、人工复核页面都会依赖这个顺序。 ## 3. 推荐目录结构 ```text . ├── README.md ├── 工作流_本地使用版.md ├── 工作流_Gitea版.md ├── 通用图片表格识别工作流模板.md ├── 待处理-[任务名]图片集群/ │ └── [批次文件夹名]/ ├── 已处理-[任务名]图片集群/ ├── 数据处理工作区/ │ ├── 01_任务配置.template.json │ ├── 01_任务配置.json │ ├── 02_图片表格OCR归档.py │ ├── 03_人工复核修正.template.json │ ├── 03_人工复核修正.json │ ├── 04_合并批次结果.py │ ├── 05_同步PostgreSQL单表.py │ ├── 06_PostgreSQL建表结构.template.sql │ ├── 06_PostgreSQL建表结构.sql │ ├── 07_处理程序说明.md │ └── 08_本地运行流程.template.sh ├── 数据处理结果区/ │ ├── 已处理-[任务名]图片集群/ │ └── 信息记录/ └── 人工复核网页端/ ``` 目录职责: - `待处理-[任务名]图片集群/`:新下载、尚未处理的原始图片批次。 - `已处理-[任务名]图片集群/`:确认完成归档后的原始图片批次。 - `数据处理工作区/`:任务配置、处理脚本、人工修正模板、数据库结构、说明和本地运行流程模板。 - `数据处理结果区/已处理-[任务名]图片集群/`:每个批次的 OCR 缓存、拼接图、结构化 JSON、CSV、复核报告。 - `数据处理结果区/信息记录/`:全局汇总、批次汇总、重复键报告、缺失键报告。 - `人工复核网页端/`:可选,用于可视化查看来源图片、修正字段、抽查和同步数据库。 提交到 Gitea 时,只提交程序、模板、空 README、SQL 结构和说明文档。不要提交图片、OCR 缓存、识别结果、人工修正实数据、`.env`、数据库导出文件。 ## 4. 配置占位 ### 4.1 腾讯云 OCR 推荐使用环境变量,不要写入脚本或文档。 ```bash export TENCENTCLOUD_SECRET_ID='填入腾讯云 SecretId' export TENCENTCLOUD_SECRET_KEY='填入腾讯云 SecretKey' export TENCENTCLOUD_REGION='ap-shanghai' ``` 建议脚本支持: ```text OCR 引擎:[table-v3 / general-accurate / 其他] 默认接口:RecognizeTableAccurateOCR 默认地域:ap-shanghai 单次超时:60-120 秒 失败重试:0-2 次 调用间隔:0.2-1 秒 ``` ### 4.2 PostgreSQL 数据库是可选模块。没有确认字段和表名之前,先只产出本地 JSON / CSV。 ```bash export WORKFLOW_DB_HOST='数据库主机' export WORKFLOW_DB_PORT='5432' export WORKFLOW_DB_NAME='数据库名' export WORKFLOW_DB_USER='数据库用户' export WORKFLOW_DB_PASSWORD='数据库密码' ``` 待人工补充: ```text 正式表名:[填写] 主键策略:[bigserial / uuid / 来源字段组合] 唯一约束:[填写主唯一键或组合唯一键] 允许为空字段:[填写] 必须人工复核才允许入库的异常:[填写] 索引字段:[填写常用查询字段] ``` ### 4.3 Gitea ```text 仓库地址:[填写] 默认分支:[main / master / 其他] 提交范围:程序、模板、说明、SQL、示例配置 排除范围:密钥、图片、OCR 缓存、处理结果、人工修正实数据、数据库密码 ``` 建议 `.gitignore` 至少包含: ```gitignore .env *.env __pycache__/ *.pyc 待处理-*图片集群/ 已处理-*图片集群/ 数据处理结果区/ 数据处理工作区/03_人工复核修正.json 人工复核网页端/instance/ ``` ## 5. 批处理脚本能力清单 `02_图片表格OCR归档.py` 建议具备以下能力: 1. 扫描输入目录,识别 `.png`、`.jpg`、`.jpeg`、`.bmp`。 2. 按自然序排序图片,例如 `第2页.png` 应排在 `第10页.png` 前面。 3. 可按第一层文件夹做业务分类,例如科室、设备、项目、来源系统。 4. 将多张图片纵向拼接,降低 OCR 调用次数。 5. 拼接时支持上下白边,例如 `--image-padding-y 24`,减少贴边表格行漏识别。 6. 调用 OCR 接口,响应写入 `raw_ocr/` 缓存。 7. 从 OCR 响应解析表格行和列,生成统一字段顺序的记录。 8. 将每条记录绑定来源图片、图片名、图片内行号、拼接组、OCR 请求 ID。 9. 对字段做清洗,例如空格归一、日期规范化、编号纠错、列错位修正。 10. 对记录做自动校验,输出 `自动复核通过` 或 `需人工复核`。 11. 支持读取 `03_人工复核修正.json` 后用缓存重建结果。 12. 支持主唯一键去重,输出重复键报告。 13. 输出结构化 JSON、JSONL、CSV、复核报告、汇总信息。 推荐命令参数: ```bash python3 数据处理工作区/02_图片表格OCR归档.py \ --config "数据处理工作区/01_任务配置.json" \ --input "待处理-[任务名]图片集群/[批次文件夹名]" \ --output "数据处理结果区/已处理-[任务名]图片集群/[批次文件夹名]-列表归档结果" \ --corrections "数据处理工作区/03_人工复核修正.json" \ --ocr-engine table-v3 \ --batch-size 6 \ --image-padding-y 24 \ --workers 1 \ --folder-workers 2 \ --timeout 90 \ --max-retries 1 ``` 只用已有 OCR 缓存重建: ```bash python3 数据处理工作区/02_图片表格OCR归档.py \ --config "数据处理工作区/01_任务配置.json" \ --input "待处理-[任务名]图片集群/[批次文件夹名]" \ --output "数据处理结果区/已处理-[任务名]图片集群/[批次文件夹名]-列表归档结果" \ --ocr-engine table-v3 \ --batch-size 6 \ --image-padding-y 24 \ --rebuild-from-cache ``` ## 6. OCR 策略模板 建议默认策略: - 图片预处理:保持原图,不裁切;必要时统一 RGB;拼接图背景使用白色。 - 拼接策略:先按 `batch-size=6` 纵向拼接;如果漏行、超时或接口失败,自动降到 `4/3/2/单张`。 - 白边策略:上下各加 `24px` 白边作为初始值;如果图片行距很小或边缘文字贴边,可增加到 `32px` 或 `40px`。 - 缓存策略:每个拼接图对应一个 OCR JSON 缓存;默认命中缓存不重新请求;加 `--force` 才重新识别。 - 行数校验:按图片高度、已知行数或模板行高估算预期行数,OCR 返回行数偏少时触发降档。 - 失败处理:单个拼接组失败时记录错误,不让整个批次无声失败;正式任务结束后必须检查错误列表。 输出目录建议: ```text [批次]-列表归档结果/ ├── merged_images/ │ └── [来源文件夹]/ ├── raw_ocr/ │ └── [来源文件夹]/ ├── 列表_分类归档.json ├── 图片表格_结构化.json ├── 图片表格_记录.jsonl ├── 图片表格_记录.csv ├── 复核报告.json ├── 重复主键报告.json └── 信息记录/ ├── 汇总.json └── 分类汇总.csv ``` ## 7. 结构化记录模板 建议每条记录采用分层结构,便于同时支持业务展示、复核和数据库同步。 ```json { "处理批次": "[批次名]", "业务分类1": "[例如大科室,可为空]", "业务分类2": "[例如子科室,可为空]", "来源文件夹": "[原始文件夹名]", "记录信息": { "[字段1]": "[值]", "[字段2]": "[值]", "[字段3]": "[值]" }, "图片信息": { "图片路径": "[原始图片路径]", "图片名": "[原始图片名]", "图片序号": "[自然排序序号或页码]", "图片内行号": 1, "拼接组序号": 1, "拼接图片路径": "[merged_images 路径]", "OCR缓存路径": "[raw_ocr 路径]", "OCR请求ID": "[接口返回 RequestId]" }, "复核": { "状态": "自动复核通过", "提示": [], "人工修正": false, "人工备注": "" } } ``` 复核状态建议统一: - `自动复核通过`:字段清洗和规则校验后没有发现明显问题。 - `需人工复核`:缺必填项、格式异常、行数可疑、主键缺失、时间逻辑异常等。 - `人工复核通过`:命中人工修正配置,修正后通过校验。 - `AI修改-待确认`:可作为网页端草稿状态,不应直接入库为人工确认结果。 ## 8. 字段清洗和校验模板 每个任务都需要人工补充清洗规则,不建议把某个业务的规则硬套到新任务。 基础清洗: - 全角转半角。 - 去除多余空格、换行、不可见字符。 - 统一日期格式,例如 `YYYY-MM-DD HH:MM:SS`。 - 统一编号格式,例如去空格、统一大小写、修正常见 OCR 误识别。 - 处理列错位,例如长文本吞入下一列、时间字段左移、数字字段被识别到备注列。 基础校验: - 主唯一键不能为空。 - 必填字段不能为空。 - 数字字段必须可转成整数或小数。 - 日期字段必须符合目标格式。 - 起止时间不能倒置;如果倒置,应标记为 `需人工复核`。 - 同批次或全局主唯一键重复时,必须输出重复报告。 任务专用校验占位: ```text [规则1]: [规则2]: [规则3]: ``` 去重策略占位: ```text 主唯一键:[填写] 重复时保留:[后出现记录 / 字段更完整记录 / 人工复核通过记录 / 其他] 缺少主唯一键:[剔除 / 保留但需人工复核 / 禁止入库] 重复报告文件名:[填写] ``` ## 9. 人工复核模板 人工修正文件建议只在本地存在,仓库只保留 `.template.json`。 `数据处理工作区/03_人工复核修正.template.json`: ```json [ { "图片路径": "待处理-[任务名]图片集群/[批次]/[图片名].png", "图片内行号": 1, "记录信息": { "[字段1]": "[人工确认值]", "[字段2]": "[人工确认值]" }, "复核选项": {}, "复核备注": "[可选]" } ] ``` 人工复核顺序: 1. 打开批次结果中的 `复核报告.json`。 2. 根据 `图片路径`、`图片名`、`图片内行号` 回看原图或网页端裁剪图。 3. 将确认值写入 `03_人工复核修正.json`。 4. 使用 `--rebuild-from-cache` 重建,不重复调用 OCR。 5. 检查 `复核报告.json` 中需复核数量是否下降。 6. 重新合并全局结果。 如果使用网页端,建议它至少支持: - 批次列表和汇总。 - 按复核状态过滤记录。 - 原图裁剪定位到图片内行。 - 编辑字段并保存到人工修正 JSON。 - 数据库可用时同步单条记录;数据库不可用时保留待同步状态。 - 抽查功能可选,AI 输出只作为辅助,不直接覆盖人工确认结果。 ## 10. 合并批次模板 `04_合并批次结果.py` 建议扫描 `数据处理结果区/` 下所有 `*-列表归档结果`,合并每个批次的结构化结果。 推荐输出: ```text 数据处理结果区/ ├── 合并_图片表格_结构化.json ├── 合并_图片表格_记录.jsonl ├── 合并_图片表格_记录.csv └── 信息记录/ ├── 全局汇总.json ├── 批次汇总.csv ├── 重复主键报告.json └── 缺少主键报告.json ``` 合并时建议重新执行全局去重,因为不同批次之间也可能出现重复主键。 运行: ```bash python3 数据处理工作区/04_合并批次结果.py --config "数据处理工作区/01_任务配置.json" ``` 合并后检查: ```text 批次数 总图片数 合并前记录数 合并后记录数 需人工复核记录数 人工修正记录数 重复主键剔除记录数 缺少主键剔除记录数 ``` ## 11. PostgreSQL 入库模板 `05_同步PostgreSQL单表.py` 建议只读取合并后的 JSON,生成临时 CSV,再用 `psql \copy` 导入正式表。 入库原则: - 数据库只放正式查看和追溯需要的字段。 - OCR 请求号、OCR 缓存路径、拼接图路径、拼接组细节等中间态字段默认留在本地结果目录,不进入正式表,除非业务明确需要。 - 主唯一键应有唯一约束。 - 必填主键应有非空约束。 - 重要时间逻辑、状态逻辑可放入数据库 CHECK 约束。 建表示例骨架: ```sql CREATE TABLE IF NOT EXISTS "[目标表名]" ( record_id bigserial PRIMARY KEY, batch_name text NOT NULL, source_folder text NOT NULL, image_path text NOT NULL, image_name text NOT NULL, image_row_no integer NOT NULL, unique_key text NOT NULL, field_1 text, field_2 text, field_3 text, review_status text NOT NULL, review_notes text, manual_corrected boolean NOT NULL DEFAULT false, imported_at timestamptz NOT NULL DEFAULT now(), audit_result text, audit_ai_feedback text, audit_manual_feedback text, audit_checked_by text, audit_checked_at timestamptz, CONSTRAINT uq_target_unique_key UNIQUE (unique_key), CONSTRAINT ck_target_unique_key_present CHECK (btrim(unique_key) <> '') ); CREATE INDEX IF NOT EXISTS idx_target_batch_name ON "[目标表名]"(batch_name); CREATE INDEX IF NOT EXISTS idx_target_source_folder ON "[目标表名]"(source_folder); CREATE INDEX IF NOT EXISTS idx_target_review_status ON "[目标表名]"(review_status); ``` 同步命令: ```bash export WORKFLOW_DB_HOST='数据库主机' export WORKFLOW_DB_PORT='5432' export WORKFLOW_DB_NAME='数据库名' export WORKFLOW_DB_USER='数据库用户' export WORKFLOW_DB_PASSWORD='数据库密码' python3 数据处理工作区/05_同步PostgreSQL单表.py \ --input "数据处理结果区/合并_图片表格_结构化.json" \ --schema "数据处理工作区/06_PostgreSQL建表结构.sql" \ --table '"[目标表名]"' ``` 入库后核对: ```sql SELECT count(*) FROM "[目标表名]"; SELECT review_status, manual_corrected, count(*) FROM "[目标表名]" GROUP BY review_status, manual_corrected; SELECT unique_key FROM "[目标表名]" GROUP BY unique_key HAVING count(*) > 1; ``` ## 12. 本地完整流程 处理一个新批次: ```bash # 1. 设置 OCR 密钥 export TENCENTCLOUD_SECRET_ID='填入腾讯云 SecretId' export TENCENTCLOUD_SECRET_KEY='填入腾讯云 SecretKey' # 2. 运行 OCR 归档 python3 数据处理工作区/02_图片表格OCR归档.py \ --config "数据处理工作区/01_任务配置.json" \ --input "待处理-[任务名]图片集群/[批次文件夹名]" \ --output "数据处理结果区/已处理-[任务名]图片集群/[批次文件夹名]-列表归档结果" \ --ocr-engine table-v3 \ --batch-size 6 \ --image-padding-y 24 \ --workers 1 \ --folder-workers 2 \ --timeout 90 \ --max-retries 1 # 3. 检查复核报告和重复报告 # 4. 必要时填写 03_人工复核修正.json # 5. 用缓存重建 python3 数据处理工作区/02_图片表格OCR归档.py \ --config "数据处理工作区/01_任务配置.json" \ --input "待处理-[任务名]图片集群/[批次文件夹名]" \ --output "数据处理结果区/已处理-[任务名]图片集群/[批次文件夹名]-列表归档结果" \ --ocr-engine table-v3 \ --batch-size 6 \ --image-padding-y 24 \ --rebuild-from-cache # 6. 合并所有批次 python3 数据处理工作区/04_合并批次结果.py --config "数据处理工作区/01_任务配置.json" # 7. 可选:同步数据库 python3 数据处理工作区/05_同步PostgreSQL单表.py ``` 确认无误后移动原始图片批次: ```bash mv "待处理-[任务名]图片集群/[批次文件夹名]" "已处理-[任务名]图片集群/" ``` ## 13. Gitea 提交流程 提交前检查: ```bash git status --short --ignored git diff --cached --name-only rg -n "Secret|PASSWORD|密码|密钥|TENCENTCLOUD_SECRET|DB_PASSWORD" README.md 工作流*.md 数据处理工作区 人工复核网页端 ``` 推荐只提交: ```bash git add \ .gitignore \ README.md \ 工作流_本地使用版.md \ 工作流_Gitea版.md \ 通用图片表格识别工作流模板.md \ 数据处理工作区/01_任务配置.template.json \ 数据处理工作区/02_图片表格OCR归档.py \ 数据处理工作区/03_人工复核修正.template.json \ 数据处理工作区/04_合并批次结果.py \ 数据处理工作区/05_同步PostgreSQL单表.py \ 数据处理工作区/06_PostgreSQL建表结构.template.sql \ 数据处理工作区/07_处理程序说明.md \ 数据处理工作区/08_本地运行流程.template.sh \ 人工复核网页端 git commit -m "Add generic image table OCR workflow" git push origin main ``` 不要提交: ```text .env 数据处理工作区/03_人工复核修正.json 待处理-*图片集群/ 已处理-*图片集群/ 数据处理结果区/ raw_ocr/ merged_images/ *.csv *.jsonl 包含真实业务数据的 *.json ``` ## 14. 迁移到新任务时的改造清单 必须改: - `[任务名]`、输入目录、输出目录。 - 字段顺序和字段名。 - OCR 行列解析逻辑。 - 字段清洗规则。 - 必填字段和复核规则。 - 主唯一键和去重策略。 - CSV 表头。 - PostgreSQL 表名、列名、约束和索引。 通常要改: - 分类规则,例如科室、设备、项目类型、来源系统。 - 行数估算规则,例如每张图片有多少数据行。 - 拼接白边和默认 batch-size。 - 人工复核网页端展示字段。 - 抽查提示词和 AI 校验标准。 通常不用改: - 环境变量读取方式。 - OCR 缓存机制。 - `--rebuild-from-cache` 重建方式。 - 批次合并流程。 - Gitea 排除真实数据和密钥的原则。 ## 15. 完成标准 一个批次可以认为处理完成,需要同时满足: - OCR 脚本运行结束,没有未处理的接口错误。 - `图片表格_结构化.json` 和 `图片表格_记录.csv` 已生成。 - `复核报告.json` 已检查,需人工复核项已处理或明确保留。 - 主唯一键缺失和重复报告已检查。 - 合并脚本已运行,全局汇总符合预期。 - 如果启用 PostgreSQL,入库记录数与合并结果一致。 - 原始图片批次已从 `待处理` 移到 `已处理`。 - Gitea 仓库没有密钥、图片、OCR 缓存、真实处理结果。 ## 16. 给未来智能体的执行提示 遇到一个新图片表格任务时,先不要直接写死业务规则。建议按以下顺序推进: 1. 读取本模板和当前目录结构。 2. 盘点待处理图片批次、图片数量、图片命名规律。 3. 抽样查看 3-5 张图片,确认表格字段、行高、是否有表头、是否跨页。 4. 让用户确认字段顺序、主唯一键、是否需要数据库。 5. 基于模板生成或改造处理脚本。 6. 先小批量试跑,检查 OCR 响应、行数和列错位。 7. 固化清洗规则和复核规则。 8. 全批次运行,输出报告。 9. 人工复核后用缓存重建。 10. 合并、可选入库、归档。 本模板只定义工作流骨架。腾讯云 API 密钥、Gitea 地址、PostgreSQL 连接、目标表结构、业务字段、人工修正规则,都应在具体任务中由人工确认后再补充。