共计 4598 个字符,预计需要花费 12 分钟才能阅读完成。
工作:提取医案,有局部医案存在于 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 生成图片的时候的像素可能不够,导致图片不太清晰。这个问题的解决办法下一篇文章再写。