改进拖放PDF转换为图片在转换为TXT文件的程序

news/2024/9/28 6:23:11/

前段时间我写了Python识别拖放的PDF文件再转成文本文件-CSDN博客

最近有2点更新,一是有一些pdf文件转换出来的图片是横的,这样也可以识别文字,但是可能会影响效果,另一个是发现有一些文字识别不出来,看了关于提高PaddleOCR识别准确率的一些优化(一)_如何提高paddleocr识别准确率-CSDN博客发现是图片文件的尺寸太大了,为此将其缩小一半再识别。确实提高了识别率。

代码:

# -*- coding: utf-8 -*-
"""
Created on Sun Aug 25 10:42:39 2024@author: YBK
"""import tkinter as tk
import windnd
from tkinter.messagebox import showinfo
import os
from PIL import Image
import fitz
from fitz import Document as openPDF
import time
import re
from paddleocr import PaddleOCR
import subprocessdef dec_to_36(num):base = [str(x) for x in range(10)] + [chr(x) for x in range(ord('A'),ord("A")+26)]# 前者把 0 ~ 9 转换成字符串存进列表 base 里,后者把 A ~ Z 存进列表l = []if num<0:return "-"+dec_to_36(abs(num))while True:num,rem = divmod(num,36) # 求商 和 留余数l.append(base[rem])if num == 0:return "".join(l[::-1])def nowtime_to_str():#将当前时间戳转化为36进制,约6位字符,减少文件名长度unix_timestamp = int(time.time())return(dec_to_36(unix_timestamp))def pdf2pic(path, pic_path):'''# 从pdf中提取图片:param path: pdf的路径:param pic_path: 图片保存的路径:return:'''t0 = time.perf_counter()# 使用正则表达式来查找图片checkXO = r"/Type(?= */XObject)"checkIM = r"/Subtype(?= */Image)"# 打开pdfdoc = openPDF(path)# 图片计数imgcount = 0lenXREF = doc.xref_length()# 打印PDF的信息print("文件名:{}, 页数: {}, 对象: {}".format(path, len(doc), lenXREF - 1))# 遍历每一个对象for i in range(1, lenXREF):# 定义对象字符串text = doc.xref_object(i)isXObject = re.search(checkXO, text)# 使用正则表达式查看是否是图片isImage = re.search(checkIM, text)# 如果不是对象也不是图片,则continueif not isXObject or not isImage:continueimgcount += 1# 根据索引生成图像pix = fitz.Pixmap(doc, i)# 根据pdf的路径生成图片的名称# new_name = path.replace('\\', '_') + "_img{}.png".format(imgcount)# new_name = new_name.replace(':', '')new_name = os.path.basename(path).replace('.pdf', '_') + "img" + str(imgcount).zfill(3) + ".png"# 如果pix.n<5,可以直接存为PNGif pix.n < 5:pix._writeIMG(os.path.join(pic_path, new_name),1,10)# 否则先转换CMYKelse:pix0 = fitz.Pixmap(fitz.csRGB, pix)pix0._writeIMG(os.path.join(pic_path, new_name),1,10)pix0 = None# 释放资源pix = Noneimage = Image.open(os.path.join(pic_path, new_name))#对于尺寸大于2000 * 2000的图像,缩放至(h * 0.5,w * 0.5)识别准确率有所提升if image.width > 2000 or image.height > 2000:new_image = image.resize((int(image.width * 0.5), int(image.height * 0.5)))new_image.save(os.path.join(pic_path, new_name))print("缩小图片尺寸")new_image.close()image = Image.open(os.path.join(pic_path, new_name))#对于图片宽度大于高度,左旋转if image.width > image.height: rotated_img = image.transpose(Image.ROTATE_90)print("左旋转")rotated_img.save(os.path.join(pic_path, new_name))           image.close()t1 = time.perf_counter()print("运行时间:{}s".format(t1 - t0))print("提取了{}张图片".format(imgcount))
def get_file_size(file_path):# 获取文件的大小(单位为字节)file_size = os.stat(file_path).st_sizereturn file_size
def dragged_files(files):fileurl = ''if len(files) > 1:# print("请拖放一个文件!")showinfo("提示","请拖放一个文件!")else:# print(files[0].decode('gbk'))fileurl = files[0].decode('gbk')# print(os.path.splitext(fileurl)[1])if fileurl != '' and os.path.splitext(fileurl)[1] == '.pdf':pdfpath = fileurlfilename0 = os.path.basename(fileurl).replace('.pdf','') + nowtime_to_str()# filename0 用于生成文件夹和文件名,为了不重复,在后面加入编码后的时间戳pic_path = f'e:\\临时文件夹\\{filename0}\\'if not os.path.exists(pic_path):os.mkdir(pic_path)m = pdf2pic(pdfpath, pic_path)pngpath = pic_pathouttxtpath = 'e:\\临时文件夹\\'+filename0+'.txt'ocr = PaddleOCR(use_angle_cls=True, lang="ch") # need to run only once to download and load model into memorylines = []for filename in os.listdir(pngpath):img_path = pngpath+filenameresult = ocr.ocr(img_path, cls=True)print(img_path)# image = Image.open(img_path).convert('RGB')if result[0] is not None:boxes = [detection[0] for line in result for detection in line] # Nested loop addedtxts = [detection[1][0] for line in result for detection in line] # Nested loop addedscores = [detection[1][1] for line in result for detection in line] # Nested loop addedfor box, txt, score in zip(boxes, txts, scores):if score > 0.7:# lines.append(txt.replace('\n',''))lines.append(txt+'\n')# lines.append('\n')with open(outtxtpath, 'w', encoding='utf-8') as f:f.writelines(line for line in lines)subprocess.run(['notepad.exe', outtxtpath], check=True)if __name__ == '__main__':rootWindow = tk.Tk()rootWindow.title("拖放PDF文件识别文字")rootWindow.geometry("300x120")windnd.hook_dropfiles(rootWindow , func=dragged_files)rootWindow.mainloop()


http://www.ppmy.cn/news/1531007.html

相关文章

Python--操作列表

1.for循环 1.1 for循环的基本语法 for variable in iterable: # 执行循环体 # 这里可以是任何有效的Python代码块这里的variable是一个变量名&#xff0c;用于在每次循环迭代时临时存储iterable中的下一个元素。 iterable是一个可迭代对象&#xff0c;比如列表&#xff08;…

OJ在线评测系统 后端 使用代理模式编写测试类 并 实现核心业务判题流程

编写测试类(代理模式) 实现示例的代码沙箱 package com.dduo.dduoj.judge.codesandbox.impl;import com.dduo.dduoj.judge.codesandbox.CodeSandbox; import com.dduo.dduoj.judge.codesandbox.model.ExecuteCodeRequest; import com.dduo.dduoj.judge.codesandbox.model.Exec…

【Java】字符串处理 —— String、StringBuffer 与 StringBuilder

由于String类是final类型的&#xff0c;所以使用String定义的字符串是一个常量&#xff0c;因此它一旦创建&#xff0c;其内容和长度是不可改变的。如果需要对一个字符串进行修改&#xff0c;则只能创建新的字符串。为了便于对字符串进行修改&#xff0c;在JDK中提供了一个Stri…

5步了解 地理处理合成孔径雷达工具集

摘要: 本文将带大家了解 ArcGIS Pro 合成孔径雷达工具集中的所有地理处理工具。有了 Image Analyst 许可证,就可以访问 Image Analyst 工具箱中的此工具集。此工具集是锦上添花,它使处理 SAR Ground Range Detect... 本文将带大家了解 ArcGIS Pro 合成孔径雷达工具集中的所有…

安装镜像烧录软件Etcher

一、下载Etcher安装包 访问官方网站&#xff1a; 打开浏览器&#xff0c;访问Etcher的官方网站https://etcher.balena.io/#download-etcher 下载安装包&#xff1a; 在官方网站找到Etcher的下载链接。 点击下载链接 二、安装Etcher 命令安装 点击下载链接会跳转至以下界面…

Vue 响应式监听 Watch 最佳实践

一. 前言 上一篇文章我们学习了 watch 的基础知识&#xff0c;了解了它的基本使用方法及注意事项&#xff0c;本篇文章我们继续了解在Vue 中 响应式监听 watch 的妙用。了解 watch 的基础使用请参考上一篇文章&#xff1a; 详解 Vue 中 Watch 的使用方法及注意事项https://bl…

《深度学习》—— ResNet 残差神经网络

文章目录 一、什么是ResNet&#xff1f;二、残差结构&#xff08;Residual Structure&#xff09;三、Batch Normalization&#xff08;BN----批归一化&#xff09; 一、什么是ResNet&#xff1f; ResNet 网络是在 2015年 由微软实验室中的何凯明等几位大神提出&#xff0c;斩获…

Ubuntu下简易安装openjdk8的命令行

1. 搜索 openjdk sudo apt search openjdk2. 在搜索结果中&#xff0c;选择带有jdk名字的进行安装 sudo apt install openjdk-8-jdk3. 安装成功 java -version