pdf有两类,一类是别人用word转pdf,你想转过来那种,带有光标那种,计算机能轻松识别,转换相对简单很多。第二类,即图片类pdf,也就是平常工作中看到的各种扫描件,它的识别相对要复杂一些,但又常常是最主要的。近期突发奇想想坚持试写一个,期间遇到许多问题 ,但好在看了许多人的一些经验总结,最后一个个问题都突破了。然后我自己还遇到一些网上找不到答案,自己琢磨解决的。所以想稍微写点东西,希望对其他朋友有所帮助。
必备工具
1、Python 建议安装3.7或以上版本(我自己安装的是3.8版本,pycharm和anaconda3)
2、tesseract-ocr 下载地址: https://github.com/UB-Mannheim/tesseract/wiki 使用最新版本即可
(如果你还想详细了解tesseract-ocr,可以登录 Python OCR工具pytesseract详解 - 墨天轮 学习)
需要用到的库主要有:
pip install pillow
pip install opencv-python
pip install fitz
pip install PyMuPDF
pip install pytesseract
大致思路
其实本质是识别jpg或者png格式的图片,至于pdf,则只是加多了一步,即把pdf文件解开为一张张jpg或者png格式,利用for循环就能实现。用os弄出要转的图片的路径,赋值给img_path_guodu,然后接下来就可以通过下面的代码实现
text = pytesseract.image_to_string(Image.open(img_path_guodu), lang='chi_sim+eng')
doc = docx.Document() # 创建一个新的word文档
doc.add_paragraph(text) # 往文档里添加识别出来的文字
doc.add_page_break() # 添加分页符,等于在word里按多了一次Ctrl+Enter
# 下面两行设置了文档字体全篇为宋体,缺一行不可
doc.styles['Normal'].font.name = u'宋体'
doc.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')
doc.save(os.getcwd() + '\\' + file_name + ".docx") # 保存文档
常见问题
一、运行后提示No module named ‘frontend‘
控制台出现下面提示:
报错有两种可能:
1、你没装PyMuPDF。解决方法:
pip install PyMuPDF
2、安装装了,但版本不对,最好装下面这个:
pip install PyMuPDF==1.19.0
你如果装的是pip install PyMuPDF==1.16.14 ,系统会提示:ERROR: pdf2docx 0.5.3 has requirement PyMuPDF>=1.19.0, but you'll have pymupdf 1.16.14 which is incompatible.
翻译:要安装更高版本的PyMuPDF才能对应pdf2docx 0.5.3。
所以我还是觉得最好直接安装pip install PyMuPDF==1.19.0
二、出现下面提示:
pytesseract.pytesseract.TesseractNotFoundError: tesseract is not installed or it’s not in your path
如下图:
解决方法:复制上面图片中选中的那个地址,去那个地址下,打开pytesseract.py文件,按照下面图这样修改:
# tesseract_cmd = 'tesseract'
tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
三、提示AttributeError: 'NoneType' object has no attribute '__array_interface__',起初我以为是安装Tesseract时没有勾选下载可供识别的语言,所以我就重新安装并且全部勾选了,但还是不行。错误提示如下图:
这里有先说说实现文字识别有两种写法,一种依赖于opencv的写法,一种不依赖opencv:
依赖opencv的如下:
img = cv.imread(img_path)
print(img)
text = pytesseract.image_to_string(Image.fromarray(img), lang='chi_sim+eng') # lang='chi_sim+eng'是识别简体中文和英文;'chi_tra'则表示繁体中文
不依赖opencv写法如下:
text=pytesseract.image_to_string(Image.open(img_path), lang='chi_sim+eng') # 这里用到的参数只有路径。
问题所在:
问题出在img = cv.imread(img_path),其中的路径不可以带有中文。
我一开始发现前面的引入模块的代码
这里,import cv2 as cv 一行呈灰色,我试着执行以下操作:
但还是无法使用依赖opencv的写法去实现文字识别。
我试着重新pip install opencv-python安装模块,也是不行。
最后我发现,问题就出在img = cv.imread(img_path)这里读取的路径、包括文件名只能带有英文数字及一些特定字符,不能带有中文、日文等字符,带有中文就没法使用cv方法,当你print(img)时,控制台也会显示None,说明此时读不出img。一旦把文件夹及需要识别的文件的文件名,全部改为英文字母时,就可以运行程序。
解决方法:
如果出现上面的错误,则可以选择用不依赖opencv的方法,便不再出现报错问题
四、文件抽出来时,放大参数设置得太大。PDF抽出图片后,在识别时,无法识别图片前面那几行字,还有最后一行或几行也没法识别,并且容易出现错误识别。
问题就出在:
PDF文件解压成一张张jpg格式后,通常文件因为太大而无法完整识别全部内容,易出现部分遗漏或错漏,这里我之前有认识误区,我以为图片越大越容易识别,其实不是的,2800像素*2800像素,就是比较好的了,超过10000像素的反而识别得很混乱。
解决方法:需要先将文件压到合适大小,把短边改为2800像素,长边根据短边做出相应等比例缩放。如此则即可以识别,同时又不至于文件太大。
认真读下面几段代码,就能理解等比例缩放图片大小的实现方式了,下面的方式,不需要用到opencv模块。cv、cv2模块,因为不能读取带有中文路径的文件,所以最好避开opencv模块,不然太局限了。
img_path = 'C:/Users/sun2020/Desktop/tpdf_docx/test266.png'
picture=Image.open(img_path)
heng,shu=picture.size
print(heng,shu)
picture = picture.resize((2800,int(2800*shu/heng)),Image.ANTIALIAS) #改变尺寸,保持图片高品质
heng1,shu1=picture.size
print(heng1,shu1)
五、当我们读取的文件太大时,有时系统提示:
raise DecompressionBombError(
PIL.Image.DecompressionBombError: Image size (217795500 pixels) exceeds limit of 178956970 pixels, could be decompression bomb DOS attack.
翻译:图像大小(217795500像素)超过178956970像素的限制
解决方法:
在你的程序刚刚开始写的位置,写入下面三行代码:
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
Image.MAX_IMAGE_PIXELS = None
以后运行便不会报错。