工作:提取医案,有局部医案存在于pdf书中,但这些pdf是图片格式的,须要把这些内容转换成为文字内容。
思路:把pdf文件转换为单张图片汇合,而后再对单张图片进行ocr辨认,对辨认的后果文字进行拼接。
利用pypdf2模块,读取pdf,读取二进制内容,利用wand模块将其中某一页转换为图片并保留。
1 读取pdf并转换为图片
装置pypdf2包。pip install pypdf2
装置python包:wandpip install wand
wand的文档:https://docs.wand-py.org/
上代码:
import iofrom wand.image import Imagefrom wand.color import Colorfrom PyPDF2 import PdfFileReader, PdfFileWriterimport jsonmemo = {}# 用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 Falsedef 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生成图片的时候的像素可能不够,导致图片不太清晰。这个问题的解决办法下一篇文章再写。