用於pdf翻譯的PdfTranlate(總結篇)

  項目地址:https://gitee.com/Shanyalin/pdf-tranlate。

  先說一聲抱歉,工作原因無法將所有代碼開源,但是到目前所有的處理思路及方案都會在本總結篇中說明。

       1.關於版面分析

       將paddleocr和docbank分別封裝成web服務分開部署,開發時兩個項目的運行環境會在某歷史版本上有衝突,因此各自用了一套虛擬環境來分開運行。web服務通過頁面圖片識別返回頁面的佈局信息。

  docbank返回的標籤有12個(相關腳本中是13個);paddleocr返回的標籤可以自定義,預訓練模型裏返回的標籤是5個,且是docbank返回標籤的子集。因此可以將兩個預訓練模型識別出的佈局信息合併處理,選擇準確度較高的識別結果,也可以對不同的標籤採用不同的閾值進行採用。例如paddleocr中list、table的識別結果可以臨時提高閾值,當然這跟實際識別需求有關。

  2.關於識別特殊字符

  特殊字符在pymupdf中通常被識別爲65533,實際上\ud800-\udfff(即55296-57343)之間的符號在mupdf中都無法識別,部分特殊符號(d800-db7f)是用兩個來表示特殊符號的。對於這些無法識別的符號,已經確認可以將指定區域轉化爲pixmap進行圖片提取。我們可以先用佔位符替換特殊符號,待翻譯完畢後對佔位符進行替換,在佔位符的位置換上圖片輸出即可,但是文本輸出與圖片輸出需要分開調用,所以需要計算排版。

  3.關於文本整合

  起初的思路是依賴mupdf在提取時以block爲單位,block內的lines及lines下的spans都是採取默認合併的思路,或者通過觀察總結規律來對block進行合併,甚至有專門的對table進行識別的方案。但實踐證明這種方案錯誤率較高。

  引入機器學習對版面進行分析後,根據要處理的文本來靈活調整閾值,儘管仍有不足,但文本整合的效果確實更好了。兩個模型預測結果的交叉對比,使得文本在提取後更容易整合。比如在確定文本是table及其他不需要處理的佈局內,可以直接將表格內容跳過;在確定兩部分文字同屬一個佈局,即可對文本進行整合。

  文本整合繞不開的文本的提取,get_text的不同參數有不同的提取結果,且會對文本的bbox產生影響,如提取過程中英文的某些字符座標出現異常,進而span、line的bbox受到影響。

  一個例子幫助理解下,字符串“span”在提取時返回的結果是:[{‘bbox’: (10,10,16,18), ’c’:’s’, ’origin’: (10,16)},{‘bbox’: (16,10,38,18), ’c’: ‘p’, ‘origin’: (16,16)},{‘bbox’: (22,10,28,18), ‘c’: ‘a’, ‘origin’: (22,16)},{‘bbox’: (28,10,34,18), ‘c’: ‘n’, ‘origin’: (28,16)}],那line的bbox是(10,10,38,18)還是(10,10,34,18)呢? (10,10,38,18),實際上我們更希望獲得的是(10,10,34,18),(10,10,38,18)可能無法用版面分析結果來進行文本的整合。

  就目前的試驗而言,對英文采用rawdict進行提取,以char爲最小單位,提取整合後以span爲基本單位進行後續的整合;對中文采用dict進行提取,以span爲基本單位進行後續整合,不必使用char重新整合;Span之後的中英文整合邏輯基本一致。

  關於rawdict、dict的結構,可查看:TextPage — PyMuPDF 1.19.3 documentation

  4.關於文本輸出

  文本輸出包括兩部分:一,排版或預排版;二,輸出。先說輸出,因爲排版或預排版是受輸出方法影響的。

  文本輸出常採用shape.insert_textbox和textwriter.fill_textbox.兩種方式。這兩個方法的源碼中都有預排版過程,且都是強耦合,區別在於fill_textbox可以獲取最後一個字符的結束位置,而insert_textbox則是返回未輸出的部分。

  另一個影響輸出的問題是字體,pymupdf中內置了不少字體,也可以通過pymupdf-font來引入更多的字體,甚至是引入自定義字體。在部分情況下一種字體很難完成整個pdf的文本輸出,尤其是數學類學科的文檔,數學符號等在常用字體中是沒有相關編碼的,直接在mupdf中輸出結果大概率是65533。因此在輸出的時候需要檢測當前字體是否可以完整輸出,如果不可以就需要對文本切分,更換輸入法。

  然後再來說說預排版。通過讀pymupdf的源碼我們可以對它預排版的思路有所瞭解。簡而言之可以理解成語文考試中寫作文,提前畫好格子,然後往裏邊排文字。不同的字號對應了同樣大小的範圍,每行寫的字數。

  如果考慮了所有輸出中出現的問題,那麼預排版是可以進行解耦的,當然這會極大得增加複雜性。在充分閱讀了源碼之後,我們可以對源碼進行擴展來適用我們的需求。提取預排版代碼用於計算文本的字體大小,擴展自動檢測文本是否需要更換字體輸出等功能。

  5.關於原樣輸出

  可以採用覆蓋的思路,儘量在原位置輸出,已證實可行,但需要提高版面分析的精度。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章