指南:在瀏覽器與 Node.js 中運行多語言 OCR)
Tesseract.js v7 實戰(zhàn)指南在瀏覽器與 Node.js 中運行多語言 OCR【免費下載鏈接】tesseract.jsPure Javascript OCR for more than 100 Languages 項目地址: https://gitcode.com/GitHub_Trending/te/tesseract.jsTesseract.js 是一個純 JavaScript 的 OCR 庫通過 WebAssembly 封裝 Tesseract OCR 引擎可在瀏覽器和 Node.js 兩個環(huán)境中從圖片中識別出近百種語言的文本。本文基于倉庫根目錄的 README.md 展開并結(jié)合 src/createWorker.js、src/index.js 等源碼梳理了安裝、Worker 生命周期、調(diào)度器并行處理、核心參數(shù)與版本升級注意事項讀完你可以獨立完成從 CDN 引入到 Node 服務(wù)集成的完整 OCR 方案。項目定位Tesseract 引擎的 JavaScript 封裝層Tesseract.js 的目標(biāo)是把獨立的 Tesseract 可以看到當(dāng)前倉庫版本為7.0.0核心依賴tesseract.js-core^7.0.0提供了 wasm 運行時其余依賴bmp-js、zlibjs、idb-keyval等分別負(fù)責(zé)圖片解碼、gzip 解壓與瀏覽器 IndexedDB 緩存。README 對項目邊界有兩條明確的“不做”聲明集成前必須了解不支持 PDF 文件如需對 PDF 做 OCR需用第三方庫先把 PDF 渲染為圖片序列不修改 Tesseract 識別模型識別精度完全取決于底層 Tesseract 引擎本身本項目不會為此做任何模型層面的增強。這兩個邊界在 docs/faq.md 中也有呼應(yīng)Tesseract.js 不編輯底層引擎引擎相關(guān)的 bug 應(yīng)到 Tesseract 主項目提出手寫體識別效果差也屬于引擎模型層面的限制沒有任何參數(shù)組合能顯著改善。安裝方式CDN、npm 與 Node.js 版本要求Tesseract.js 兼容三種接入方式script標(biāo)簽本地拷貝或 CDN、webpack 等打包器、Node.js 直接運行。CDN 引入!-- v5 -- script srchttps://cdn.jsdelivr.net/npm/tesseract.js5/dist/tesseract.min.js/script引入后全局變量Tesseract可用通過Tesseract.createWorker創(chuàng)建 worker。若使用import語法倉庫同時提供 ESM 構(gòu)建產(chǎn)物dist/tesseract.esm.min.js由 package.json 中rollup -c scripts/rollup.esm.mjs的構(gòu)建步驟生成。Node.js 引入# 最新版本 npm install tesseract.js yarn add tesseract.js # 舊版本 npm install tesseract.js3.0.3 yarn add tesseract.js3.0.3環(huán)境要求Tesseract.js v7 需要 Node.js v16 或更新版本v6 需要 Node.js v14 或更新版本。倉庫內(nèi)官方示例 examples/node/recognize.js 展示了 Node 環(huán)境下的最小用法const { createWorker } require(../..); (async () { const worker await createWorker(eng, 1, { logger: (m) console.log(m), // 輸出進度日志 }); const { data: { text } } await worker.recognize(image); console.log(text); await worker.terminate(); })();快速上手createWorker → recognize → terminate 三步模式README 給出的核心用法非常簡單import { createWorker } from tesseract.js; (async () { const worker await createWorker(eng); const ret await worker.recognize(https://tesseract.projectnaptha.com/img/eng_bw.png); console.log(ret.data.text); await worker.terminate(); })();多圖片場景的關(guān)鍵優(yōu)化識別多張圖片時應(yīng)只創(chuàng)建一個 worker對每張圖片依次調(diào)用worker.recognize最后統(tǒng)一worker.terminate()——而不是為每張圖片重復(fù)走一遍完整的創(chuàng)建/加載流程。源碼視角worker 創(chuàng)建時發(fā)生了什么從 src/createWorker.js 可以看到createWorker的完整簽名是module.exports async (langs eng, oem OEM.LSTM_ONLY, _options {}, config {}) { ... }即四個參數(shù)依次為語言默認(rèn)eng、引擎模式 OEM默認(rèn)OEM.LSTM_ONLY值為 1、自定義選項對象、初始化參數(shù)對象。其內(nèi)部實現(xiàn)是一條三階段初始化鏈見 src/createWorker.js#L239-L243loadInternal() // 1. 加載 wasm core按設(shè)備能力選 SIMD/LSTM 構(gòu)建 .then(() loadLanguageInternal(langs)) // 2. 下載并緩存語言 traineddata .then(() initializeInternal(langs, oem, config)) // 3. 初始化 Tesseract 引擎 .then(() workerResResolve(resolveObj))也就是說await createWorker(...)返回時wasm 核心、語言數(shù)據(jù)與引擎初始化已全部完成。這正是 v5 之后的破壞性變更worker.initialize與worker.loadLanguage應(yīng)從代碼中刪除舊版需要手動調(diào)用新版 worker 創(chuàng)建即預(yù)加載源碼中的load函數(shù)已僅保留一個 deprecation 警告。worker 對象最終暴露的方法集合src/createWorker.js#L224-L237為load已廢棄、writeText、readText、removeFile、FS、reinitialize、setParameters、recognize、detect、terminate。每個方法內(nèi)部都通過startJob構(gòu)造一個 job經(jīng)send投遞給獨立的 Web Worker / Worker Thread 執(zhí)行主線程只通過 Promise 拿到結(jié)果。引擎模式OEMOEM 常量定義在 src/constants/OEM.js值名稱含義0TESSERACT_ONLY僅 Legacy 引擎1LSTM_ONLY僅 LSTM 引擎默認(rèn)2TESSERACT_LSTM_COMBINED兩者結(jié)合3DEFAULT由引擎自動選擇設(shè)置非默認(rèn)語言與 OEM 的例子createWorker(chi_sim, 1)。需要特別注意源碼中的一段限制邏輯src/createWorker.js#L36默認(rèn)情況下下載的 wasm core 只支持 LSTM如果之后想用worker.reinitialize切到 Legacy 模式OEM 0/2必須在創(chuàng)建時就通過legacyCore: true、legacyLang: true確保下載了支持 Legacy 的代碼與語言數(shù)據(jù)否則會拋出Legacy model requested but code missing.。createWorker 選項詳解完整的參數(shù)說明見 docs/api.md整理如下選項說明corePath指向包含全部 4 個core 文件的目錄tesseract-core.wasm.js、tesseract-core-simd.wasm.js、tesseract-core-lstm.wasm.js、tesseract-core-simd-lstm.wasm.js。不要指向單個.js文件Tesseract.js 需要能根據(jù)設(shè)備能力自行選擇構(gòu)建版本langPathtraineddata 下載路徑末尾不要帶/workerPathworker 腳本下載路徑dataPathwasm 文件系統(tǒng)中保存 traineddata 的路徑一般不修改cachePathtraineddata 緩存路徑Node 中更常用瀏覽器中僅改變 IndexedDB 的 keycacheMethod緩存策略write默認(rèn)讀寫、readOnly、refresh、nonelegacyCore設(shè)為true確保下載的代碼同時支持 Legacy 模型legacyLang設(shè)為true確保下載的語言數(shù)據(jù)同時支持 Legacy 模型workerBlobURL是否用 Blob URL 加載 worker 腳本默認(rèn)truegzip遠端 traineddata 是否 gzip 壓縮默認(rèn)truelogger進度回調(diào)如m console.log(m)errorHandlerworker 錯誤處理函數(shù)如err console.error(err)第四參數(shù)config用于設(shè)置 Tesseract 的“init only”參數(shù)——這類參數(shù)在引擎初始化之后無法再修改如load_system_dawg、load_number_dawg、load_punc_dawg只能通過它傳入其余大部分 Tesseract 參數(shù)都可以初始化后通過worker.setParameters或recognize的 options 修改。自定義路徑的典型場景完全本地化部署見 docs/local-installation.mdconst worker await createWorker(eng, 1, { workerPath: https://cdn.jsdelivr.net/npm/tesseract.jsv5.0.0/dist/worker.min.js, langPath: https://tessdata.projectnaptha.com/4.0.0, corePath: https://cdn.jsdelivr.net/npm/tesseract.js-corev5.0.0, });recognize 與常用參數(shù)worker.recognize(image, options, output, jobId)是核心 OCR 調(diào)用docs/api.md 與 docs/examples.md 中的典型用法// 基礎(chǔ)識別 const { data: { text } } await worker.recognize(image); // 只識別圖片中的一個矩形區(qū)域 const { data: { text } } await worker.recognize(image, { rectangle: { top: 0, left: 0, width: 100, height: 100 }, });輸入格式詳見 docs/image-format.md支持 bmp、jpg、png、pbm、webp、gif非動畫數(shù)據(jù)類型上瀏覽器和 Node 均支持 base64 dataURL 字符串與 buffer瀏覽器額外支持File/Blob、img/canvas元素Node 額外支持本地圖片路徑字符串。圖片需要“格式 數(shù)據(jù)類型”同時滿足例如包含 png 的 buffer 可以包含裸像素數(shù)據(jù)的 buffer 不行。另外 API 文檔特別提示圖像分辨率越高識別效果通常越好對同一張圖先做上采樣常常能顯著提升結(jié)果。輸出格式默認(rèn)只返回text。如需其他格式通過output參數(shù)顯式開啟例如worker.recognize(image, {}, { hocr: true })完整列表text、blocksjson、hocr、tsv。這正是 v6 的破壞性變更——此前默認(rèn)返回全部輸出現(xiàn)在除text外全部默認(rèn)關(guān)閉。setParameters 常用參數(shù)參數(shù)類型默認(rèn)值說明tessedit_pageseg_modeenumPSM.SINGLE_BLOCK頁面切分模式取值見 src/constants/PSM.jstessedit_char_whiteliststring字符白名單限定結(jié)果只包含這些字符適合內(nèi)容受限的場景如純數(shù)字preserve_interword_spacesstring00或1保留詞間空格user_defined_dpistring自定義 dpi用于修復(fù)Warning: Invalid resolution 0 dpi. Using 70 instead.await worker.setParameters({ tessedit_char_whitelist: 0123456789 });注意setParameters不能修改oem——它只在初始化時確定切換必須走worker.reinitialize(langs, oem, config)。PSM 常量共 14 種取值從OSD_ONLY: 0到RAW_LINE: 13Tesseract.js 默認(rèn)使用SINGLE_BLOCK值6而 Tesseract CLI 默認(rèn)AUTO值3——這也是兩者結(jié)果可能不同的原因之一詳見 docs/faq.md。worker.detect(image)則執(zhí)行 OSD方向與文字方向檢測而非 OCR同樣要求 worker 已加載 Legacy 支持創(chuàng)建時設(shè)置legacyCore: true, legacyLang: true這一點在 src/createWorker.js#L178-L180 中有對應(yīng)的運行時檢查。調(diào)度器Scheduler并行處理多張圖片docs/workers_vs_schedulers.md 給出了兩種執(zhí)行模式直接使用單個 worker或用 scheduler 管理多個 worker 并行處理。單任務(wù)場景下 scheduler 沒有優(yōu)勢但批量任務(wù)場景下能顯著提升吞吐。示例用 4 個 worker 并行執(zhí)行 10 個識別任務(wù)。const scheduler Tesseract.createScheduler(); const workerGen async () { const worker await Tesseract.createWorker(eng); scheduler.addWorker(worker); }; const workerN 4; (async () { const resArr Array(workerN); for (let i 0; i workerN; i) { resArr[i] workerGen(); } await Promise.all(resArr); /** Add 10 recognition jobs */ const results await Promise.all(Array(10).fill(0).map(() ( scheduler.addJob(recognize, https://tesseract.projectnaptha.com/img/eng_bw.png).then((x) x.data.text) ))); await scheduler.terminate(); // 同時終止所有 worker })();Scheduler API 包括addWorker(worker)一個 worker 只應(yīng)加入一個 scheduler、addJob(action, ...payload)目前支持recognize與detect、getQueueLen()、getNumWorkers()、terminate()終止所有 worker。兩條重要的工程約束來自同一文檔加入同一 scheduler 的 worker 應(yīng)當(dāng)同構(gòu)——語言、參數(shù)一致。scheduler 分配任務(wù)給哪個 worker 是不確定的worker 之間差異會導(dǎo)致識別結(jié)果不可復(fù)現(xiàn)長駐 Node.js 服務(wù)中應(yīng)定期重建 worker/scheduler例如每 500 個任務(wù)重建一次。原因是 wasm 內(nèi)存在運行中只能擴張不能收縮一張大圖片會永久抬高 worker 的內(nèi)存水位同時 Tesseract 會隨任務(wù)不斷往內(nèi)部詞典中“學(xué)習(xí)”新詞數(shù)千個無關(guān)文檔跑完后詞典會被污染甚至混入錯別字。版本升級須知v4 / v5 / v6 的重大變更README 匯總了三個大版本的破壞性變更升級時逐條對照即可v6修復(fù)了此前版本的內(nèi)存泄漏運行時與內(nèi)存占用整體下降破壞性變更除text外的所有輸出格式默認(rèn)關(guān)閉重新啟用示例worker.recognize(image, {}, { hocr: true })blocks輸出對象的內(nèi)部結(jié)構(gòu)有小幅調(diào)整。v5默認(rèn)文件體積大幅縮小英語縮小 54%中文縮小 73%首次使用無緩存的運行時約降低 50%內(nèi)存占用顯著下降破壞性變更createWorker參數(shù)簽名改變——非默認(rèn)語言與 OEM 直接作為createWorker的實參傳入如createWorker(chi_sim, 1)worker.initialize與worker.loadLanguage應(yīng)從代碼中刪除。v4新增旋轉(zhuǎn)預(yù)處理選項含自動旋轉(zhuǎn) auto-rotate顯著提升精度可取回處理后的中間圖片旋轉(zhuǎn)、灰度、二值化版本改進并行處理scheduler支持破壞性變更createWorker變?yōu)?asyncgetPDF函數(shù)被recognize的pdf選項取代。支持語言與常見問題支持語言清單見 docs/tesseract_lang_list.md近 100 種語言多語言混合識別可用數(shù)組形式createWorker([eng, chi_tra])PDF 不支持可選方案是用 PDF.js / muPDF 等第三方庫將 PDF 渲染為圖片后再識別手寫體不支持Tesseract 模型圍繞印刷體假設(shè)構(gòu)建與 Tesseract CLI 結(jié)果不一致時依次核對參數(shù)oem/psm默認(rèn)值不同、語言數(shù)據(jù)OEM 1 默認(rèn)使用整數(shù)化后的 tessdata_best 數(shù)據(jù)與 Tesseract 引擎版本完整排查流程見 docs/faq.md框架集成報Cannot find module通常是因為打包系統(tǒng)打亂了 worker 入口位置手動設(shè)置workerPath指向本地的worker-script/node/index.jsNode或worker.min.js瀏覽器即可解決。本地開發(fā)、構(gòu)建與測試倉庫提供了完整的開發(fā)工作流README “Contributing” 一節(jié)git clone https://gitcode.com/GitHub_Trending/te/tesseract.js.git cd tesseract.js npm install npm start # 啟動開發(fā)服務(wù)器開發(fā)服務(wù)器基于 scripts/server.js啟動后在瀏覽器打開http://localhost:3000/examples/browser/basic-efficient.html即可體驗修改src目錄下的文件會自動重新構(gòu)建tesseract.min.js與worker.min.js。npm run build # 構(gòu)建靜態(tài)文件輸出到 dist 目錄 npm run lint # eslint 檢查 src npm run test # 并行啟動 dev server 并運行瀏覽器karma Nodemocha測試從 package.json 的腳本定義看build實際是rimraf dist webpack --config scripts/webpack.config.prod.js rollup -c scripts/rollup.esm.mjs即 webpack 產(chǎn)出 UMD 主包與 worker 包、rollup 產(chǎn)出 ESM 構(gòu)建test由npm-run-all并行拉起 dev server 與瀏覽器/Node 雙端測試套件測試用例位于 tests/。提交 PR 前應(yīng)確保npm run lint與npm run test全部通過??偨Y(jié)Tesseract.js 的架構(gòu)可以概括為主線程 APIcreateWorker/createScheduler/setLogging等導(dǎo)出定義見 src/index.js 獨立 worker 線程內(nèi)的 wasm 引擎 按需下載并緩存的語言數(shù)據(jù)。掌握“worker 一次創(chuàng)建、多任務(wù)復(fù)用、最后 terminate”的基本模式配合 scheduler 處理批量任務(wù)、setParameters微調(diào)識別行為、corePath/langPath完成本地化部署就能覆蓋絕大多數(shù) OCR 集成場景。項目細節(jié)可進一步參考 docs/api.md、docs/performance.md 與 examples/ 目錄下的官方示例?!久赓M下載鏈接】tesseract.jsPure Javascript OCR for more than 100 Languages 項目地址: https://gitcode.com/GitHub_Trending/te/tesseract.js創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考