我做的百度飛槳PaddleOCR .NET呼叫庫

2023-02-22 18:00:47

我做的百度飛槳PaddleOCR .NET呼叫庫

.NET Conf 2021中國我做了一次《.NET玩轉計算機視覺OpenCV》的分享,其中提到了一個效果特別好的OCR識別引擎——百度飛槳PaddleOCR,可離線部署,後來我逐步把它封裝了一下,程式碼全部開源(可點選檢視原文跳轉到Github):https://github.com/sdcb/paddlesharp,可以直接安裝NuGet包使用,支援.NET Framework/.NET Core、支援Linux、支援GPU呼叫,支援14種語言模型的自動下載:

這裡有使用方法和範例程式碼:

執行效果:


促使我給PaddleOCR做.NET封裝的原因,是PaddleOCR令人驚訝的識別精度。我之前用過TesseractOCR,看到有人說是「世界上唯一」免費且好用的OCR引擎,但我發現它不好用,它的精度一直介於「可用」與「不可用」之間,處於勉強可用的狀態——即使是我使用了Best的TesseractOCR模型也是如此(而且效能也不快)。
比如你看這個例子,用TesseractOCR跑的,耗時48秒,英語和數位識別還是可圈可點的,但中文……裡面有空格不說,而且大量識別錯誤,非常不通順,詮釋了什麼叫「介於可用與不可用之間」。

但PaddleOCR不同,去看看官網範例,全部都是效果爆炸的感覺,最令人我驚訝的是它的精度,尤其是文字在旋轉的狀態下的精度:

上文中同樣的例子,在PaddleOCR中的執行結果:

可見精度好得多,耗時也只要9秒。

我是怎麼封裝的?

我發現市場上有人封裝過,但他們都是基於C++ API,然後自己寫了一層C++,然後包裝成C API進行封裝。這樣的好處是暴露出來的C API比較簡單,呼叫起來很方便,但缺點是不方便擴充套件,使用起來笨重得多,跨平臺也很難。

基於C API使用起來不方便,但上層不是有咱們.NET/C#嘛,我相信再不方便的API,只要用上了C#/.NET去封裝它,都能做得很方便地去呼叫,於是我做出了這樣的一個架構(這個架構本質是模仿了OpenCvSharp4)

  1. 最底層是C API的NuGet封裝包,這個用PInvoke來封裝C API,它的NuGet包名字是:Sdcb.PaddleInference
  2. 與底層配套的包叫native binding包,我提供了兩個,一個是基於CPU的Sdcb.PaddleInference.runtime.win64.mkl,一個是基於GPU的Sdcb.PaddleInference.runtime.win64.cuda11_cudnn8_tr7。
  3. 值得注意的是,native binding包與低層包沒有任何依賴關係。
  4. 再往上層是應用包,應用包依賴於低層的推理庫包Sdcb.PaddleInference,文字識別OCR就是Paddle推理庫Inference的一個應用,因此提供了一個Sdcb.PaddleOCR,封裝了PaddleDetector、PaddleClassificator、PaddleRecognizor以及PaddleOcrAll用來做串聯

最往上層走就是擴充套件包,我提供了一個用於幫助使用者自動下載OCR模型的Sdcb.PaddleOCR.KnownModels,注意這個擴充套件包與上述包沒有任何參照關係。

有了這些包,我做出來的這個封裝就比其它封裝更有競爭力,比如能支援GPU或者不支援GPU,比如支援Linux平臺,比如更換不同的模型,比如支援設定不同的引數——使用者甚至可以不基於我提供的應用包,自己去使用自己的邏輯封裝PaddleOCR或者其它應用。

這幾天我參與了百度飛槳的一個車牌號識別的3天訓練營,我發現可以從百度的BML平臺下載模型之後,只需簡短的改動就能將我的PaddleSharp改成支援車牌號識別:

我發現通過這些綿薄之力,能為.NET社群帶來一些方便。比如有客戶已經用上我的包,做了一個Word外掛,是付費產品,效果很不錯:

這些內容都是開源的:https://github.com/sdcb/paddlesharp,喜歡的朋友請給我一個star哦。

另外我還建立了一個QQ群,C#/.NET計算機視覺技術交流,裡面也包括有關這個PaddleSharp的使用、部署答疑和技術討論,歡迎有興趣的同行一起參與!