# 🔍 OCR 可视化验证系统 一个功能强大的 OCR 识别与验证系统,集成了多种 OCR 工具支持、智能交叉验证、可视化校验和表格数据分析功能,专为财务报表、数据表格等复杂文档设计。 ## ✨ 核心功能 ### 🎯 多工具 OCR 支持 - **Dots OCR**:专业 VLM OCR 引擎 - **PaddleOCR PPStructV3**:结构化文档识别 - **Table Recognition V2**:专业表格识别 - **MinerU VLM-2.5.3**:多模态文档理解 ### 🔄 智能交叉验证 - **多数据源对比**:支持不同 OCR 工具结果的交叉验证 - **细粒度差异检测**:精确到单元格级别的差异分析 - **智能表格对比**: - 标准表格模式 - 流水表格模式(支持表头位置检测) - **差异分类统计**: - 金额差异(`table_amount`) - 日期时间差异(`table_datetime`) - 文本差异(`table_text`) - 表头差异(位置、内容、结构) - 段落差异 ### 📊 可视化校验工具 - **交互式图像标注**:点击文本高亮对应图像位置 - **精确坐标定位**:基于 bbox 的精确位置标示 - **旋转角度处理**: - 自动检测文档旋转角度 - 支持手动调整旋转 - 智能坐标转换 - **多渲染模式**: - HTML 渲染(支持横向滚动) - Markdown 渲染 - DataFrame 表格 - 原始文本 ### 📈 表格数据分析 - **智能表格解析**:自动识别并转换 HTML 表格 - **交互式操作**: - 过滤(按列值、关键词) - 排序(升序/降序) - 分页显示 - 列选择显示 - **数据导出**:支持 CSV、Excel 格式 - **统计分析**:自动生成数值列统计信息 ### 🔧 数字标准化 - 全角/半角字符转换 - 千分位分隔符标准化 - 小数点格式统一 - 支持批量标准化处理 ## 🚀 快速开始 ### 环境配置 ```bash # 创建 conda 环境 conda create -n py312 python=3.12 -y conda activate py312 # 克隆项目 git clone https://gitee.com/zhch158_admin/ocr_verify.git cd ocr_verify # 安装依赖 pip install -r requirements.txt # 或手动安装 pip install streamlit plotly pandas pillow numpy opencv-python openpyxl \ beautifulsoup4 pyyaml fuzzywuzzy python-Levenshtein ``` ### 配置文件 编辑 [`config.yaml`](config.yaml) 配置数据源: ```yaml data_sources: - name: "至远彩色_2023年报" ocr_tool: "ppstructv3" ocr_out_dir: "/path/to/ppstructv3/output" src_img_dir: "/path/to/source/images" description: "使用 PPStructV3 的识别结果" - name: "至远彩色_2023年报" ocr_tool: "mineru" ocr_out_dir: "/path/to/mineru/output" src_img_dir: "/path/to/source/images" description: "使用 MinerU 的识别结果" ``` ## 📖 使用指南 ### 1️⃣ 启动可视化验证工具 ```bash # 启动 Streamlit 应用 python -m streamlit run streamlit_ocr_validator.py # 或使用启动脚本 python run_streamlit_validator.py ``` **功能模块:** #### 📄 内容人工检查 - 选择数据源和页码 - 点击文本内容查看图像位置 - 旋转图像调整角度 - 显示所有文本框或仅显示选中框 #### 🔍 交叉验证结果 - 选择两个不同的 OCR 数据源 - 点击「交叉验证」按钮运行批量验证 - 查看详细的差异对比结果 - 下载验证报告(Excel、JSON) #### 📊 表格分析 - 解析 HTML 表格为 DataFrame - 过滤、排序、搜索表格数据 - 导出表格为 CSV 或 Excel - 查看统计信息 ### 2️⃣ 命令行对比工具 使用 [`compare_ocr_results.py`](compare_ocr_results.py) 进行命令行对比: ```bash # 基本对比 python compare_ocr_results.py file1.md file2.md # 使用流水表格模式 python compare_ocr_results.py file1.md file2.md \ --table-mode flow_list \ --similarity-algorithm ratio \ -o output/comparison_result \ -f both # 仅生成 JSON 报告 python compare_ocr_results.py file1.md file2.md \ -f json -o report ``` **参数说明:** - `-o, --output`:输出文件名(不含扩展名) - `-f, --format`:输出格式(`json`、`markdown`、`both`) - `--table-mode`:表格比对模式(`standard`、`flow_list`) - `--similarity-algorithm`:相似度算法(`ratio`、`partial_ratio`、`token_sort_ratio`、`token_set_ratio`) - `--ignore-images`:忽略图片内容对比 ### 3️⃣ 数字标准化工具 使用 [`normalize_financial_numbers.py`](normalize_financial_numbers.py): ```python from normalize_financial_numbers import normalize_financial_numbers, normalize_json_file # 标准化文本中的数字 text = "2023年净利润为28,239,305.48元" normalized = normalize_financial_numbers(text) # 输出: "2023年净利润为28,239,305.48元" # 批量标准化 JSON 文件 normalize_json_file("input.json", "output.json") ``` ## 📁 项目结构 ``` ocr_verify/ ├── streamlit_ocr_validator.py # 主应用入口 ├── streamlit_validator_core.py # 核心验证器类 ├── streamlit_validator_ui.py # UI 组件 ├── streamlit_validator_table.py # 表格处理 ├── streamlit_validator_cross.py # 交叉验证 ├── streamlit_validator_result.py # 结果展示 ├── ocr_validator_layout.py # 布局管理 ├── ocr_validator_utils.py # 工具函数 ├── ocr_validator_file_utils.py # 文件处理 ├── compare_ocr_results.py # OCR 结果对比 ├── normalize_financial_numbers.py # 数字标准化 ├── merge_mineru_paddle_ocr.py # 合并 MinerU 和 Paddle OCR 结果 ├── config.yaml # 配置文件 ├── styles.css # 样式文件 ├── output/ # 输出目录 │ └── pre_validation/ # 交叉验证结果 ├── .streamlit/ # Streamlit 配置 │ └── config.toml # Streamlit 设置 └── README.md # 项目文档 ``` ## 🎯 核心功能详解 ### 交叉验证流程 1. **数据源选择** - 选择 OCR 数据源(如 PPStructV3) - 选择验证数据源(如 MinerU) 2. **批量验证** - 自动匹配相同页码的文件 - 逐页进行差异检测 - 生成详细验证报告 3. **差异分析** - 表格差异:逐单元格对比 - 段落差异:智能段落匹配 - 结构差异:表头位置、行缺失等 4. **结果展示** - 差异列表(按类型、严重程度分类) - 统计图表(饼图、柱状图) - 详细对比视图(左右对照) ### 表格对比算法 #### 标准模式 (`standard`) - 适用于结构固定的表格 - 逐行逐列对比 - 适合财务报表、数据统计表 #### 流水表格模式 (`flow_list`) - 智能检测表头位置 - 支持表头前内容对比 - 自动列类型检测(数字、日期、文本) - 适合银行流水、交易记录等 ### 图像旋转处理 ```python # 自动检测旋转角度 detection_result = detect_image_orientation_by_opencv(image_path) # 手动调整旋转 validator.layout_manager.rotated_angle = 90 # 顺时针 90 度 # 坐标自动转换 rotated_image, rotated_bboxes = rotate_image_and_coordinates( image, angle, coordinates_list, rotate_coordinates=True ) ``` ## 📊 输出示例 ### 交叉验证报告 #### JSON 格式 ```json { "differences": [ { "type": "table_amount", "position": "第15行第5列", "file1_value": "15.00", "file2_value": "15,00", "description": "金额不一致: 15.00 vs 15,00", "severity": "medium", "column_name": "金额", "column_type": "numeric" } ], "statistics": { "total_differences": 42, "table_differences": 35, "amount_differences": 8, "datetime_differences": 3, "text_differences": 24, "paragraph_differences": 7, "high_severity": 8, "medium_severity": 20, "low_severity": 14 } } ``` #### Markdown 格式 ```markdown # OCR结果对比报告 ## 统计信息 - 总差异数量: **42** - 表格差异: **35** - 金额差异: **8** - 日期差异: **3** - 文本差异: **24** - 段落差异: **7** ## 差异详情 | 序号 | 位置 | 类型 | 原OCR结果 | 验证结果 | 描述 | |------|------|------|-----------|----------|------| | 1 | 第15行第5列 | table_amount | 15.00 | 15,00 | 金额不一致 | ``` ## 🔧 高级配置 ### OCR 工具配置 在 [`config.yaml`](config.yaml) 中配置工具参数: ```yaml ocr: tools: ppstructv3: name: "PPStructV3" json_structure: "object" rotation: coordinates_are_pre_rotated: true mineru: name: "MinerU" json_structure: "array" rotation: coordinates_are_pre_rotated: false ``` ### 合并 MinerU 和 Paddle OCR 结果 ```bash echo "A用户_单元格扫描流水" python merge_mineru_paddle_ocr.py \ --mineru-dir "/Users/zhch158/workspace/data/流水分析/A用户_单元格扫描流水/mineru-vlm-2.5.3_Results" \ --paddle-dir "/Users/zhch158/workspace/data/流水分析/A用户_单元格扫描流水/data_PPStructureV3_Results" \ --output-dir "/Users/zhch158/workspace/data/流水分析/A用户_单元格扫描流水/merged_results" \ --format "both" echo "B用户_扫描流水" python merge_mineru_paddle_ocr.py \ --mineru-dir "/Users/zhch158/workspace/data/流水分析/B用户_扫描流水/mineru-vlm-2.5.3_Results" \ --paddle-dir "/Users/zhch158/workspace/data/流水分析/B用户_扫描流水/data_PPStructureV3_Results" \ --output-dir "/Users/zhch158/workspace/data/流水分析/B用户_扫描流水/merged_results" \ --format "both" echo "德_内蒙古银行照" python merge_mineru_paddle_ocr.py \ --mineru-dir "/Users/zhch158/workspace/data/流水分析/德_内蒙古银行照/mineru-vlm-2.5.3_Results" \ --paddle-dir "/Users/zhch158/workspace/data/流水分析/德_内蒙古银行照/data_PPStructureV3_Results" \ --output-dir "/Users/zhch158/workspace/data/流水分析/德_内蒙古银行照/merged_results" \ --format "both" echo "对公_招商银行图" python merge_mineru_paddle_ocr.py \ --mineru-dir "/Users/zhch158/workspace/data/流水分析/对公_招商银行图/mineru-vlm-2.5.3_Results" \ --paddle-dir "/Users/zhch158/workspace/data/流水分析/对公_招商银行图/data_PPStructureV3_Results" \ --output-dir "/Users/zhch158/workspace/data/流水分析/对公_招商银行图/merged_results" \ --format "both" echo "至远彩色印刷工业有限公司" python merge_mineru_paddle_ocr.py \ --mineru-dir "/Users/zhch158/workspace/data/至远彩色印刷工业有限公司/mineru-vlm-2.5.3_Results" \ --paddle-dir "/Users/zhch158/workspace/data/至远彩色印刷工业有限公司/data_PPStructureV3_Results" \ --output-dir "/Users/zhch158/workspace/data/至远彩色印刷工业有限公司/merged_results" \ --format "both" ``` ### Streamlit 配置 编辑 [`.streamlit/config.toml`](.streamlit/config.toml): ```toml [theme] primaryColor = "#0288d1" backgroundColor = "#ffffff" secondaryBackgroundColor = "#f5f5f5" [server] maxUploadSize = 200 enableXsrfProtection = true ``` ## 🐛 常见问题 ### Q1: 图像显示位置不正确? **A:** 检查 OCR 工具的坐标是否已预旋转,在 `config.yaml` 中调整 `coordinates_are_pre_rotated` 设置。 ### Q2: 交叉验证结果为空? **A:** 确保两个数据源包含相同页码的文件,且文件名格式为 `*_page_XXX.json`。 ### Q3: 表格对比差异过多? **A:** 尝试切换到 `flow_list` 模式,或调整相似度算法参数。 ## 📝 开发说明 ### 扩展开发 - 新增 OCR 工具:在 `ocr_validator_utils.py` 中添加解析函数 - 自定义对比算法:继承 `OCRResultComparator` 类 - 新增渲染模式:在 `ocr_validator_layout.py` 中扩展 ## 🤝 贡献指南 欢迎提交 Issue 和 Pull Request! 1. Fork 本仓库 2. 创建特性分支 (`git checkout -b feature/AmazingFeature`) 3. 提交更改 (`git commit -m 'Add some AmazingFeature'`) 4. 推送到分支 (`git push origin feature/AmazingFeature`) 5. 提交 Pull Request ## 📄 许可证 本项目采用 MIT 许可证。详见 [LICENSE](LICENSE) 文件。 ## 📞 联系方式 - **作者**: zhch158_admin - **邮箱**: zhch158@sina.com - **仓库**: https://gitee.com/zhch158_admin/ocr_verify.git ## 🙏 致谢 --- **最后更新**: 2025年10月10日