任务:提取病历。一些医疗记录存在于 pdf 书籍中,但这些 PDF 是图片格式。这些内容需要转换成文本内容。

思路:将pdf文件转换成单张图片集,然后ocr识别单张图片,拼接识别出来的文字。

使用pypdf2模块读取pdf和二进制内容,使用wand模块将页面转换为图片并保存。

1 阅读pdf并转换成图片

安装 pypdf2 包。

点安装 pypdf2

安装python包:wand

点安装魔杖

魔杖的文件:https://docs.wand-py.org/

上码:

导入 io

从 wand.image 导入图像

从 wand.color 导入颜色

从 PyPDF2 导入 PdfFileReader、PdfFileWriter

导入 json

备忘录 u003d {}

使用 PyPDF2 的 PdfFileReader 读取 pdf 文件

def getPdfReader(文件名):

阅读器 u003d memo.get(文件名,无)

如果读者是无:

阅读器 u003d PdfFileReader(文件名,严格 u003d 假)

备忘录[文件名] u003d 阅读器

返回读者

将带页码的pdf页面转换成图片格式

def _run_convert(文件名,页面,resu003d120):

idx u003d 页 + 1

pdfile u003d getPdfReader(文件名)

pageObj u003d pdfile.getPage(page) # 页面从 0 开始

dst_pdf u003d PdfFileWriter()

dst_pdf.addPage(pageObj)

pdf_bytes u003d io.BytesIO()

dst_pdf.write(pdf_bytes)

pdf_bytes.seek(0)

img u003d 图片(文件u003dpdf_bytes,分辨率u003dres)

img.format u003d 'png'

图像.压缩\质量 u003d 100

img.background_color u003d 颜色(“白色”)

img_path u003d '{}{}.png'.format(文件名[:filename.rindex('.')], idx)

img.save(文件名u003dimg_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 -dMaxBitmapu003d500000000 -dAlignToPixelsu003d0 -dGridFitTTu003d2 "-sDEVICEu003dpngalpha" -dTextAlphaBitsu003d4 - dGraphicsAlphaBitsu003d4 "-r120x120" -dPrintedu003dfalse "-sOutputFileu003dC:/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...

您可以下载适用于 Windows(64 位)的 Ghostscript 9.55.0。

至此,图片就可以生成了。

2调用百度智能云识别文字

首先,你需要有一个百度账号才能注册。拥有帐户后,您还需要创建一个“应用程序”。

打开https://cloud.baidu.com/produ...,在“产品”-“人工智能”-“OCR字符识别”下选择“通用场景字符识别”。

然后,点击下图中的“立即使用”。

然后点击下图中的“创建应用”。

填写信息后,将创建一个应用程序。我创建的是“病历识别”。

上图中,APIKey和Secret Key就是我们接下来需要用到的。

上码:

def ocr_baidu(文件名,访问权限_token):

编码:utf-8

'''

通用字符识别

'''

请求_url u003d "https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic"

以二进制方式打开图片文件

f u003d 打开(文件名,'rb')

img u003d base64.b64encode(f.read())

参数 u003d {“图像”:img}

access_token u003d '[调用认证接口获取的token]'

请求\url u003d 请求\url + "?access_tokenu003d" + access_token

标头 u003d {'content-type': 'application/x-www-form-urlencoded'}

response u003d requests.post(request_url, datau003dparams, headersu003dheaders)

如果响应:

打印(response.json())

对于 response.json().get("words_result") 中的单词:

# print(words.get("words"))

打印(字)

返回 response.json().get("words_result")

其他:

返回无

最终结果是一个列表,其中包含一个以单词为key的字典,如下图所示:

3 合并文本

比如“写作说明”应该是标题,第二个到第三个值组合成一个段落。最好的方法应该是使用nlp技术进行语义识别。在这里,我们只是做字符识别,不是很准确。

上码:

def 是_ChineseMarks(char):

如果 char u003du003d "." 或 char u003du003d "?" 或 char u003du003d "!"或 char u003du003d """ 或 char u003du003d ": ":

返回真

其他:

返回错误

def merge2txt(words_list, line_max_numu003d26, title_max_numu003d10):

'''

{'words': '准备说明'}

{'字':'<伤寒论是汉代医学家张仲景《伤寒杂病论》的一部分。'}

{'字':'其原理和方法为历代医家所遵循,其方剂为古今临床常用,尊为“方”'}

{'字':'《书始祖》,是中国医学典籍的重要一卷。'}

1.Title:如果 words 对应字符串的长度小于title_max_num,并且No.如果数字结束,则表示当前是一个title。

2.Paragraph:如果最后一个字符是。句号,且长度小于line_max_num,表示当前是一个段落。

:param words_list:

:param line_max_num:

:param 标题_max_num:

:return: 合并后的文本内容

'''

txt u003d ""

for i in words_list:

单词 u003d str(i.get("单词"))

if (not is_ChineseMarks(words[-1])) 和 len(words) <u003d title_max_num:

txt +u003d " " # 8 个空格

txt +u003d 单词

txt +u003d "\n"

elif is_ChineseMarks(words[-1]) 和 len(words) <u003d line_max_num:

txt +u003d 单词

txt +u003d "\n"

txt +u003d " " # 4个空格,表示段落的开头

其他:

如果 txt.endswith("\n"):

txt +u003d " "#4个空格,表示段落的开头

txt +u003d 单词

返回 txt

调用百度的ocr服务也需要访问_token,这个访问_token是由创建应用所使用的API Key和Secret key生成的。可以参考百度的文档:https://ai.baidu.com/ai-doc/R...

获取\token() 代码:

定义获取_token():

#client_id为官网获取的AK和client_secret为官网获取的SK

client_id u003d "使用你的 API 密钥"

client_secret u003d "使用你的密钥"

主机 u003d 'https://aip.baidubce.com/oauth/2.0/token?grant_typeu003dclient_credentials&client_idu003d' + client_id + '&client_secretu003d' + client_secret

响应 u003d requests.get(主机)

打印(主机)

打印(response.content)

如果响应:

access\token u003d response.json().get("access\token")

返回访问权限_token

上层主要功能:

如果 __name__ u003du003d "__main__":

filename u003d "G:\数据\上课;上课开始\网络编程\2018\网络\病历pdf传输文本\温病论医疗案例选编\选编伤寒论医案汇编.pdf"

_run_convert(文件名, 3)

访问\令牌 u003d 获取\令牌()

filename u003d "G:\数据\上课;上课开始\网络编程\2018\网络\病历pdf传输文本\温病论医学案例选编\医学选编伤寒论例4.png"

words_list u003d ocr_baidu(文件名,访问权限_token)

txt u003d merge2txt(words_list,26,10)

打印(txt)

合并后得到的结果如下:

原图如下:

可以看出识别率还是有一些问题的。百度的ocr识别率毋庸置疑。应该是中国最好的。关键问题可能是pdf生成图片时像素不够,导致图片不清晰。这个问题的解决方法会写在下一篇文章中。

Logo

学AI,认准AI Studio!GPU算力,限时免费领,邀请好友解锁更多惊喜福利 >>>

更多推荐