STREAMLIT_GUIDE.md 19 KB

🚀 Streamlit OCR可视化校验工具使用指南

🎯 工具介绍

基于Streamlit开发的OCR可视化校验工具,提供现代化的Web界面和丰富的交互体验,让OCR结果校验变得直观高效。特别新增了强大的表格数据分析功能。

🔧 核心功能

  • 实时交互: 点击文本即时高亮图片位置
  • 动态过滤: 搜索、类别筛选、条件过滤
  • 数据表格: 可排序的详细数据视图
  • 统计信息: 实时统计和进度跟踪
  • 错误标记: 一键标记和管理识别错误
  • 报告导出: 生成详细的校验报告
  • 表格分析: HTML表格转DataFrame,支持过滤、排序、导出
  • 多种渲染: HTML/Markdown/DataFrame/原始文本四种显示模式

🚀 快速启动

1. 安装依赖

# 安装Streamlit和相关依赖
pip install streamlit plotly pandas pillow numpy opencv-python openpyxl

2. 启动应用

# 方法1: 完整功能版本
python -m streamlit run streamlit_ocr_validator.py

# 方法2: 使用启动脚本
python run_streamlit_validator.py

# 方法3: 开发模式(自动重载)
streamlit run streamlit_ocr_validator.py --server.runOnSave true

3. 访问界面

浏览器会自动打开 http://localhost:8501,如果没有自动打开,请手动访问该地址。

🖥️ 界面使用指南

主界面布局

┌─────────────────────────────────────────────────────────────────────┐
│ 🔍 OCR可视化校验工具                                                 │
├─────────────────────────────────────────────────────────────────────┤
│ 📊 总文本块: 13  🔗 可点击: 9  ❌ 标记错误: 2  ✅ 准确率: 85.7%      │
├─────────────────────────┬───────────────────────────────────────────┤
│ 📄 OCR识别内容            │ 🖼️ 原图标注                               │
│                        │                                           │
│ 🔍 搜索框               │ [显示选中位置的红框标注]                   │
│ 📍 选择文本下拉框        │ [图片缩放和详细信息]                       │
│                        │                                           │
│ 📝 MD内容预览           │ 📍 选中文本详情                           │
│ [4种渲染模式选择]        │ - 文本内容: xxx                           │
│ ○ HTML渲染             │ - 位置: [x1,y1,x2,y2]                    │
│ ● Markdown渲染         │ - 宽度: xxx px                            │
│ ○ DataFrame表格 ⭐      │ - 高度: xxx px                            │
│ ○ 原始文本             │                                           │
│                        │                                           │
│ 🎯 可点击文本列表        │                                           │
│ [📍 文本1] [❌] [✅]     │                                           │
│ [📍 文本2] [❌] [✅]     │                                           │
└─────────────────────────┴───────────────────────────────────────────┘

侧边栏功能

┌─────────────────────┐
│ 📁 文件选择          │
│ [选择OCR结果文件]    │
│ [🔄 加载文件]       │
│                    │
│ 🎛️ 控制面板         │
│ [🧹 清除选择]       │
│ [❌ 清除错误标记]   │
│                    │
│ 📊 表格快捷操作 ⭐   │
│ [🔍 快速预览表格]   │
│ [📥 一键导出所有表格] │
│                    │
│ 🔧 调试信息         │
│ [调试信息开关]      │
└─────────────────────┘

使用步骤

  1. 选择文件

    • 从侧边栏下拉框中选择OCR结果JSON文件
    • 点击"🔄 加载文件"按钮加载数据
    • 查看顶部统计信息确认加载成功
  2. 浏览统计信息

    • 查看总文本块数量
    • 了解可点击文本数量
    • 确认图片是否正确加载
    • 查看当前准确率
  3. 交互校验

    • 使用下拉框选择要校验的文本
    • 点击左侧的"📍 文本内容"按钮
    • 观察右侧图片上的红色框标注
    • 查看右下角显示的详细位置信息
  4. 搜索过滤

    • 使用搜索框快速定位特定文本
    • 在MD内容预览中查看完整识别结果
    • 通过搜索结果快速定位问题文本
  5. 表格数据分析 ⭐ 新增

    • 选择"DataFrame表格"渲染模式
    • 查看自动解析的HTML表格
    • 使用过滤、排序功能分析数据
    • 查看表格统计信息
    • 导出CSV或Excel文件
  6. 错误标记管理

    • 点击文本旁边的"❌"按钮标记错误
    • 点击"✅"按钮取消错误标记
    • 观察准确率的实时变化
    • 使用侧边栏批量清除标记

🎨 高级功能

完整版本独有功能 (streamlit_ocr_validator.py)

📊 错误标记系统

  • 标记错误: 点击文本旁边的"❌"按钮标记识别错误
  • 取消标记: 点击"✅"按钮取消错误标记
  • 统计准确率: 自动计算识别准确率
  • 错误过滤: 只显示标记为错误的文本
  • 批量操作: 侧边栏提供批量清除功能

📈 表格数据分析 ⭐ 核心新功能

  • 智能表格检测: 自动识别HTML表格内容
  • DataFrame转换: 将HTML表格转换为可操作的pandas DataFrame
  • 多维度操作: 支持过滤、排序、搜索等操作
  • 统计分析: 自动生成表格行列数、数值列统计等信息
  • 数据导出: 支持CSV、Excel格式导出
  • 可视化图表: 基于表格数据生成统计图表

🎛️ 多种渲染模式

  • HTML渲染: 原生HTML表格显示,保持格式
  • Markdown渲染: 转换为Markdown表格格式
  • DataFrame表格: 转换为可交互的数据表格 ⭐
  • 原始文本: 纯文本格式显示

🔧 侧边栏控制

  • 文件管理: 侧边栏选择和管理OCR文件
  • 控制面板: 清除选择、清除错误标记等操作
  • 表格快捷操作: 快速预览和导出表格功能 ⭐
  • 调试信息: 详细的系统状态和数据信息

📊 过滤和筛选

  • 多条件过滤: 按类别、错误状态、尺寸等多重筛选
  • 实时搜索: 动态搜索文本内容
  • 数据表格: 可排序、可筛选的完整数据视图

表格分析功能详解 ⭐

功能特性

# 表格检测和转换
if '<table>' in display_content.lower():
    st.session_state.validator.display_html_table_as_dataframe(display_content)
else:
    st.info("当前内容中没有检测到HTML表格")

支持的表格操作

  1. 基础操作

    • 自动检测HTML表格
    • 转换为pandas DataFrame
    • 表格信息统计(行数、列数、列名等)
  2. 数据过滤

    • 按列内容过滤
    • 支持文本搜索
    • 条件筛选
  3. 数据排序

    • 按任意列排序
    • 升序/降序选择
    • 多列排序
  4. 统计分析

    • 数值列描述性统计
    • 数据类型分析
    • 缺失值统计
  5. 数据导出

    • CSV格式导出
    • Excel格式导出
    • 支持过滤后数据导出

使用示例

# 在streamlit界面中
def display_html_table_as_dataframe(self, html_content: str, enable_editing: bool = False):
    """将HTML表格解析为DataFrame显示"""
    import pandas as pd
    from io import StringIO, BytesIO
    
    try:
        # 使用pandas直接读取HTML表格
        tables = pd.read_html(StringIO(html_content))
        if tables:
            for i, table in enumerate(tables):
                st.subheader(f"📊 表格 {i+1}")
                
                # 创建表格操作按钮
                col1, col2, col3, col4 = st.columns(4)
                with col1:
                    show_info = st.checkbox(f"显示表格信息", key=f"info_{i}")
                with col2:
                    show_stats = st.checkbox(f"显示统计信息", key=f"stats_{i}")
                with col3:
                    enable_filter = st.checkbox(f"启用过滤", key=f"filter_{i}")
                with col4:
                    enable_sort = st.checkbox(f"启用排序", key=f"sort_{i}")
                
                # 显示表格
                st.dataframe(table, use_container_width=True)

🔧 自定义开发

扩展功能开发

1. 添加新的表格处理功能 ⭐

import plotly.express as px
import streamlit as st

def create_table_visualization(df):
    """创建表格数据可视化"""
    if not df.empty:
        numeric_cols = df.select_dtypes(include=[np.number]).columns
        
        if len(numeric_cols) > 0:
            # 创建统计图表
            fig = px.bar(
                x=df.index,
                y=df[numeric_cols[0]],
                title=f"{numeric_cols[0]} 分布"
            )
            st.plotly_chart(fig, use_container_width=True)
            
            # 创建散点图
            if len(numeric_cols) > 1:
                fig_scatter = px.scatter(
                    df, 
                    x=numeric_cols[0], 
                    y=numeric_cols[1],
                    title=f"{numeric_cols[0]} vs {numeric_cols[1]}"
                )
                st.plotly_chart(fig_scatter, use_container_width=True)

# 在主应用中使用
if st.checkbox("显示数据可视化"):
    create_table_visualization(filtered_table)

2. 高级表格编辑功能

def advanced_table_editor(df):
    """高级表格编辑器"""
    st.subheader("🔧 高级编辑")
    
    # 数据编辑
    edited_df = st.data_editor(
        df,
        use_container_width=True,
        num_rows="dynamic",  # 允许添加删除行
        key="advanced_editor"
    )
    
    # 数据验证
    if not edited_df.equals(df):
        st.success("✏️ 数据已修改")
        
        # 显示变更统计
        changes = len(edited_df) - len(df)
        st.info(f"行数变化: {changes:+d}")
        
        # 导出修改后的数据
        if st.button("💾 保存修改"):
            csv_data = edited_df.to_csv(index=False)
            st.download_button(
                "下载修改后的数据",
                csv_data,
                "modified_table.csv",
                "text/csv"
            )
    
    return edited_df

3. 批量表格处理

def batch_table_processing():
    """批量表格处理功能"""
    st.subheader("📦 批量表格处理")
    
    uploaded_files = st.file_uploader(
        "上传多个包含表格的文件", 
        type=['md', 'html'], 
        accept_multiple_files=True
    )
    
    if uploaded_files and st.button("开始批量处理"):
        all_tables = []
        progress_bar = st.progress(0)
        
        for i, file in enumerate(uploaded_files):
            content = file.read().decode('utf-8')
            
            if '<table' in content.lower():
                tables = pd.read_html(StringIO(content))
                for j, table in enumerate(tables):
                    table['source_file'] = file.name
                    table['table_index'] = j
                    all_tables.append(table)
            
            progress_bar.progress((i + 1) / len(uploaded_files))
        
        if all_tables:
            st.success(f"✅ 共处理 {len(all_tables)} 个表格")
            
            # 合并所有表格
            if st.checkbox("合并所有表格"):
                try:
                    merged_df = pd.concat(all_tables, ignore_index=True)
                    st.dataframe(merged_df)
                    
                    # 导出合并结果
                    csv_data = merged_df.to_csv(index=False)
                    st.download_button(
                        "下载合并表格",
                        csv_data,
                        "merged_tables.csv",
                        "text/csv"
                    )
                except Exception as e:
                    st.error(f"合并失败: {e}")

4. 表格数据质量检查 ⭐

def table_quality_check(df):
    """表格数据质量检查"""
    st.subheader("🔍 数据质量检查")
    
    # 基础统计
    col1, col2, col3 = st.columns(3)
    with col1:
        st.metric("总行数", len(df))
    with col2:
        st.metric("总列数", len(df.columns))
    with col3:
        null_percent = (df.isnull().sum().sum() / (len(df) * len(df.columns))) * 100
        st.metric("缺失值比例", f"{null_percent:.1f}%")
    
    # 详细质量报告
    quality_issues = []
    
    # 检查空值
    null_cols = df.columns[df.isnull().any()].tolist()
    if null_cols:
        quality_issues.append(f"发现 {len(null_cols)} 列存在空值: {', '.join(null_cols)}")
    
    # 检查重复行
    duplicate_rows = df.duplicated().sum()
    if duplicate_rows > 0:
        quality_issues.append(f"发现 {duplicate_rows} 行重复数据")
    
    # 检查数据类型一致性
    for col in df.columns:
        if df[col].dtype == 'object':
            # 检查是否应该是数值类型
            numeric_like = df[col].str.replace(',', '').str.replace('$', '')
            try:
                pd.to_numeric(numeric_like, errors='raise')
                quality_issues.append(f"列 '{col}' 可能应该是数值类型")
            except:
                pass
    
    if quality_issues:
        st.warning("⚠️ 发现数据质量问题:")
        for issue in quality_issues:
            st.write(f"- {issue}")
    else:
        st.success("✅ 数据质量良好")

📊 性能优化

1. 缓存优化

@st.cache_data
def load_and_process_ocr_data(file_path: str):
    """缓存OCR数据加载和处理"""
    with open(file_path, 'r') as f:
        ocr_data = json.load(f)
    
    # 处理数据
    processed_data = process_ocr_data(ocr_data)
    return processed_data

@st.cache_resource
def load_image(image_path: str):
    """缓存图片加载"""
    return Image.open(image_path)

@st.cache_data
def parse_html_tables(html_content: str):
    """缓存表格解析结果"""
    try:
        tables = pd.read_html(StringIO(html_content))
        return tables
    except:
        return []

2. 大文件处理

def handle_large_tables():
    """处理大型表格"""
    if 'page_size' not in st.session_state:
        st.session_state.page_size = 100
    
    # 分页显示表格
    if not df.empty:
        total_rows = len(df)
        pages = (total_rows - 1) // st.session_state.page_size + 1
        
        col1, col2, col3 = st.columns([1, 2, 1])
        with col2:
            current_page = st.slider("页数", 1, pages, 1)
        
        # 显示当前页数据
        start_idx = (current_page - 1) * st.session_state.page_size
        end_idx = min(start_idx + st.session_state.page_size, total_rows)
        current_df = df.iloc[start_idx:end_idx]
        
        st.dataframe(current_df, use_container_width=True)
        st.info(f"显示第 {start_idx+1}-{end_idx} 行,共 {total_rows} 行")

3. 内存优化

def optimize_dataframe_memory(df):
    """优化DataFrame内存使用"""
    initial_memory = df.memory_usage(deep=True).sum()
    
    # 优化数值类型
    for col in df.select_dtypes(include=['int']).columns:
        df[col] = pd.to_numeric(df[col], downcast='integer')
    
    for col in df.select_dtypes(include=['float']).columns:
        df[col] = pd.to_numeric(df[col], downcast='float')
    
    # 优化字符串类型
    for col in df.select_dtypes(include=['object']).columns:
        if df[col].nunique() < len(df) * 0.5:  # 如果唯一值少于50%,转换为category
            df[col] = df[col].astype('category')
    
    final_memory = df.memory_usage(deep=True).sum()
    reduction = (initial_memory - final_memory) / initial_memory * 100
    
    st.info(f"内存优化:减少 {reduction:.1f}% ({initial_memory/1024/1024:.1f}MB → {final_memory/1024/1024:.1f}MB)")
    
    return df

🚀 部署指南

本地开发部署

# 开发模式运行(自动重载)
streamlit run streamlit_ocr_validator.py --server.runOnSave true

# 指定端口运行
streamlit run streamlit_ocr_validator.py --server.port 8502

# 指定主机运行(局域网访问)
streamlit run streamlit_ocr_validator.py --server.address 0.0.0.0

Docker部署

FROM python:3.9-slim

WORKDIR /app

# 安装系统依赖
RUN apt-update && apt-get install -y \
    libgl1-mesa-glx \
    libglib2.0-0 \
    libsm6 \
    libxext6 \
    libxrender-dev \
    libgomp1 \
    && rm -rf /var/lib/apt/lists/*

# 安装Python依赖
COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .

EXPOSE 8501
CMD ["streamlit", "run", "streamlit_ocr_validator.py", "--server.address=0.0.0.0"]

Streamlit Cloud部署

  1. 将代码推送到GitHub仓库
  2. 访问 https://share.streamlit.io/
  3. 连接GitHub仓库并部署
  4. 设置环境变量(如API密钥)

💡 最佳实践

1. 用户体验优化

  • 加载状态: 使用st.spinner()显示加载状态
  • 错误处理: 使用st.error()友好地显示错误信息
  • 进度提示: 使用st.progress()显示处理进度
  • 数据缓存: 合理使用@st.cache_data提升性能

2. 界面设计

  • 布局清晰: 使用st.columns()合理分布内容
  • 视觉层次: 使用不同级别的标题和分隔符
  • 交互反馈: 及时响应用户操作
  • 移动友好: 考虑不同屏幕尺寸的适配

3. 表格处理最佳实践 ⭐

  • 大表格处理: 对超过1000行的表格启用分页显示
  • 内存管理: 使用数据类型优化减少内存使用
  • 导出优化: 大表格导出时显示进度条
  • 错误处理: 优雅处理表格解析失败的情况

4. 数据安全

  • 输入验证: 验证上传文件的格式和内容
  • 错误处理: 妥善处理异常情况
  • 资源清理: 及时清理临时文件和内存

🎉 总结

Streamlit版本的OCR校验工具经过升级后提供了更加强大的功能:

基础功能:实时交互、动态更新、错误管理
表格分析:HTML表格转DataFrame、多种操作、导出功能 ⭐
数据处理:过滤、排序、统计分析、可视化 ⭐
批量操作:多文件处理、批量导出、合并功能 ⭐
质量检查:数据质量分析、问题检测、优化建议 ⭐
扩展性:易于添加新功能和自定义组件
用户体验:现代化界面、响应式设计、直观操作

新增的表格分析功能使其不仅能够校验OCR结果,更能深入分析表格数据,成为一个完整的OCR数据处理工作台!


🌟 特别推荐:使用DataFrame表格模式分析财务报表等结构化数据,体验完整的数据处理工作流程。