太方便了!告別復(fù)制粘貼,Python 輕松實(shí)現(xiàn) PDF 轉(zhuǎn)文本!
對(duì)很多人來說,將 PDF 轉(zhuǎn)換為可編輯的文本是個(gè)剛需,卻苦于沒有簡單方法。在本文介紹的項(xiàng)目中,來自 K1 Digital 的高級(jí)機(jī)器學(xué)習(xí)工程師 Lucas Soares,嘗試使用 OCR(光學(xué)字符識(shí)別)自動(dòng)轉(zhuǎn)錄 pdf 幻燈片,轉(zhuǎn)錄效果還不錯(cuò)。
傳統(tǒng)的講座通常伴隨著一組 pdf 幻燈片。一般來說,想要對(duì)此類講座做筆記,需要從 pdf 復(fù)制、粘貼很多內(nèi)容。
最近,來自 K1 Digital 的高級(jí)機(jī)器學(xué)習(xí)工程師 Lucas Soares 一直在嘗試通過使用 OCR(光學(xué)字符識(shí)別)自動(dòng)轉(zhuǎn)錄 pdf 幻燈片,以便直接在 markdown 文件中操作它們的內(nèi)容,從而避免手動(dòng)復(fù)制和粘貼 pdf 內(nèi)容,實(shí)現(xiàn)這一過程的自動(dòng)化。
左為項(xiàng)目作者 Lucas Soares。
項(xiàng)目地址:https://github.com/EnkrateiaLucca/ocr_for_transcribing_pdf_slides
為什么不使用傳統(tǒng)的 pdf 轉(zhuǎn)文本工具呢?
Lucas Soares 發(fā)現(xiàn)傳統(tǒng)工具往往會(huì)帶來更多的問題,需要花時(shí)間解決。他曾經(jīng)嘗試使用傳統(tǒng)的 Python 軟件包,但是遇到了很多問題(例如必須使用復(fù)雜的正則表達(dá)式模式解析最終輸出等),因此決定嘗試使用目標(biāo)檢測和 OCR 來解決。
基本過程可分為以下步驟:
- 將 pdf 轉(zhuǎn)換為圖片;
- 檢測和識(shí)別圖像中的文本;
- 展示示例輸出。
基于深度學(xué)習(xí)的 OCR 將 pdf 轉(zhuǎn)錄為文本
將 pdf 轉(zhuǎn)換為圖像
Soares 使用的 pdf 幻燈片來自于 David Silver 的增強(qiáng)學(xué)習(xí)(參見以下 pdf 幻燈片地址)。使用「pdf2image」包將每張幻燈片轉(zhuǎn)換為 png 圖像格式。
pdf 幻燈片示例。地址:https://www.davidsilver.uk/wp-content/uploads/2020/03/intro_RL.pdf
代碼如下:
- from pdf2image import convert_from_path
- from pdf2image.exceptions import (
- PDFInfoNotInstalledError,
- PDFPageCountError,
- PDFSyntaxError
- )
- pdf_path = "path/to/file/intro_RL_Lecture1.pdf"
- images = convert_from_path(pdf_path)
- for i, image in enumerate(images):
- fname = "image" + str(i) + ".png"
- image.save(fname, "PNG")
經(jīng)過處理后,所有的 pdf 幻燈片都轉(zhuǎn)換成 png 格式的圖像:
檢測和識(shí)別圖像中的文本
為了檢測和識(shí)別 png 圖像中的文本,Soares 使用 ocr.pytorch 庫中的文本檢測器。按照說明下載模型并將模型保存在 checkpoints 文件夾中。
ocr.pytorch 庫地址:https://github.com/courao/ocr.pytorch
代碼如下:
- # adapted from this source: https://github.com/courao/ocr.pytorch
- %load_ext autoreload
- %autoreload 2
- import os
- from ocr import ocr
- import time
- import shutil
- import numpy as np
- import pathlib
- from PIL import Image
- from glob import glob
- import matplotlib.pyplot as plt
- import seaborn as sns
- sns.set()
- import pytesseract
- def single_pic_proc(image_file):
- image = np.array(Image.open(image_file).convert('RGB'))
- result, image_framed = ocr(image)
- return result,image_framed
- image_files = glob('./input_images/*.*')
- result_dir = './output_images_with_boxes/'
- # If the output folder exists we will remove it and redo it.
- if os.path.exists(result_dir):
- shutil.rmtree(result_dir)
- os.mkdir(result_dir)
- for image_file in sorted(image_files):
- result, image_framed = single_pic_proc(image_file) # detecting and recognizing the text
- filename = pathlib.Path(image_file).name
- output_file = os.path.join(result_dir, image_file.split('/')[-1])
- txt_file = os.path.join(result_dir, image_file.split('/')[-1].split('.')[0]+'.txt')
- txt_f = open(txt_file, 'w')
- Image.fromarray(image_framed).save(output_file)
- for key in result:
- txt_f.write(result[key][1]+'\n')
- txt_f.close()
設(shè)置輸入和輸出文件夾,接著遍歷所有輸入圖像(轉(zhuǎn)換后的 pdf 幻燈片),然后通過 single_pic_proc() 函數(shù)運(yùn)行 OCR 模塊中的檢測和識(shí)別模型,最后將輸出保存到輸出文件夾。
其中檢測繼承(inherit)了 Pytorch CTPN 模型,識(shí)別繼承了 Pytorch CRNN 模型,兩者都存在于 OCR 模塊中。
示例輸出
代碼如下:
- import cv2 as cv
- output_dir = pathlib.Path("./output_images_with_boxes")
- # image = cv.imread(str(np.random.choice(list(output_dir.iterdir()),1)[0]))
- image = cv.imread(f"{output_dir}/image7.png")
- size_reshaped = (int(image.shape[1]),int(image.shape[0]))
- image = cv.resize(image, size_reshaped)
- cv.imshow("image", image)
- cv.waitKey(0)
- cv.destroyAllWindows()
下圖左為原始 pdf 幻燈片,圖右為轉(zhuǎn)錄后的輸出文本,轉(zhuǎn)錄后的準(zhǔn)確率非常高。
文本識(shí)別輸出如下:
- filename = f"{output_dir}/image7.txt"
- with open(filename, "r") as text:
- for line in text.readlines():
- print(line.strip("\n"))
通過上述方法,最終你可以得到一個(gè)非常強(qiáng)大的工具來轉(zhuǎn)錄各種文檔,從檢測和識(shí)別手寫筆記到檢測和識(shí)別照片中的隨機(jī)文本。擁有自己的 OCR 工具來處理一些文本內(nèi)容,這比依賴外部軟件來轉(zhuǎn)錄文檔要好的多。