利用PaddleOCR进行图片的跨页表格提取与合并(PDF扫描版)

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

  • 前言
    • 1.环境准备
    • 2.文件路径与阈值设置
    • 3.定义辅助函数
    • 4.处理PDF文件
    • 5.总结

前言

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

1.环境准备

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

  • 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 oswarnings.filterwarnings("ignore")
logging.disable(logging.DEBUG)
logging.disable(logging.WARNING)

2.文件路径与阈值设置

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

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

3.定义辅助函数

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

  • top_bottom_table_info:获取页面中最上方表格的列数和坐标。
  • find_bottom_table_info:获取页面中最下方表格的列数和坐标。
  • is_continuation:判断表格是否跨页。
def top_bottom_table_info(table_result):top_table = Nonemin_y = 0for 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 = tablemin_y = current_bottom_yif 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_xyelse:return Nonedef find_bottom_table_info(table_result):bottom_table = Nonebottom_y = 0for 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 = tablebottom_y = current_bottom_yif 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_xyelse:return Nonedef 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 Falseis_last_table_at_bottom = bottom_xy[3] > dthreshold * page_heightis_first_table_at_top = top_xy[1] < topthreshold * page_heightreturn is_last_table_at_bottom and is_first_table_at_top

4.处理PDF文件

读取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.sizelast_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('表格提取完成')

5.总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/45651.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php将png转为jpg,可设置压缩率

/** * 将PNG文件转换为JPG文件 * param $pngFilePath string PNG文件路径 * param $jpgFilePath string JPG文件路径 * param $quality int JPG质量,0-100,值越低&#xff0c;压缩率越高 * return void * throws Exception */ function convertPngToJpg($pngFilePath, $jpgFile…

Golang:数据科学领域中的高性能并发编程新星

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒📝 并发性能的卓越表现📝 系统级工具的便捷性📝 语言设计的简洁性📝 强类型系统的严格性📝 版本兼容性的稳定性📝 内置工具的全面性⚓️ 相关链接 ⚓️📖 介绍 📖 在数据科学和机器学习的广阔天地…

Web3 社交领域的开发技术

Web3 社交领域的开发技术主要包括以下几种&#xff0c;随着 Web3 技术的不断发展&#xff0c;Web3 社交领域将会出现更多新的技术和应用场景。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1. 区块链技术 区块链技术是 Web3 社交的…

Arcgis横向图例设置

想把这个图例改成横向的 点击图例的属性&#xff0c;找到样式

Sklearn 入门教程:开启机器学习之旅

一、引言 在当今数据驱动的时代&#xff0c;机器学习已经成为解决各种实际问题的强大工具。Scikit-learn&#xff08;简称 sklearn&#xff09;是 Python 中广泛使用的机器学习库&#xff0c;它提供了丰富的算法和工具&#xff0c;使得构建和训练机器学习模型变得简单而高效。本…

虚幻引擎ue5游戏运行界面白茫茫一片,怎么处理

根剧下图顺序即可调节游戏运行界面光照问题&#xff1a; 在大纲里找到post&#xff0c;然后选中它&#xff0c;找到Exposure 把最低亮度和最高亮度的0改为1即可

C# Winform 系统方案目录的管理开发

在做一个中等复杂程度项目时&#xff0c;我们通常有系统全局配置&#xff0c;还要有对应的方案目录的管理和更新。 比如我们有如下需求&#xff1a;开发一个方案管理&#xff0c;可以新建、打开和保存方案&#xff0c;同时还需要保存方案中的各种文件。我设计的采用目录管理和…

在Linux上部署Java项目过程

文章目录 1、ps -ef | grep java2、杀死指定的.jar程序3、此时再查看java进程4、找到.jar包在linux上存储的位置5、切换到存放.jar目录5、把相应的.jar包放入这个目录6、启动指定的java程序 1、ps -ef | grep java [rootiZuf6332h890vozldoxcprZ bailian]# ps -ef | grep java…

fastadmin 如何通过权限组来控制列的显示与隐藏

方法1 以版本控制&#xff08;application/admin/controller/Version.php&#xff09;为例子 需求 就是在有时候&#xff0c;有些列不想让这个权限组的人看到&#xff0c;只给制定的权限组的人看 1.给权限组创建一个字段 ALTER TABLE lt_auth_group ADD COLUMN isBoothView T…

IDEA 中的调试方式(以 java 为例)

文章目录 IDEA 中的调试方式(以 java 为例)1. 基本介绍2. 断点调试的快捷键2.1 设置断点并启动调试2.3 快捷键 IDEA 中的调试方式(以 java 为例) 在开发中查找错误的时候&#xff0c;我们可以用断点调试&#xff0c;一步一步的看源码执行的过程&#xff0c;从而发现错误所在。 …

如何在QGC中接收和处理无人机上传的各种传感器数据(如GPS、IMU等)。

在 QGroundControl (QGC) 中接收和处理无人机上传的各种传感器数据&#xff08;如 GPS、IMU 等&#xff09;&#xff0c;主要通过 MAVLink 协议实现。MAVLink 是一种轻量级的消息传输协议&#xff0c;用于无人机和地面站之间的通信。QGC 通过 MAVLink 消息接收来自无人机的传感…

iPhone删除所有照片的高效三部曲

苹果手机用久了&#xff0c;系统缓存包括自己使用手机留下的内存肯定会越来越多。其中&#xff0c;相册中的照片数量可能会急剧增加&#xff0c;占据大量的存储空间。当用户们想要对相册进行彻底清理&#xff0c;实现iPhone删除所有照片时&#xff0c;不妨跟随以下详细的三部曲…

数据结构(3.9_1)——特殊矩阵的压缩存储

总览 一维数组的存储结构 如果下标从1开始&#xff0c;则a[i]的存放地址LOC (i-1)*sizeof(ElemType); 二维数组的存储 二维数组也具有随机存储的特性 设起始地址为LOC 在M行N列的二维数组b[M][N]中&#xff0c;若按行优先存储&#xff0c; 则b[i][j]的存储地址的LOC (i*…

百度2025校园招聘内推开始啦

百度2025校园招聘内推开始啦&#xff0c;快来投递你心仪的职位吧&#xff08; 网申链接地址&#xff1a;https://talent.baidu.com/jobs/list?recommendCodeIZB4S3&recruitTypeGRADUATE &#xff09;填入内推码&#xff0c;完成投递&#xff0c;get内推绿色通道~我的内推码…

ASP.NET Core中创建中间件的几种方式

前言 今天我们一起来盘点一下在ASP.NET Core应用程序中添加和创建中间件常见的四种方式。 中间件介绍 ASP.NET Core中间件&#xff08;Middleware&#xff09;是用于处理HTTP请求和响应的组件&#xff0c;它们被安排在请求处理管道中&#xff0c;并按顺序执行。中间件的设计是为…

ES 慢上游响应问题优化在用户体验场景中的实践

在抖音亿级日活流量的情况下&#xff0c;每天收到的用户反馈也是大量的&#xff0c;而用户反馈对于产品的发展与未来是至关重要的&#xff0c;因此用户体验管理平台&#xff08;简称VoC&#xff09;就应运而生&#xff0c;VoC 平台旨在通过技术平台化的方式&#xff0c;结合反馈…

uni-app 保存号码到通讯录

1、 添加模块 2、添加权限 3、添加策略 Android&#xff1a; "permissionExternalStorage" : {"request" : "none","prompt" : "应用保存运行状态等信息&#xff0c;需要获取读写手机存储&#xff08;系统提示为访问设备上的照片…

房屋出租管理系统小程序需求分析及功能介绍

房屋租赁管理系统适用于写字楼、办公楼、厂区、园区、商城、公寓等商办商业不动产的租赁管理及租赁营销&#xff1b;提供资产管理&#xff0c;合同管理&#xff0c;租赁管理&#xff0c; 物业管理&#xff0c;门禁管理等一体化的运营管理平台&#xff0c;提高项目方管理运营效率…

Eureka: Netflix开源的服务发现框架

在微服务架构中&#xff0c;服务发现是一个关键组件&#xff0c;它允许服务实例之间相互发现并进行通信。Eureka是由Netflix开源的服务发现框架&#xff0c;它是Spring Cloud体系中的核心组件之一。Eureka提供了服务注册与发现的功能&#xff0c;支持区域感知和自我保护机制&am…

电脑如何快速删除相同的文件?分享5款重复文件删除工具

您有没有发现最近电脑运行速度变慢了&#xff1f;启动时间变得更长&#xff0c;甚至完成简单任务也难以如常&#xff1f;这可能是因为重复文件堆积所致。我们发现&#xff0c;清理或移动这些重复的文件和文件夹可以产生惊人的效果。通过删除不必要的重复文件和垃圾文件&#xf…