落地實踐:從ZIP解壓到參數(shù)調(diào)優(yōu))
簡介這是一套基于EasyOCR開發(fā)的OCR文字識別系統(tǒng)聚焦圖像文字提取與文本識別面向機器學(xué)習(xí)初學(xué)者、計算機相關(guān)課程設(shè)計學(xué)生以及需要批量處理圖片文字的開發(fā)者。壓縮包共8個文件以Python腳本、示例圖片和說明文檔為主包含初版與最終版兩套代碼、三張示例圖、依賴清單、README說明以及課程設(shè)計匯報PPT整個壓縮包僅1.83MB輕量易用。系統(tǒng)完整覆蓋圖像輸入、預(yù)處理、EasyOCR引擎識別與結(jié)果輸出流程其中預(yù)處理環(huán)節(jié)涵蓋灰度化、二值化、去噪等常用手段三張示例圖可直接運行檢驗效果依賴文件幫助快速搭建環(huán)境而初版與最終版兩套代碼的對比有利于理解代碼迭代思路。匯報PPT清晰呈現(xiàn)了開發(fā)過程和系統(tǒng)設(shè)計思路README提供了必要的使用指引。目前已有39人學(xué)習(xí)下載適合作為OCR入門實踐、課程設(shè)計或技術(shù)選型參考能快速獲得一套可運行的圖像文字識別解決方案。1. 拿到這個 OCR 項目的 zip先別急著解壓假如你手上的“基于EasyOCR的OCR文字識別系統(tǒng).zip”是從同事、網(wǎng)盤或某個開源頁面下來的它大概率不是一個單純的模型文件而是一整套可運行的工程Python依賴、識別腳本、模型目錄、配置文件甚至Dockerfile。這個系統(tǒng)要解決的核心問題很直白把圖片里的文字“摳”出來返回文本、坐標和置信度并且在你自己的機器上離線跑不依賴外部OCR服務(wù)。適合的人群也明確要快速給業(yè)務(wù)接入文字識別的后端工程師、寫自動化腳本的測試開發(fā)以及想研究OCR落地流程的學(xué)生。不過這里有個反直覺的結(jié)論這類zip項目里真正花時間的往往不是OCR模型本身而是環(huán)境對齊、模型下載和參數(shù)調(diào)優(yōu)。如果只把EasyOCR當(dāng)成“裝完就能用”你大概率會在torch版本、模型下載卡住、CPU推理慢這三個地方翻車。這篇文章就順著這個zip包從解壓到上線一步步拆開講。2. 先看清楚壓縮包里是什么EasyOCR 的識別鏈路與依賴2.1 解壓前先驗貨zip 完整性、偽加密與常見包內(nèi)結(jié)構(gòu)對于任何以zip分發(fā)的項目第一件事不是雙擊解壓而是校驗文件完整性。常見做法是先跑unzip -t EasyOCR_OCR_System.zip這條命令會逐個檢查壓縮包內(nèi)的CRC校驗值。如果輸出里出現(xiàn)“bad CRC”或“missing EOCD”一類報錯說明文件傳輸過程被截斷了直接解壓大概率會少文件。這時最省事的方案是重新下載不要嘗試“修復(fù)”。如果你在寫批量處理腳本也可以用Python檢查import zipfile with zipfile.ZipFile(EasyOCR_OCR_System.zip, r) as zf: bad_file zf.testzip() if bad_file: print(損壞文件:, bad_file) else: print(zip 校驗通過)testzip()會解壓每個成員并比對CRC返回第一個損壞的文件名結(jié)果為None則整個包無損。這個習(xí)慣能幫你省掉很多“運行時import報錯但找不到原因”的時間。另一個zip特有的坑是“偽加密”?,F(xiàn)象是解壓時提示輸入密碼但你明明沒設(shè)過密碼。原因是壓縮包的制作方用第三方工具修改了通用位標志位把普通文件標記成了加密狀態(tài)實際文件數(shù)據(jù)并沒有被加密。這種文件用7-Zip打開通常能直接預(yù)覽或解壓。如果你需要確認它是不是偽加密可以用一段短腳本檢查本地文件頭里的標志位import struct with open(EasyOCR_OCR_System.zip, rb) as f: content f.read(64) # 只需要開頭一段 # 本地文件頭固定以 PK\x03\x04 開頭 idx content.find(bPK\x03\x04) flags struct.unpack(H, content[idx6:idx8])[0] if flags 0x1: print(通用標志位第0位置1標記為加密) else: print(未標記加密)這段代碼只做診斷不用于破解任何真實加密包。遇到偽加密的zip直接用7-Zip“無密碼解壓”即可或者在Linux終端用7z x 文件.zip強制嘗試。要特別提醒偽加密只能處理“標記錯亂”的壓縮包如果文件被真正加密這種手段沒有意義。通過校驗后一個典型的EasyOCR工程包目錄結(jié)構(gòu)通常長這樣EasyOCR_OCR_System/ ├── requirements.txt ├── config.yaml ├── main.py ├── ocr_core.py ├── models/ # 本地模型文件可能為空 ├── test_images/ └── README.md有些包會把模型文件省掉運行時自動下載有些會內(nèi)置一個Flask或FastAPI服務(wù)端。拿到手之后先看README和requirements再決定是先裝環(huán)境還是先跑demo不要一上來就雙擊main.py。2.2 兩段式識別文本檢測負責(zé)找字識別負責(zé)認字EasyOCR之所以比老牌的Tesseract更容易出效果是因為它把OCR拆成了兩個獨立環(huán)節(jié)。第一段用CRAFT模型做文本檢測本質(zhì)上是一個全卷積網(wǎng)絡(luò)負責(zé)從圖像里找出“哪里是文字”輸出每個字符或單詞的包圍框以及字符間的鏈接關(guān)系。第二段是識別器把檢測出的文本區(qū)域裁剪出來送入一個基于ResNet特征提取器加序列預(yù)測的網(wǎng)絡(luò)輸出文字序列和置信度。兩個模型分開意味著你可以分別調(diào)參。檢測階段最常用的是text_threshold、low_text和link_threshold它們控制哪些像素被視為文字、哪些區(qū)域要合并成完整單詞。識別階段主要受canvas_size和mag_ratio影響這兩個參數(shù)決定輸入圖像被縮放到什么尺度直接關(guān)系到小字的識別率。簡單說檢測參數(shù)影響“能不能找到字”識別參數(shù)影響“找到的字認不認得出”。選EasyOCR做這套系統(tǒng)三個理由比較關(guān)鍵。第一是開箱即用支持簡體中文和英文混排不需要自己訓(xùn)練模型第二是返回結(jié)果帶坐標和置信度方便做后續(xù)結(jié)構(gòu)化處理第三是模型文件是標準的PyTorch格式以后可以替換成自己訓(xùn)練的識別器。反過來它也有短板PyTorch運行時體積大CPU推理速度不快首次運行要下載模型文件。如果你的場景是純內(nèi)網(wǎng)且沒有GPU這個取舍要在選型階段想清楚。在檢測模型里CRAFT比早期EAST更適合中文場景。EAST輸出的是整個文本框?qū)χ形倪@種“每個字獨立成框”的排版不友好CRAFT則先從字符級別預(yù)測“每個像素是不是字符中心”再通過鏈接關(guān)系把字符組成單詞或文本行對中文這種緊湊文字更穩(wěn)。這也是為什么EasyOCR對中文的召回率普遍好于Tesseract模板匹配路線的根本原因。2.3 模型下載是第一個黑匣子失敗時看哪里EasyOCR默認在第一次創(chuàng)建Reader時下載檢測模型和識別模型保存到當(dāng)前用戶目錄下的~/.EasyOCR/model。檢測模型負責(zé)定位文字區(qū)域識別模型負責(zé)轉(zhuǎn)成字符串兩個文件缺一不可。很多人在這一步卡住誤以為程序死循環(huán)了。我給的排查順序是先看終端輸出有沒有停在“Downloading detection model”附近然后打開~/.EasyOCR/model目錄看有沒有.pth文件。如果文件一直在下載但進度幾乎不動說明網(wǎng)絡(luò)連接不穩(wěn)定。常見做法是找一臺能正常訪問外網(wǎng)的機器把模型文件下載下來傳到這個目錄文件名必須和日志里打印的URL末尾一致因為EasyOCR是按文件名加載的。還有一個很容易忽略的位置Windows下用戶目錄可能是C:\Users\你的名字\.EasyOCR如果在Docker容器里跑HOME變量可能被改動模型會下載到別的地方。我一般會在腳本開頭打印reader.model_dir來確認實際路徑避免“文件明明放了結(jié)果加載的還是舊模型”這種詭異問題。如果你拿到的zip包里有models目錄注意看里面是不是已經(jīng)被作者放好了模型文件。如果是直接把文件復(fù)制到~/.EasyOCR/model再啟動程序就會跳過下載。復(fù)制時留意版本EasyOCR在不同版本里的模型結(jié)構(gòu)不完全兼容最好和requirements.txt里鎖定的EasyOCR版本配套使用否則運行時可能報state_dict不匹配。3. 跑通最小識別系統(tǒng)環(huán)境、命令與第一段 Python3.1 環(huán)境安裝先把 torch 和 easyocr 的版本鎖住EasyOCR依賴PyTorch而PyTorch的安裝方式?jīng)Q定了你是在用GPU還是CPU。最容易踩的坑是直接pip install easyocr它會把一套默認的PyTorch拖進來這個版本很可能和你的CUDA對不上導(dǎo)致滿心期待用GPU實際跑的一直是CPU性能差一個量級。穩(wěn)妥的順序是先建虛擬環(huán)境再裝PyTorch最后裝EasyOCR。python -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install easyocr這里用了PyTorch官方CUDA 11.8的wheel源確保安裝的torch帶GPU支持。如果你沒有NVIDIA顯卡或者只想在CPU上跑第二行換成pip install torch torchvision即可不要加--index-url參數(shù)。安裝完成后用一段最小代碼驗證環(huán)境import torch import easyocr print(CUDA available:, torch.cuda.is_available()) reader easyocr.Reader([ch_sim, en], gputorch.cuda.is_available()) print(EasyOCR ready)邏輯說明torch.cuda.is_available()返回True才說明當(dāng)前torch能調(diào)用顯卡如果返回False但機器明顯有GPU多半是torch裝成了CPU版或者顯卡驅(qū)動與CUDA版本不匹配。這時先用nvidia-smi查看驅(qū)動版本再回到PyTorch官網(wǎng)對照whl列表重裝。這里也建議把依賴導(dǎo)出到requirements.txt鎖定版本避免隔幾個月后EasyOCR升級導(dǎo)致行為變化??梢赃@樣固定pip freeze | grep -iE easyocr|torch|torchvision requirements.txt3.2 命令行快速識別一條命令看全貌EasyOCR自帶命令行工具適合先拿一張測試圖跑通全流程確認模型文件和參數(shù)沒問題。假設(shè)你的zip包里有test_images/contract.jpg可以這樣跑easyocr -l ch_sim en -f test_images/contract.jpg --detail1 --gpuTrue-l指定語言ch_sim是簡體中文en是英文--detail1表示輸出文本框坐標和置信度--gpuTrue使用GPU。第一次運行會下載模型需要一點時間后面再跑就很快。終端輸出是一個Python列表大致是這個結(jié)構(gòu)[[([[x1, y1], [x2, y2], [x3, y3], [x4, y4]], 合同編號, 0.93), ...]]坐標順序是“左上、右上、右下、左下”中間是識別文本最后是置信度。如果圖上文字很多終端會被刷屏建議重定向到文件easyocr -l ch_sim en -f test_images/contract.jpg --detail1 --gpuTrue result.txt命令行適合快速驗證但正式接業(yè)務(wù)時還是推薦用Python API因為你可以拿到結(jié)構(gòu)化結(jié)果并做后續(xù)清理、映射和入庫。3.3 Python 調(diào)用的最小腳本把坐標、文本和置信度一起拿回來把命令行的邏輯搬到Python里核心代碼只有幾行import json import easyocr reader easyocr.Reader([ch_sim, en], gpuTrue) # Reader 只創(chuàng)建一次 result reader.readtext( test_images/contract.jpg, detail1, paragraphTrue, ) output [] for box, text, confidence in result: # box 是四個坐標點組成的 numpy 數(shù)組 box_list box.tolist() output.append({ box: box_list, text: text, confidence: round(float(confidence), 4), }) print(json.dumps(output, ensure_asciiFalse, indent2))邏輯說明Reader對象的創(chuàng)建是一次性的內(nèi)部包含檢測和識別兩個模型不要在每個請求里重復(fù)創(chuàng)建。readtext()返回三元組四邊形坐標、識別文本、置信度。paragraphTrue會把相鄰文本框按語義合并成段落減少碎片化輸出。坐標默認是numpy數(shù)組直接json序列化會報錯所以先用tolist()轉(zhuǎn)成普通列表。這里的參數(shù)說明detail1保持輸出坐標和置信度如果只想要純文本設(shè)置detail0但這樣一般不建議因為丟了坐標就很難做模板匹配和版面分析。paragraphTrue在合同、掃描件這類密集文本場景很有用但同時也可能把不該合并的相鄰區(qū)域拼在一起需要根據(jù)結(jié)果取舍。3.4 建立性能基線一張圖到底該跑多久很多人拿到系統(tǒng)后都會問“為什么這么慢”。這里給一個粗略基線一張1080P的照片在NVIDIA GTX 1660上大約需要1到2秒純CPU跑需要10到30秒如果是A4掃描件因為輸入分辨率更高時間還要翻倍。這個數(shù)據(jù)可以幫助你判斷問題是否出在環(huán)境上。要精確測量單張耗時用time.perf_counter()包住readtext調(diào)用import time import easyocr reader easyocr.Reader([ch_sim, en], gpuTrue) start time.perf_counter() result reader.readtext(test_images/contract.jpg) elapsed time.perf_counter() - start print(felapsed: {elapsed:.2f}s, boxes: {len(result)})如果速度不達標優(yōu)先縮短canvas_size。這個參數(shù)控制檢測階段輸入圖像的長邊默認值比較大適合小字密集的圖片。在性能測試時可以在readtext()里顯式傳入canvas_size512和mag_ratio1.0對比默認值下的識別結(jié)果。數(shù)值越小、計算量越小但也可能漏掉小字。我一般先跑512和2048兩個值用肉眼對比識別文本再決定生產(chǎn)環(huán)境用哪個。4. 從“能識別”到“識別得準”參數(shù)、豎排與結(jié)構(gòu)化4.1 三個最值得調(diào)的識別參數(shù)當(dāng)測試圖出現(xiàn)大量漏檢或誤檢時問題基本出在檢測階段的三個閾值上。它們的作用如下參數(shù)默認值作用推薦調(diào)整方向text_threshold0.7判定一個區(qū)域是否算文字的最低置信度漏檢時降到0.5誤檢時升到0.8low_text0.4低置信度文本候選區(qū)域的閾值模糊文字降到0.2link_threshold0.4字符之間是否合并成單詞的閾值文字框碎成多段時降到0.3mag_ratio1.0圖像放大倍數(shù)影響小字識別小字多時設(shè)為1.5到2.0一個實用的調(diào)參流程是固定其他參數(shù)只改一個變量。比如漏檢率高先調(diào)text_threshold和low_text如果文字框斷成很多碎片再調(diào)link_threshold。不要同時改四個參數(shù)否則根本不知道是誰起作用。Python里這樣傳參result reader.readtext( noisy.png, text_threshold0.5, low_text0.3, link_threshold0.3, mag_ratio1.5, )邏輯說明這些閾值作用于檢測模型輸出的概率圖。text_threshold直接決定哪些像素進入后處理調(diào)低后候選框數(shù)量會變多噪聲多的圖也跟著變多l(xiāng)ow_text控制的是模型“次要預(yù)測”的取舍專門負責(zé)低對比度文字。參數(shù)之間有耦合所以每次改完都要保存帶參數(shù)的輸出圖做對比而不是憑記憶判斷。4.2 豎排與縱向文本沒有現(xiàn)成開關(guān)時的兩條路經(jīng)常有人問“EasyOCR能不能開豎排/縱向閱讀順序”這里統(tǒng)一回答EasyOCR本身沒有內(nèi)置豎排方向分類器它輸出的文本框順序遵循模型內(nèi)部的排列習(xí)慣通常是從左到右、從上到下。遇到真正的豎排文字直接讀readtext的返回結(jié)果會得到混亂順序。第一條路是讓圖像“豎排變橫排”把原始圖片旋轉(zhuǎn)90度識別完成后把坐標映射回原圖。代碼可以這樣寫import cv2 import easyocr import numpy as np img cv2.imread(vertical.png) rotated cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE) reader easyocr.Reader([ch_sim], gpuTrue) result reader.readtext(rotated) # 坐標映射旋轉(zhuǎn)90度后新坐標(x,y)對應(yīng)原圖坐標(height - y, x) for box, text, conf in result: new_box np.array(box) mapped np.zeros_like(new_box) mapped[:, 0] img.shape[0] - new_box[:, 1] mapped[:, 1] new_box[:, 0] print(mapped, text, conf)第二條路是保留原圖識別后自己排序。判斷每個文本框的寬高比如果高度大于寬度認為這一塊是豎排文本然后按左上角x坐標從大到小、y坐標從小到大排序如果文本排列是自右向左的舊書還需要額外處理閱讀順序。我一般優(yōu)先用旋轉(zhuǎn)法因為識別模型在正向橫排文本上的準確率遠高于豎排。旋轉(zhuǎn)法的問題是多了一次圖像編解碼和內(nèi)存拷貝但對多數(shù)業(yè)務(wù)來說可以忽略。如果你處理的是大量豎排古籍建議單獨訓(xùn)練一個方向分類器而不是每次旋轉(zhuǎn)整張圖。4.3 固定模板與票據(jù)裁剪 ROI 比全圖識別穩(wěn)得多很多業(yè)務(wù)是固定模板比如氣表讀數(shù)、發(fā)票、合同編號。這類圖最大的特點是背景復(fù)雜直接全圖識別會把印章、表格線、水印都當(dāng)成候選文本導(dǎo)致輸出混亂、置信度被拉低。成熟的做法是先用模板定位或顏色過濾找到ROI再對ROI單獨識別。比如一張氣表照片表盤區(qū)域基本固定可以用以下流程import cv2 import easyocr img cv2.imread(meter.jpg) # x, y, w, h 來自模板標注第一次手工標之后存到配置文件 x, y, w, h 120, 340, 500, 240 roi img[y:yh, x:xw] reader easyocr.Reader([ch_sim, en], gpuTrue) result reader.readtext(roi) # 識別坐標是ROI坐標系映射回原圖需要加偏移量 for box, text, conf in result: mapped_box [(px x, py y) for px, py in box] print(mapped_box, text, conf)這里的關(guān)鍵是把檢測限定在ROI內(nèi)既減少計算量也避免印章和水印干擾。坐標偏移是另一個容易忽略的細節(jié)識別結(jié)果里的坐標是相對ROI的要疊加(x, y)才能回到原圖坐標系。我一般會在config.yaml里維護一組模板ROI坐標換設(shè)備型號時只改配置不改代碼。如果同一張圖上要識別多個區(qū)域比如合同的甲方、乙方、金額可以用一個循環(huán)完成。每個區(qū)域的分辨率不能太小長邊至少保持在150像素以上否則識別模型很難給出穩(wěn)定結(jié)果。你可以先做一次全圖檢測用返回的坐標反推出ROI位置再保存下來這樣比手工量坐標省力。4.4 本地 EasyOCR 與云端 OCR 的邊界這一節(jié)幫你在選型時少走彎路。EasyOCR和云端OCR不是替代關(guān)系而是取舍關(guān)系。數(shù)據(jù)必須留在內(nèi)網(wǎng)、單張圖識別頻率不高、文本是標準印刷體這時EasyOCR非常合適但如果要識別手寫體、復(fù)雜表格、長文檔或者要求準召率達到99%以上商業(yè)云端API通常更穩(wěn)。成本上也要會算賬。EasyOCR免費但占用開發(fā)時間GPU服務(wù)器也要花錢云API按次計費勝在省心。很多團隊的做法是“本地先做初篩低置信度結(jié)果再送云端”這個混合策略能把成本壓到最低。我維護的一個簡單決策表是條件建議方案數(shù)據(jù)敏感必須離線本地EasyOCR配合GPU有GPU但不想管模型本地EasyOCR用默認模型單次調(diào)用量小、要穩(wěn)定云端API中文生僻字、手寫體云端API或自定義訓(xùn)練混合場景本地過濾低置信度云端兜底選型不是越強越好而是用最小的成本滿足“能接受的最差準確率”。先明確這個紅線再決定用哪條路。5. 避坑從 zip 到生產(chǎn)環(huán)境的高頻翻車記錄5.1 解壓報“invalid zip archive: could not find EOCD”現(xiàn)象用Python的zipfile讀取時報BadZipFile: File is not a zip file或者系統(tǒng)提示找不到EOCD記錄。原因文件下載不完整或者從網(wǎng)盤下載時被服務(wù)端截斷。解決先跑unzip -t或testzip()校驗如果文件確實損壞重新下載不要嘗試用修復(fù)工具救一個壞掉的zip。還有一個隱蔽情況某些壓縮軟件把真正的zip包放在了一個自解壓exe后面直接改后綴名是打不開的需要用原始方式解壓。5.2 zip 偽加密導(dǎo)致每次解壓都要密碼現(xiàn)象解壓時提示輸入密碼用空密碼也解不開但文件來源明明是公開項目。原因壓縮包作者為了防止網(wǎng)盤自動檢測或防盜鏈設(shè)置了偽加密標志把普通文件標成了加密實際數(shù)據(jù)沒有加密。解決用7-Zip打開看標記是否為偽加密如果是用7-Zip直接解壓即可多數(shù)情況下不會彈密碼框。這段提醒僅限于處理“標記錯亂”的文件不要把公開渠道下載的東西和來源不明的加密包混為一談。5.3 模型一直卡在 Downloading現(xiàn)象第一次運行EasyOCR進度條長時間不動最后報超時或ConnectionError。原因模型文件托管在境外服務(wù)器部分網(wǎng)絡(luò)環(huán)境下連接不穩(wěn)定。解決按2.3節(jié)的方法手動下載模型文件放進~/.EasyOCR/model。這里有個細節(jié)模型文件名必須和代碼日志里URL末尾的文件名完全一致大小寫錯了也不行否則程序會重新嘗試下載。5.4 GPU 環(huán)境跑出了 CPU 的速度現(xiàn)象機器有NVIDIA顯卡但識別一張圖要十幾秒。原因PyTorch被裝成了CPU版本或者CUDA版本和驅(qū)動不匹配。解決用torch.cuda.is_available()驗證如果是Anaconda環(huán)境用了默認源先卸載torch再按3.1節(jié)重新安裝。還有一種情況是顯存不足EasyOCR檢測到分配失敗后自動退回CPU這時調(diào)小canvas_size或減少并發(fā)給GPU留出空間。5.5 中文識別結(jié)果里出現(xiàn)“口”或亂碼現(xiàn)象印刷體中文能檢測到框但輸出字符串里有些字變成方塊或亂碼。原因內(nèi)置中文模型訓(xùn)練語料里沒有這個生僻字或者輸入圖像分辨率太低導(dǎo)致字形細節(jié)丟失。解決先用mag_ratio2.0放大圖像重試如果還是亂碼再考慮用自定義識別模型補齊字符集。這里不建議靠后處理做字符替換容易把正常字也改錯是給自己埋雷。6. 更進一步訓(xùn)練自己的模型并用回歸圖集鎖住質(zhì)量如果內(nèi)置模型在你們的業(yè)務(wù)數(shù)據(jù)上識別率不夠真正的解法不是反復(fù)改閾值而是訓(xùn)練一個自己的識別器。EasyOCR官方提供了訓(xùn)練工具底層是常見的序列識別方案。流程大致是先準備一批和目標字體、背景一致的訓(xùn)練圖用文本渲染工具生成帶標注的圖片然后轉(zhuǎn)成EasyOCR訓(xùn)練需要的lmdb數(shù)據(jù)庫最后修改配置文件里的字符集和模型結(jié)構(gòu)訓(xùn)練幾十個epoch。訓(xùn)練自定義模型有一個容易忽略的點數(shù)據(jù)要以“字”為單位統(tǒng)計分布不要只追求總量。很多業(yè)務(wù)場景里高頻字就幾百個把高頻字樣本備足、生僻字少量帶過效果遠好于均勻鋪開。訓(xùn)練完后得到一個.pth文件替換掉原來識別器的模型文件再把Reader里的recog_network參數(shù)指向新模型名就能在不改業(yè)務(wù)代碼的情況下切換模型。我更想多說一句驗證方法。接入任何一個OCR系統(tǒng)時我第一件事是固定一套“回歸圖集”包含不同字體、不同縮放、不同光照的測試圖20張每張標注好標準文本。每次改參數(shù)、換模型、升級依賴都在這套圖集上重新跑一遍計算兩個指標字符級準確率識別正確的字符數(shù)占總字符數(shù)比例和編輯距離預(yù)測字符串和目標字符串的差異程度。只有這兩個指標都穩(wěn)定才敢把系統(tǒng)推到線上。具體做法是寫一個腳本把readtext的結(jié)果按坐標從上到下、從左到右拼接成整段文本再用difflib和標準答案比對輸出差異行。這樣既能定位是哪種字體、哪張圖出了問題也不會在調(diào)參時憑感覺“看起來好像變好了”。這套習(xí)慣幫我避免過很多次“模型一換線上識別率掉了幾個點”的事故。OCR項目的坑大多不藏在算法里而是藏在環(huán)境、坐標映射和驗證口徑里。把這些地方守住這個基于EasyOCR的zip系統(tǒng)才能真正變成你業(yè)務(wù)里穩(wěn)定的一塊拼圖。希望幫到你。本文還有配套的精品資源點擊獲取