Files
PACS/UPP列表处理/通用图片表格识别工作流模板.md
2026-05-25 12:33:24 +08:00

21 KiB
Raw Permalink Blame History

通用图片表格识别工作流模板

本文档用于把一个空白目录整理成“图片列表 / 图片表格 OCR 识别 -> 结构化归档 -> 人工复核 -> 合并 -> 可选入库”的通用工作流模板。

模板抽象自 ~/Desktop/HIS数据处理/患者列表处理 的成熟流程,但这里不绑定 HIS、患者列表、UPP 或任何具体业务字段。后续遇到类似“多张图片中包含规则表格,需要批量识别成结构化记录”的任务时,可先复制本模板,再人工补充腾讯云 API、Gitea、PostgreSQL、字段清洗规则和业务校验规则。

1. 适用场景

适合:

  • 输入是一批或多批图片,图片中包含列表、目录、清单、统计表、检查单、排班表等规则表格。
  • 需要保留每条结构化记录的来源图片、图片内行号、批次名等追溯信息。
  • OCR 结果需要自动校验,也允许人工复核和人工修正。
  • 最终结果既要保存在本地 JSON / CSV也可能同步到 PostgreSQL 或其他数据库。
  • 工作流需要可提交到 Gitea但不能提交密钥、图片原件、OCR 缓存和识别结果。

不适合直接套用:

  • 图片完全无表格结构,需要复杂版面理解。
  • 每张图片字段位置差异极大,无法用统一列名和统一清洗规则描述。
  • 任务要求实时在线处理,而不是批量离线归档。

2. 模板使用方式

新任务开始时,先人工填写本节占位信息。

项目名称:[填写,例如 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. 推荐目录结构

.
├── 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

推荐使用环境变量,不要写入脚本或文档。

export TENCENTCLOUD_SECRET_ID='填入腾讯云 SecretId'
export TENCENTCLOUD_SECRET_KEY='填入腾讯云 SecretKey'
export TENCENTCLOUD_REGION='ap-shanghai'

建议脚本支持:

OCR 引擎:[table-v3 / general-accurate / 其他]
默认接口RecognizeTableAccurateOCR
默认地域ap-shanghai
单次超时60-120 秒
失败重试0-2 次
调用间隔0.2-1 秒

4.2 PostgreSQL

数据库是可选模块。没有确认字段和表名之前,先只产出本地 JSON / CSV。

export WORKFLOW_DB_HOST='数据库主机'
export WORKFLOW_DB_PORT='5432'
export WORKFLOW_DB_NAME='数据库名'
export WORKFLOW_DB_USER='数据库用户'
export WORKFLOW_DB_PASSWORD='数据库密码'

待人工补充:

正式表名:[填写]
主键策略:[bigserial / uuid / 来源字段组合]
唯一约束:[填写主唯一键或组合唯一键]
允许为空字段:[填写]
必须人工复核才允许入库的异常:[填写]
索引字段:[填写常用查询字段]

4.3 Gitea

仓库地址:[填写]
默认分支:[main / master / 其他]
提交范围程序、模板、说明、SQL、示例配置
排除范围密钥、图片、OCR 缓存、处理结果、人工修正实数据、数据库密码

建议 .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、复核报告、汇总信息。

推荐命令参数:

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 缓存重建:

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 白边作为初始值;如果图片行距很小或边缘文字贴边,可增加到 32px40px
  • 缓存策略:每个拼接图对应一个 OCR JSON 缓存;默认命中缓存不重新请求;加 --force 才重新识别。
  • 行数校验按图片高度、已知行数或模板行高估算预期行数OCR 返回行数偏少时触发降档。
  • 失败处理:单个拼接组失败时记录错误,不让整个批次无声失败;正式任务结束后必须检查错误列表。

输出目录建议:

[批次]-列表归档结果/
├── merged_images/
│   └── [来源文件夹]/
├── raw_ocr/
│   └── [来源文件夹]/
├── 列表_分类归档.json
├── 图片表格_结构化.json
├── 图片表格_记录.jsonl
├── 图片表格_记录.csv
├── 复核报告.json
├── 重复主键报告.json
└── 信息记录/
    ├── 汇总.json
    └── 分类汇总.csv

7. 结构化记录模板

建议每条记录采用分层结构,便于同时支持业务展示、复核和数据库同步。

{
  "处理批次": "[批次名]",
  "业务分类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 误识别。
  • 处理列错位,例如长文本吞入下一列、时间字段左移、数字字段被识别到备注列。

基础校验:

  • 主唯一键不能为空。
  • 必填字段不能为空。
  • 数字字段必须可转成整数或小数。
  • 日期字段必须符合目标格式。
  • 起止时间不能倒置;如果倒置,应标记为 需人工复核
  • 同批次或全局主唯一键重复时,必须输出重复报告。

任务专用校验占位:

[规则1]
[规则2]
[规则3]

去重策略占位:

主唯一键:[填写]
重复时保留:[后出现记录 / 字段更完整记录 / 人工复核通过记录 / 其他]
缺少主唯一键:[剔除 / 保留但需人工复核 / 禁止入库]
重复报告文件名:[填写]

9. 人工复核模板

人工修正文件建议只在本地存在,仓库只保留 .template.json

数据处理工作区/03_人工复核修正.template.json

[
  {
    "图片路径": "待处理-[任务名]图片集群/[批次]/[图片名].png",
    "图片内行号": 1,
    "记录信息": {
      "[字段1]": "[人工确认值]",
      "[字段2]": "[人工确认值]"
    },
    "复核选项": {},
    "复核备注": "[可选]"
  }
]

人工复核顺序:

  1. 打开批次结果中的 复核报告.json
  2. 根据 图片路径图片名图片内行号 回看原图或网页端裁剪图。
  3. 将确认值写入 03_人工复核修正.json
  4. 使用 --rebuild-from-cache 重建,不重复调用 OCR。
  5. 检查 复核报告.json 中需复核数量是否下降。
  6. 重新合并全局结果。

如果使用网页端,建议它至少支持:

  • 批次列表和汇总。
  • 按复核状态过滤记录。
  • 原图裁剪定位到图片内行。
  • 编辑字段并保存到人工修正 JSON。
  • 数据库可用时同步单条记录;数据库不可用时保留待同步状态。
  • 抽查功能可选AI 输出只作为辅助,不直接覆盖人工确认结果。

10. 合并批次模板

04_合并批次结果.py 建议扫描 数据处理结果区/ 下所有 *-列表归档结果,合并每个批次的结构化结果。

推荐输出:

数据处理结果区/
├── 合并_图片表格_结构化.json
├── 合并_图片表格_记录.jsonl
├── 合并_图片表格_记录.csv
└── 信息记录/
    ├── 全局汇总.json
    ├── 批次汇总.csv
    ├── 重复主键报告.json
    └── 缺少主键报告.json

合并时建议重新执行全局去重,因为不同批次之间也可能出现重复主键。

运行:

python3 数据处理工作区/04_合并批次结果.py --config "数据处理工作区/01_任务配置.json"

合并后检查:

批次数
总图片数
合并前记录数
合并后记录数
需人工复核记录数
人工修正记录数
重复主键剔除记录数
缺少主键剔除记录数

11. PostgreSQL 入库模板

05_同步PostgreSQL单表.py 建议只读取合并后的 JSON生成临时 CSV再用 psql \copy 导入正式表。

入库原则:

  • 数据库只放正式查看和追溯需要的字段。
  • OCR 请求号、OCR 缓存路径、拼接图路径、拼接组细节等中间态字段默认留在本地结果目录,不进入正式表,除非业务明确需要。
  • 主唯一键应有唯一约束。
  • 必填主键应有非空约束。
  • 重要时间逻辑、状态逻辑可放入数据库 CHECK 约束。

建表示例骨架:

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);

同步命令:

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 '"[目标表名]"'

入库后核对:

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. 本地完整流程

处理一个新批次:

# 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

确认无误后移动原始图片批次:

mv "待处理-[任务名]图片集群/[批次文件夹名]" "已处理-[任务名]图片集群/"

13. Gitea 提交流程

提交前检查:

git status --short --ignored
git diff --cached --name-only
rg -n "Secret|PASSWORD|密码|密钥|TENCENTCLOUD_SECRET|DB_PASSWORD" README.md 工作流*.md 数据处理工作区 人工复核网页端

推荐只提交:

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

不要提交:

.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 连接、目标表结构、业务字段、人工修正规则,都应在具体任务中由人工确认后再补充。