close

在前的文章《知識圖譜落地不可迴避的重頭戲:文檔版面分析關鍵技術、開放數據與開源組件概述》中,我們從知識圖譜在工業界落地中受忽視的一環、文檔版面分析關鍵技術與數據集、現有開放可用的工具模型三個方向進行了版面分析在知識圖譜構建環節中的重要性。

而進一步的,我們可以看到,目前很多pdf文檔中包含了包括圖片、表格等豐富的信息,例如,財務報表、技術報告、學術期刊和各種論文等帶有大量繪製圖表信息的文檔,經常採用PDF格式保存,PDF內容提取版時應避免圖表文字混入正文,或針對圖表數據做進一步分析處理,都需要識別圖表信息。

而完整地將表格、圖片區域進行識別,並進行分離,可以支持多種應用場景,例如研報、年報中有大量的圖片,如果進行提取,可以進行圖片定位和搜索,通過對產業鏈研報的解析,還可以為產業鏈構建提供支撐。

因此,本文主要圍繞PDF圖片提取這一任務,從PDF區域bouding box坐標識別、PDF文件向圖片轉換以及PDF文件圖片提取三個方面進行論述,供大家一起參考。

一、PDF區域bouding box坐標識別

PDF區域boudingbox是當前PDF分析的一個重要組成部分,通過給定一個pdf文檔,需要從中找到對應的區域以及其位於pdf的坐標,下面介紹幾個代表方法:

1、基於pdfminer獲取區域的bounding box

pdfminer是一個Python的PDF解析器,用於從PDF文檔中提取信息,它專注於獲取和分析文本數據。PDFMiner允許獲取某一頁中文本的準確位置和一些諸如字體、行數的信息。基於PDFminer的圖表識別提取不需要準備數據集、花費大量時間去打標訓練,也不需要高占用GPU,識別速度快,對於機器性能的要求較低,對於大多數的報告文件都具有適用性。

布局分析返回的PDF文檔中的每個頁面LTPage對象。這個對象和頁內包含的子對象,形成一個樹結構,如圖所示:

layout是一個LTPage對象 裡面存放着 這個page解析出的各種對象 一般包括LTTextBox, LTFigure, LTImage, LTTextBoxHorizontal等,其中:

LTPage表示整個頁。可能會含有LTTextBox,LTFigure,LTImage,LTRect,LTCurve和LTLine子對象;

LTTextBox:表示一組文本塊可能包含在一個矩形區域。此box是由幾何分析中創建,並且不一定表示該文本的一個邏輯邊界,包含LTTextLine對象的列表;

LTTextLine:包含表示單個文本行LTChar對象的列表。字符對齊要水平或垂直,取決於文本的寫入模式;

LTAnno:在文本中實際的字母表示為Unicode字符串;LTAnno對象沒有,因為這些是「虛擬」的字符,根據兩個字符間的關係(例如,一個空格)由布局分析後插入;LTImage:表示一個圖像對象。嵌入式圖像可以是JPEG或其它格式,但是目前PDFMiner沒有放置太多精力在圖形對象;LTLine:代表一條直線。可用於分離文本或附圖;LTRect:表示矩形。可用於框架的另一圖片或數字;LTCurve:表示一個通用的Bezier曲線;

#bbox:# x0:從頁面左側到框左邊緣的距離。# y0:從頁面底部到框的下邊緣的距離。# x1:從頁面左側到方框右邊緣的距離。# y1:從頁面底部到框的上邊緣的距離frompdfminer.pdfparserimportPDFParserfrompdfminer.pdfdocumentimportPDFDocumentfrompdfminer.pdfpageimportPDFPagefrompdfminer.pdfinterpimportPDFResourceManager,PDFPageInterpreterfrompdfminer.pdfpageimportPDFTextExtractionNotAllowedfrompdfminer.converterimportPDFPageAggregatorfrompdfminer.layoutimportLTTextBoxHorizontal,LAParams,LTImage,LTFigure,LTLine,LTRectfrompdfminer.pdfinterpimportPDFResourceManager,PDFPageInterpreterdefparse(pdf_path):fp=open(pdf_path,'rb')#以二進制讀模式打開parser=PDFParser(fp)doc=PDFDocument(parser)ifnotdoc.is_extractable:raisePDFTextExtractionNotAllowedelse:#創建PDf資源管理器來管理共享資源rsrcmgr=PDFResourceManager()#創建一個PDF設備對象laparams=LAParams()device=PDFPageAggregator(rsrcmgr,laparams=laparams)#創建一個PDF解釋器對象interpreter=PDFPageInterpreter(rsrcmgr,device)#循環遍歷列表,每次處理一個page的內容fori,pageinenumerate(PDFPage.create_pages(doc)):datas=[]interpreter.process_page(page)#接受該頁面的LTPage對象layout=device.get_result()#這裡layout是一個LTPage對象裡面存放着這個page解析出的各種對象一般包括LTTextBox,LTFigure,LTImage,LTTextBoxHorizontal等等想要獲取文本就獲得對象的text屬性,forxinlayout:data={"page_idx":i,"label":str(type(x)),"pos":list(x.bbox)}print(data)

2、基於pp structure獲取區域的bounding box

pp structure給出了一個版面分析方法下的bounding box坐標提取方法,通過publayout版面分析,可以得到各個區域的坐標信息。

項目地址:https://github.com/PaddlePaddle/PaddleOCR/

importosimportcv2frompaddleocrimportPPStructure,draw_structure_result,save_structure_restable_engine=PPStructure(show_log=True,image_orientation=True)save_folder='./output'img_path='ppstructure/docs/table/1.png'img=cv2.imread(img_path)result=table_engine(img)save_structure_res(result,save_folder,os.path.basename(img_path).split('.')[0])三、PDF文件向圖片轉換

PDF轉換為圖片,是我們進行版面分析的一個重要前置性步驟,給定一個PDF文件,需要根據每一頁,將PDF進行切割,並轉換為一定清晰度的圖片集合。

目前,支持這一處理的包括pdfplumber以及pyMuPDF等,下面對實踐腳本進行介紹。

1、基於pdfplumber進行圖片轉換

地址:https://github.com/jsvine/pdfplumber

importpdfplumberdefpdf2img(pdf_path,img_dir):pdf=pdfplumber.open(pdf_path)fori,pageinenumerate(pdf.pages):first_page=pdf.pages[i]##resolution用於控制圖片轉換後的清晰度,值越大,得到的文件越清晰im=first_page.to_image(resolution=200)im.save('%s/%s.jpg'%(img_dir,i))pdf.close()return

2、基於pyMuPDF進行圖片轉換

地址:https://github.com/pymupdf/PyMuPDF

importfitz#fitz就是pipinstallPyMuPDFdefpdf2img(pdf_path,image_dir):pdfDoc=fitz.open(pdf_path)forpginrange(pdfDoc.pageCount):page=pdfDoc[pg]rotate=int(0)#每個尺寸的縮放係數為4,這將為我們生成分辨率提高4的圖像。#此處若是不做設置,默認圖片大小為:792X612, dpi=96zoom_x=4#(1.33333333-->1056x816)(2-->1584x1224)zoom_y=4mat=fitz.Matrix(zoom_x,zoom_y).preRotate(rotate)pix=page.getPixmap(matrix=mat,alpha=False)ifnotos.path.exists(image_path):#判斷存放圖片的文件夾是否存在os.makedirs(image_path)#若圖片文件夾不存在就創建pix.writePNG(image_path+'/'+'images_%s.png'%pg)#將圖片寫入指定的文件夾內三、PDF文件圖片提取

與將PDF切割為圖片不同,PDF文件圖片提取旨在將PDF中所包含的圖片進行分離,這種任務主要分成兩種情況,一種是圖片型的pdf,無法直接解析pdf文件本身,而是需要進行版式分析,如使用paddlpadlle ocr進行提取。另一種是非圖片型pdf,可以通過解析pdf的內部元素構成來完成提取,如基於pyMuPDF、pdf2image等。

1、基於pyMuPDF進行圖片提取

地址:https://github.com/pymupdf/PyMuPDF

importfitzimportreimportosdefsave_pdf_img(pdf_path,save_path):#使用正則表達式來查找圖片checkXO=r"/Type(?=*/XObject)"checkIM=r"/Subtype(?=*/Image)"#打開pdfdoc=fitz.open(pdf_path)#圖片計數imgcount=0#獲取對象數量長度lenXREF=doc.xref_length()#遍歷每一個圖片對象foriinrange(1,lenXREF):text=doc.xref_object(i)isXObject=re.search(checkXO,text)#使用正則表達式查看是否是圖片isImage=re.search(checkIM,text)#如果不是對象也不是圖片,則continueifnotisXObjectornotisImage:continueimgcount+=1#根據索引生成圖像pix=fitz.Pixmap(doc,i)#根據pdf的路徑生成圖片的名稱new_name=path.replace('\\','_')+"_img{}.png".format(imgcount)new_name=new_name.replace(':','')#如果pix.n<5,可以直接存為PNGifpix.n<5:pix.writePNG(os.path.join(save_path,new_name))#否則先轉換CMYKelse:pix0=fitz.Pixmap(fitz.csRGB,pix)pix0.writePNG(os.path.join(save_path,new_name))pix0=None#釋放資源pix=None

2、基於pdf2image進行圖片提取

地址:https://github.com/Belval/pdf2image

frompdf2imageimportconvert_from_pathpdf_path="test.pdf"save_path="./imagefolder"convert_from_path(pdf_path=pdf_path,#要轉換的pdf的路徑dpi=200,#dpi中的圖像質量(默認200)output_folder=save_path,#將生成的圖像寫入文件夾(而不是直接寫入內存)#注意中文名的目錄可能會出問題first_page=None,#要處理的第一頁last_page=None,#停止前要處理的最後一頁fmt="png",#輸出圖像格式jpegopt=None,#jpeg選項「quality」、「progressive」和「optimize」(僅適用於jpeg格式)thread_count=4,#允許生成多少線程進行處理userpw=None,#PDF密碼use_cropbox=False,#使用cropbox而不是mediaboxstrict=False,#當拋出語法錯誤時,它將作為異常引發transparent=False,#以透明背景而不是白色背景輸出。single_file=False,#使用pdftoppm/pdftocairo中的-singlefile選項poppler_path=None,#查找poppler二進制文件的路徑grayscale=False,#輸出灰度圖像size=None,#結果圖像的大小,使用枕頭(寬度、高度)標準paths_only=False,#不加載圖像,而是返迴路徑(需要output_文件夾)use_pdftocairo=False,#用pdftocairo而不是pdftoppm,可能有助於提高性能timeout=None,#超時)

3、基於pdfminer.six提取圖片

地址:https://pdfminersix.readthedocs.io/en/latest/howto/images.html

pipinstallpdfminer.sixpdf2txt.pyxxxx.pdf--output-dirsave_path

4、基於paddleocr的圖片提取

地址:https://aistudio.baidu.com/aistudio/projectdetail/2274897

importdatetimeimportosimportfitzimportcv2importshutilfrompaddleocrimportPPStructure,draw_structure_result,save_structure_restable_engine=PPStructure(show_log=True)save_folder='./result'//圖片保存地址img_dir='./imgs'//pdf轉換為img圖片的地址files=os.listdir(img_dir)forfiinfiles:fi_d=os.path.join(img_dir,fi)#print(fi_d)forimginos.listdir(fi_d):img_path=os.path.join(fi_d,img)img=cv2.imread(img_path)result=table_engine(img)#保存在每張圖片對應的子目錄下save_structure_res(result,os.path.join(save_folder,fi),os.path.basename(img_path).split('.')[0])總結

完整地將表格、圖片區域進行識別,並進行分離,可以支持多種應用場景,例如研報、年報中有大量的圖片,如果進行提取,可以進行圖片定位和搜索,通過對產業鏈研報的解析,還可以為產業鏈構建提供支撐。

因此,本文主要圍繞PDF圖片提取這一任務,從PDF區域bouding box坐標識別、PDF文件向圖片轉換以及PDF文件圖片提取三個方面進行論述,並給出了一些開源的識別腳本和組件,感興趣的可以多多關注,最後感謝開源工作者的無私奉獻。

參考文獻

1、https://huggingface.co/bert-base-uncased2、https://aistudio.baidu.com/aistudio/projectdetail/2274897


進技術交流群請添加AINLP小助手微信(id:ainlp2)

請備註具體方向+所用到的相關技術點

關於AINLP

AINLP 是一個有趣有AI的自然語言處理社區,專注於 AI、NLP、機器學習、深度學習、推薦算法等相關技術的分享,主題包括文本摘要、智能問答、聊天機器人、機器翻譯、自動生成、知識圖譜、預訓練模型、推薦系統、計算廣告、招聘信息、求職經驗分享等,歡迎關注!加技術交流群請添加AINLP小助手微信(id:ainlp2),備註工作/研究方向+加群目的。

閱讀至此了,分享、點讚、在看三選一吧🙏


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 鑽石舞台 的頭像
    鑽石舞台

    鑽石舞台

    鑽石舞台 發表在 痞客邦 留言(0) 人氣()