Python利用PaddleOCR进行扫描版PDF的跨页表格提取与合并

作者:

文章目录
  • 在处理PDF文件中的表格时,常常会遇到表格跨页的情况。并且一些PDF文件为扫描版。这种情况下,如果要将跨页的表格合并为一个完整的表格,手动操作不仅繁琐且容易出错。因此,本文将介绍如何利用PaddleOCR和Python代码,自动化地检测并合并这些跨页表格。
  • 首先,我们需要安装以下库: pandas:数据处理 paddleocr:OCR识别表格结构 pdf2image:将PDF页面转换为图像 beautifulsoup4:解析HTML numpy:数组处理 安装命令如下: pip install pandas paddleocr pdf2image beautifulsoup4 numpy 引入所需的库并设置一些警告和日志配置,以确保代码执行过程中不会被不必要的信息干扰: import pandas as pd from paddleocr import PPStructure, save_structure_res from pdf2image import convert_from_path from bs4 import BeautifulSoup import warnings import numpy as np import logging import os warnings.filterwarnings(“ignore”) logging.disable(logging.DEBUG) logging.disable(logging.WARNING)
  • 定义PDF文件的路径和一些参数阈值,用于判断表格是否跨页: path = ‘E:/Jobcontent/data/测试/’ output_folder = “E:/table/ex/” topthreshold = 0.2 dthreshold = 0.8 table_engine = PPStructure(show_log=True)
  • 这些辅助函数用于提取PDF页面中的表格信息,并判断表格是否跨页。 top_bottom_table_info:获取页面中最上方表格的列数和坐标。 find_bottom_table_info:获取页面中最下方表格的列数和坐标。 is_continuation:判断表格是否跨页。 def top_bottom_table_info(table_result): top_table = None min_y = 0 for table in table_result: if table[‘type’] == ‘table’: bbox = table[‘bbox’] current_bottom_y = bbox[1] if top_table is None or current_bottom_y < min_y: top_table = table min_y = current_bottom_y if top_table is not None: soup = BeautifulSoup(top_table[‘res’][‘html’], ‘html.parser’) last_row = soup.find_all(‘tr’)[-1] columns = last_row.find_all(‘td’) top_row_columns = len(columns) top_xy = top_table[‘bbox’] return top_row_columns, top_xy else: return None def find_bottom_table_info(table_result): bottom_table = None bottom_y = 0 for table in table_result: if table[‘type’] == ‘table’: bbox = table[‘bbox’] current_bottom_y = bbox[3] if bottom_table is None or current_bottom_y > bottom_y: bottom_table = table bottom_y = current_bottom_y if bottom_table is not None: soup = BeautifulSoup(bottom_table[‘res’][‘html’], ‘html.parser’) last_row = soup.find_all(‘tr’)[0] columns = last_row.find_all(‘td’) last_row_columns = len(columns) bottom_xy = bottom_table[‘bbox’] return last_row_columns, bottom_xy else: return None def is_continuation(top_row_columns, last_row_columns, bottom_xy, top_xy, page_height, dthreshold=0.8, topthreshold=0.2): if top_row_columns != last_row_columns: return False is_last_table_at_bottom = bottom_xy[3] > dthreshold * page_height is_first_table_at_top = top_xy[1] < topthreshold * page_height return is_last_table_at_bottom and is_first_table_at_top
  • 读取PDF文件并提取每页的表格信息。对于跨页的表格,提取其列数和坐标,并将结果合并。 获取PDF文件列表:获取指定路径下所有以“.pdf”结尾的文件。 逐个处理PDF文件:对于每个PDF文件,初始化一个列表来存储跨页表格信息。 将PDF页面转换为图像:将PDF文件的每一页转换为图像,并逐页处理。 提取表格信息:使用table_engine函数从每个页面图像中提取表格信息,并保存结构化结果。 检测跨页表格:检查当前页的最后一行和下一页的第一行的列数是否相同,如果相同,则记录跨页表格的信息。 合并跨页表格:对于检测到的跨页表格,读取跨页的两部分表格,合并后保存为CSV文件。 完成提取:在处理完所有PDF文件后,打印“表格提取完成”的消息。 pdf_files = [f for f in os.listdir(path) if f.endswith(‘.pdf’)] print(pdf_files) for pdf_file in pdf_files: cross_page_tables = [] pdf_path = os.path.join(path, pdf_file) images = convert_from_path(pdf_path, dpi=200) print(‘正在提取表格,请耐心等待…’) for page_number, image in enumerate(images): table_result = table_engine(np.array(image)) save_structure_res(table_result, output_folder, f'{page_number+1}’) _, page_height = image.size last_row_columns, bottom_xy = find_bottom_table_info(table_result) if page_number+1 < len(images): table_result_end = table_engine(np.array(images[page_number+1])) top_row_columns, top_xy = top_bottom_table_info(table_result_end) if is_continuation(top_row_columns, last_row_columns, bottom_xy, top_xy, page_height): cross_page_tables.append((bottom_xy, top_xy, page_number+1, page_number+2)) print(f”{pdf_file} 的表格在第 {page_number+1} 页和第 {page_number+2} 页之间跨页,并且最后一行和下一页的第一行列数相同”) if cross_page_tables: for (bottom_xy, top_xy, start_page, end_page) in cross_page_tables: output_folder_s = output_folder + f'{start_page}/’ output_folder_t = output_folder + f'{end_page}/’ file_s = f'{bottom_xy}’+’_0’+’.xlsx’ file_t = f'{top_xy}’+’_0’+’.xlsx’ s_path = os.path.join(output_folder_s, file_s) e_path = os.path.join(output_folder_t, file_t) table_result_start =pd.read_excel(s_path, header=None) table_result_end = pd.read_excel(e_path, header=None) merged_table = pd.concat([table_result_start, table_result_end], ignore_index=True) output_path = os.path.join(output_folder, f'{pdf_file}_merged_{start_page}_{end_page}.csv’) merged_table.to_csv(output_path, index=False) print(‘表格提取完成’)
  • 通过上述代码,可以实现对扫描版PDF文件中跨页表格的检测与合并,并将结果保存为CSV文件。该方法对提升PDF表格处理的自动化程度和效率具有重要意义。 到此这篇关于Python利用PaddleOCR进行扫描版PDF的跨页表格提取与合并的文章就介绍到这了,更多相关Python PaddleOCR PDF跨页表格提取与合并内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客! 您可能感兴趣的文章: Python使用PaddleOCR实现PDF/图片文字识别与版面还原 Python调用paddleocr编写一个桌面端PDF识别工具 Python使用paddleOCR批量识别pdf的方法
  • 目录
    • 前言
    • 1.环境准备
    • 2.文件路径与阈值设置
    • 3.定义辅助函数
    • 4.处理PDF文件
    • 5.总结

    在处理PDF文件中的表格时,常常会遇到表格跨页的情况。并且一些PDF文件为扫描版。这种情况下,如果要将跨页的表格合并为一个完整的表格,手动操作不仅繁琐且容易出错。因此,本文将介绍如何利用PaddleOCR和Python代码,自动化地检测并合并这些跨页表格。

    首先,我们需要安装以下库:

    • pandas:数据处理
    • paddleocr:OCR识别表格结构
    • pdf2image:将PDF页面转换为图像
    • beautifulsoup4:解析HTML
    • numpy:数组处理

    安装命令如下:

    pip install pandas paddleocr pdf2image beautifulsoup4 numpy

    引入所需的库并设置一些警告和日志配置,以确保代码执行过程中不会被不必要的信息干扰:

    import pandas as pd
    from paddleocr import PPStructure, save_structure_res
    from pdf2image import convert_from_path
    from bs4 import BeautifulSoup
    import warnings
    import numpy as np
    import logging
    import os
    
    warnings.filterwarnings("ignore")
    logging.disable(logging.DEBUG)
    logging.disable(logging.WARNING)
    

    定义PDF文件的路径和一些参数阈值,用于判断表格是否跨页:

    path = 'E:/Jobcontent/data/测试/'
    output_folder = "E:/table/ex/"
    topthreshold = 0.2
    dthreshold = 0.8
    
    table_engine = PPStructure(show_log=True)
    
    

    这些辅助函数用于提取PDF页面中的表格信息,并判断表格是否跨页。

    • top_bottom_table_info:获取页面中最上方表格的列数和坐标。
    • find_bottom_table_info:获取页面中最下方表格的列数和坐标。
    • is_continuation:判断表格是否跨页。
    def top_bottom_table_info(table_result):
        top_table = None
        min_y = 0
        for table in table_result:
            if table['type'] == 'table':
                bbox = table['bbox']
                current_bottom_y = bbox[1]
                if top_table is None or current_bottom_y < min_y:
                    top_table = table
                    min_y = current_bottom_y
    
        if top_table is not None:
            soup = BeautifulSoup(top_table['res']['html'], 'html.parser')
            last_row = soup.find_all('tr')[-1]
            columns = last_row.find_all('td')
            top_row_columns = len(columns)
            top_xy = top_table['bbox']
            return top_row_columns, top_xy
        else:
            return None
    
    def find_bottom_table_info(table_result):
        bottom_table = None
        bottom_y = 0
        for table in table_result:
            if table['type'] == 'table':
                bbox = table['bbox']
                current_bottom_y = bbox[3]
                if bottom_table is None or current_bottom_y > bottom_y:
                    bottom_table = table
                    bottom_y = current_bottom_y
    
        if bottom_table is not None:
            soup = BeautifulSoup(bottom_table['res']['html'], 'html.parser')
            last_row = soup.find_all('tr')[0]
            columns = last_row.find_all('td')
            last_row_columns = len(columns)
            bottom_xy = bottom_table['bbox']
            return last_row_columns, bottom_xy
        else:
            return None
    
    def is_continuation(top_row_columns, last_row_columns, bottom_xy, top_xy, page_height, dthreshold=0.8, topthreshold=0.2):
        if top_row_columns != last_row_columns:
            return False
        is_last_table_at_bottom = bottom_xy[3] > dthreshold * page_height
        is_first_table_at_top = top_xy[1] < topthreshold * page_height
        return is_last_table_at_bottom and is_first_table_at_top
    

    读取PDF文件并提取每页的表格信息。对于跨页的表格,提取其列数和坐标,并将结果合并。

    1. 获取PDF文件列表:获取指定路径下所有以“.pdf”结尾的文件。
    2. 逐个处理PDF文件:对于每个PDF文件,初始化一个列表来存储跨页表格信息。
    3. 将PDF页面转换为图像:将PDF文件的每一页转换为图像,并逐页处理。
    4. 提取表格信息:使用table_engine函数从每个页面图像中提取表格信息,并保存结构化结果。
    5. 检测跨页表格:检查当前页的最后一行和下一页的第一行的列数是否相同,如果相同,则记录跨页表格的信息。
    6. 合并跨页表格:对于检测到的跨页表格,读取跨页的两部分表格,合并后保存为CSV文件。
    7. 完成提取:在处理完所有PDF文件后,打印“表格提取完成”的消息。
    pdf_files = [f for f in os.listdir(path) if f.endswith('.pdf')]
    print(pdf_files)
    
    for pdf_file in pdf_files:
        cross_page_tables = []
        pdf_path = os.path.join(path, pdf_file)
        images = convert_from_path(pdf_path, dpi=200)
        print('正在提取表格,请耐心等待...')
        for page_number, image in enumerate(images):
            table_result = table_engine(np.array(image))
            save_structure_res(table_result, output_folder, f'{page_number+1}')
    
            _, page_height = image.size
            last_row_columns, bottom_xy = find_bottom_table_info(table_result)
            if page_number+1 < len(images):
                table_result_end = table_engine(np.array(images[page_number+1]))
                top_row_columns, top_xy = top_bottom_table_info(table_result_end)
    
                if is_continuation(top_row_columns, last_row_columns, bottom_xy, top_xy, page_height):
                    cross_page_tables.append((bottom_xy, top_xy, page_number+1, page_number+2))
                    print(f"{pdf_file} 的表格在第 {page_number+1} 页和第 {page_number+2} 页之间跨页,并且最后一行和下一页的第一行列数相同")
    
        if cross_page_tables:
            for (bottom_xy, top_xy, start_page, end_page) in cross_page_tables:
                output_folder_s = output_folder + f'{start_page}/'
                output_folder_t = output_folder + f'{end_page}/'
                file_s = f'{bottom_xy}'+'_0'+'.xlsx'
                file_t = f'{top_xy}'+'_0'+'.xlsx'
                s_path = os.path.join(output_folder_s, file_s)
                e_path = os.path.join(output_folder_t, file_t)
                table_result_start =pd.read_excel(s_path, header=None)
                table_result_end = pd.read_excel(e_path, header=None)
                merged_table = pd.concat([table_result_start, table_result_end], ignore_index=True)
                output_path = os.path.join(output_folder, f'{pdf_file}_merged_{start_page}_{end_page}.csv')
                merged_table.to_csv(output_path, index=False)
    
    print('表格提取完成')
    
    

    通过上述代码,可以实现对扫描版PDF文件中跨页表格的检测与合并,并将结果保存为CSV文件。该方法对提升PDF表格处理的自动化程度和效率具有重要意义。

    到此这篇关于Python利用PaddleOCR进行扫描版PDF的跨页表格提取与合并的文章就介绍到这了,更多相关Python PaddleOCR PDF跨页表格提取与合并内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!

    您可能感兴趣的文章:

    • Python使用PaddleOCR实现PDF/图片文字识别与版面还原
    • Python调用paddleocr编写一个桌面端PDF识别工具
    • Python使用paddleOCR批量识别pdf的方法

    站内搜索