最近在設計一個影象識別的功能,涉及到了影象OCR
技術, 接下來就和大家分享一下前端如何低成本上手影象識別。
案例演示
首先和大家演示一下實現的效果,我們的最終目標是基於一張圖片,透過技術的手段自動提取圖片的資訊,並展示到文件中,提高文件編寫的效率。
什麼是影象OCR技術
OCR(Optical Character Recognition,光學字符識別)是指提取影象中的文字資訊,下面介紹一些常見的圖片 OCR 技術方案:
基於規則的 OCR:使用預定義的規則和模板來識別特定型別的文字,適用於結構化的文件,如表格、票據等;
基於機器學習的 OCR:透過訓練模型來識別不同字型、大小、顏色等特徵的文字,適用於非結構化的文字,如照片、手寫字等;
two-stage 方法:文字檢測+文字識別,分別由檢測網路和識別網路來完成,是目前主流的 OCR 方法,效果較好;
端到端方法:直接輸出識別後的文字,由一個大網路來完成,但該方法仍存在特徵共享、模型訓練等問題。
上面這寫技術方案的優缺點和應用場景我簡單和大家介紹如下:
基於規則的 OCR:
優點:對於特定型別的文字,如表格、票據等,識別準確率較高。
缺點:規則和模板的定義需要大量的人工工作,對於複雜的文件結構和字型變化的適應性較差。
應用場景:適用於結構化文件的識別,如表格、票據、身份證等。
基於機器學習的 OCR:
優點:可以自動學習文字的特徵,對於不同字型、大小、顏色等的適應性較好。
缺點:需要大量的訓練資料,對於生僻字和特殊字型的識別準確率可能較低。
應用場景:適用於非結構化文字的識別,如影象、照片、手寫字等。
two-stage 方法:
優點:將文字檢測和識別分開處理,提高了識別準確率和靈活性。
缺點:需要兩個網路進行處理,計算量較大,速度較慢。
應用場景:適用於對識別準確率要求較高的場景,如文件數字化、自動化表單填寫等。
端到端方法:
優點:將文字檢測和識別統一在一個網路中進行處理,減少了計算量和處理時間。
缺點:特徵共享和模型訓練等問題仍需要進一步解決,對於複雜場景的適應性較差。
應用場景:適用於對速度要求較高的場景,如實時翻譯、圖片搜尋等。
在實際應用中,我們需要根據具體需求和場景選擇合適的 OCR 技術方案。
基於影象OCR的開源方案分享
那對於前端而言,我們怎麼能使用這些 OCR 技術呢?我在做了大量研究和查詢之後,發現了幾款不錯的OCR開源專案,可以幫助我們輕鬆在自己的應用中實現OCR能力:
Tesseract:一款由 HP 實驗室開發、由 Google 維護的開源 OCR 引擎,支援多語言和多平臺。
Tesseract.js:Tesseract 的 JavaScript 版本,支援一百多種語言,可使用 npm 安裝或在頁面中直接引用 js。
PaddleOCR:飛槳首次開源的文字識別模型套件,支援中英文識別,支援傾斜、豎排等多種方向文字識別,支援 GPU、CPU 預測。
CnOCR:Python 3 下的文字識別工具包,支援簡體中文、繁體中文(部分模型)、英文和數字的常見字元識別,自帶 20 多個訓練好的識別模型,適用於不同應用場景。
chineseocr_lite:超輕量級中文 OCR,支援豎排文字識別,支援 ncnn、mnn、tnn 推理,模型大小僅 4.7M。
這些開源方案都有各自的特點和優勢,可以根據具體需求和應用場景選擇適合的方案。在使用這些開源方案時,我們仍然需要考慮以下因素:
識別精度:不同的開源方案在識別精度上可能存在差異,可以根據對識別結果準確性的要求進行選擇。
語言支援:如果需要識別特定語言的文字,需要確保所選方案支援該語言。
效能和效率:考慮方案的執行速度和資源消耗,特別是在處理大量圖片或對實時性要求較高的情況下。
可擴充套件性:如果有進一步開發和定製的需求,選擇具有良好可擴充套件性的方案。
社羣和文件:活躍的社羣和完善的文件可以提供更好的支援和幫助。
這裏我寫一個前端實現的案例,和大家分享一下具體用法。
首先我們需要安裝tesseract.js
:
yarn add tesseract.js
其次來看看我寫的一個業務程式碼:
const fileData = await req.formData(); const searchParams = req.nextUrl.searchParams; const lang = searchParams.get('lang') || 'eng'; const file: File | null = fileData.get('file') as unknown as File if (!file) { return Response.json({ success: 0 }) } const bytes = await file.arrayBuffer() const buffer = Buffer.from(bytes) const worker = await createWorker(lang, 1, { // corePath: '', workerPath: "", // 定義work路徑 langPath: "", // 定義語言包路徑 gzip: false }); const ret = await worker.recognize(buffer); // console.log(ret.data.text); await worker.terminate(); return Response.json({ data: { output: ret.data.text } })
我們在上面程式碼裡可以看到我們需要先把檔案轉化為buffer,再利用worker ,來提取影象資訊。程式碼由於我使用的是nextjs
,對nodejs
開發比較友好,當然大家也可以用其他框架來實現。
目前這個功能我已經實現到了 Nocode/WEP
文件知識庫中,大家可以體驗參考一下:
同時爲了提高識別度,我也看到一些可行的方案,這裏和大家分享一下:
資料增強:透過對影象進行旋轉、縮放、翻轉等操作,增加資料的多樣性。
最佳化訓練:調整訓練引數,如學習率、迭代次數等,以獲得更好的模型效能。
使用高質量影象:確保輸入的影象清晰、解析度高,減少噪聲和干擾。
字元分割:將影象中的字元準確分割,有助於提高識別精度。
語言模型融合:結合語言模型來提高對文字的理解和糾正錯誤。
模型融合:嘗試融合多個不同的 OCR 模型,以綜合它們的優勢。
人工標註:對一些困難樣本進行人工標註,以改進模型學習。
超引數調優:對模型的超引數進行細緻的調整和最佳化。