工作:提取医案,有局部医案存在于pdf书中,但这些pdf是图片格式的,须要把这些内容转换成为文字内容。
思路:把pdf文件转换为单张图片汇合,而后再对单张图片进行ocr辨认,对辨认的后果文字进行拼接。
利用pypdf2模块,读取pdf,读取二进制内容,利用wand模块将其中某一页转换为图片并保留。
1 读取pdf并转换为图片
装置pypdf2包。pip install pypdf2
装置python包:wandpip install wand
wand的文档:https://docs.wand-py.org/
上代码:
import io
from wand.image import Image
from wand.color import Color
from PyPDF2 import PdfFileReader, PdfFileWriter
import json
memo = {}
# 用PyPDF2的PdfFileReader读取pdf文件
def getPdfReader(filename):
reader = memo.get(filename, None)
if reader is None:
reader = PdfFileReader(filename, strict=False)
memo[filename] = reader
return reader
# 将制订页码的pdf页面转换为图片格式
def _run_convert(filename, page, res=120):
idx = page + 1
pdfile = getPdfReader(filename)
pageObj = pdfile.getPage(page) # page是从0开始的
dst_pdf = PdfFileWriter()
dst_pdf.addPage(pageObj)
pdf_bytes = io.BytesIO()
dst_pdf.write(pdf_bytes)
pdf_bytes.seek(0)
img = Image(file=pdf_bytes, resolution=res)
img.format = 'png'
img.compression_quality = 100
img.background_color = Color("white")
img_path = '{}{}.png'.format(filename[:filename.rindex('.')], idx)
img.save(filename=img_path)
img.destroy()
执行之后会报错,短少ImageMagick。
装置ImageMagick
ImageMagick是一款收费开源的图片编辑软件。既能够通过命令行应用,也能够通过C/C++、Perl、Java、PHP、Python或Ruby调用库编程来实现。ImageMagic的次要精力集中在性能,缩小bug以及提供稳固的API和ABI上。
下载地址:https://imagemagick.org/scrip…
应用办法能够参考:https://www.cnblogs.com/Renyi…
之后,持续报错,短少另外一个软件Ghostscript。
wand.exceptions.DelegateError: FailedToExecuteCommand `"gswin64c.exe" -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 "-sDEVICE=pngalpha" -dTextAlphaBits=4 -dGraphicsAlphaBits=4 "-r120x120" -dPrinted=false "-sOutputFile=C:/Users/ADMINI~1/AppData/Local/Temp/magick-ZsQSfEM-CFt6Gr4NZ7mUFFR2UbaYvaQr%d" "-fC:/Users/ADMINI~1/AppData/Local/Temp/magick-eT1ogBLBCjx3Tm4r2jidCDxbn3jmkZw6" "-fC:/Users/ADMINI~1/AppData/Local/Temp/magick-UaYBnaqm--_f0Gm6CSzMe8LnumhQQ16A"' (ϵͳ�Ҳ���ָ�����ļ���
) @ error/delegate.c/ExternalDelegateCommand/516
阐明当初零碎没有Ghostscript软件,须要装置 Ghostscript。Ghostscript是一套建基于Adobe、PostScript及可移植文档格局(PDF)的页面描述语言等而编译成的免费软件。Ghostscript是ImageMagick的一个根底局部。
下载地址:https://ghostscript.com/relea…
能够下载Ghostscript 9.55.0 for Windows (64 bit)版本。
至此,可能生成图片了。
2 调用百度智能云辨认文字
首先须要有百度的账号,注册就不说了,有了账号之后,还须要创立“利用”。
关上https://cloud.baidu.com/produ…,抉择“产品”-》“人工智能”-》“OCR文字辨认”上面的“通用场景文字辨认”。
而后,点击下图中的“立刻应用”。
而后点击下图中的“创立利用”。
填好信息之后,就会创立好一个利用,我创立的是“医案辨认”。
在上图中额APIKey和Secret Key就是咱们接下来须要用到的。
上代码:
def ocr_baidu(filename, access_token):
# encoding:utf-8
'''
通用文字辨认
'''
request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic"
# 二进制形式关上图片文件
f = open(filename, 'rb')
img = base64.b64encode(f.read())
params = {"image": img}
# access_token = '[调用鉴权接口获取的token]'
request_url = request_url + "?access_token=" + access_token
headers = {'content-type': 'application/x-www-form-urlencoded'}
response = requests.post(request_url, data=params, headers=headers)
if response:
# print(response.json())
for words in response.json().get("words_result"):
# # print(words.get("words"))
print(words)
return response.json().get("words_result")
else:
return None
最初失去是一个list列表,外面放的是words为key的字典,如下图:
3 文字进行合并
比方外面的“编写阐明”应该是题目,第2-3个value值应该合并为一个段落。最好的办法应该是用nlp技术进行语义的辨认,这里就只简略做一下字符的判断了,不会太精确。
上代码:
def is_ChineseMarks(char):
if char == "。" or char == "?" or char == "!" or char == "“" or char == ":":
return True
else:
return False
def merge2txt(words_list, line_max_num=26, title_max_num=10):
'''
{'words': '编写阐明'}
{'words': '《伤寒论》是汉代医学家张仲景所撰《伤寒杂病论》的一部分。'}
{'words': '其理法为历代医家所遵循,其方药为古今临床所惯用,被尊为“方'}
{'words': '书之祖”,是祖国医学经典著作的重要一册。'}
1.题目:如果words对应字符串长度小于title_max_num,且没有。号完结,则示意以后为题目。
2.段落:如果最初一个字符是。句号,且长度小于line_max_num,则示意以后为段落。
:param words_list:
:param line_max_num:
:param title_max_num:
:return: 合并当前的文字内容
'''
txt = ""
for i in words_list:
words = str(i.get("words"))
if (not is_ChineseMarks(words[-1])) and len(words) <= title_max_num:
txt += " " # 8个空格
txt += words
txt += "\n"
elif is_ChineseMarks(words[-1]) and len(words) <= line_max_num:
txt += words
txt += "\n"
# txt += " " # 4个空格,示意段首
else:
if txt.endswith("\n"):
txt += " "# 4个空格,示意段首
txt += words
return txt
调用百度的ocr服务,还须要access_token,这个access_token是由后面的创立利用的API Key和Secret key来生成的。能够参考百度的文档:https://ai.baidu.com/ai-doc/R…
get_token()代码:
def get_token():
# client_id 为官网获取的AK, client_secret 为官网获取的SK
client_id = "用你的API Key"
client_secret = "用你的Secret key"
host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=' + client_id + '&client_secret=' + client_secret
response = requests.get(host)
# print(host)
# print(response.content)
if response:
access_token = response.json().get("access_token")
return access_token
上main函数:
if __name__ == "__main__":
filename = "*****.pdf"
# _run_convert(filename, 3)
access_token = get_token()
filename = "*****.png"
words_list = ocr_baidu(filename, access_token)
txt = merge2txt(words_list,26,10)
print(txt)
合并后失去的后果大略是这样的:
原图是这样的:
能够看出,其实识别率还是有些问题。这里不狐疑百度的ocr识别率,其应该是国内成果最好的几家,关键问题可能还是pdf生成图片的时候的像素可能不够,导致图片不太清晰。这个问题的解决办法下一篇文章再写。
发表回复