java中實(shí)現(xiàn)OCR文字提取的幾個(gè)常用工具(Tesseract、PaddleOCR及RapidOCR)
目前已知免費(fèi)工具:Tesseract 、PaddleOCR、EasyOCR、RapidOCR ,收費(fèi)工具:Microsoft Read API / Google Cloud Vision
以下實(shí)現(xiàn)主要針對Tesseract 、PaddleOCR、RapidOCR
| 工具 | 準(zhǔn)確度 | 速度 | 手寫識別能力 | 手寫識別能力 | 語言支持 | 數(shù)據(jù)格式 | 關(guān)鍵優(yōu)勢 | 主要局限 |
|---|---|---|---|---|---|---|---|---|
| Tesseract | ??? | ??? | 差(需微調(diào)) | 支持 | 100+ 語言 | 圖像常見格式(JPEG、PNG等)及PDF,不支持office文件 | 開源、可訓(xùn)練、跨平臺 | 中文需優(yōu)化、排版處理弱 |
| PaddleOCR | ???? | ???? | 強(qiáng)(中文手寫優(yōu)化,英文需微調(diào)) | 支持 | 中英等多語言 | 圖像常見格式(JPEG、PNG等),pdf文件需要先處理成圖片在進(jìn)行文字提前 | 中文最佳、多功能 | 依賴深度學(xué)習(xí)框架 |
| EasyOCR | ??? | ?? | 一般(英文稍好,中文差) | 不支持 | 80+ 語言 | 圖像常見格式(JPEG、PNG等),pdf文件需要先處理成圖片在進(jìn)行文字提前 | 簡單易用、支持GPU | 內(nèi)存占用高 |
| RapidOCR | ????(精簡模型,稍遜于PaddleOCR) | ???? | 強(qiáng) | 僅支持簡單手寫體 | 主流語言(中/英/日/韓等10+種) | 圖片/二進(jìn)制流(PDF需 轉(zhuǎn)換圖片再識別) | 是基于 PaddleOCR 優(yōu)化而來的輕量級OCR工具,但它針對性能、依賴體積和易用性做了大量改進(jìn)。 | 資源有限(內(nèi)存/存儲敏感場景)功能沒有PaddleOCR全面 |
以下實(shí)現(xiàn)環(huán)境基于windows本地開發(fā)
| 工具 | java中實(shí)現(xiàn)方式 |
|---|---|
| Tesseract | 1、本地安裝 Tesseract;2、需配置下載并設(shè)置訓(xùn)練數(shù)據(jù);3、maven配置依賴后可使用。 |
| PaddleOCR | 1、本地需要安裝python與PaddleOCR(pip install paddlepaddle paddleocr);2、java 端通過python腳本調(diào)用或者python中創(chuàng)建接口,java 端通過接口調(diào)用;Pdf 需要先轉(zhuǎn)換為圖片(pdf2image poppler-utils,windows需手動(dòng)安裝poppler) |
| EasyOCR | 1、本地需要安裝python與easyocr(pip install easyocr);2、java 端通過python腳本調(diào)用或者python中創(chuàng)建接口,java 端通過接口調(diào)用 |
| RapidOCR | 1、同PaddleOCR 安裝python,java 通過接口或腳本調(diào)用Python接口實(shí)現(xiàn);2、rapidORC-java(非官方) ,java中通過添加依賴使用 |
Tesseract
1、本地安裝 Tesseract OCR 引擎。原因主要是因?yàn)樗捎昧?JNI(Java Native Interface) 的方式調(diào)用本地庫,而不是純 Java 實(shí)現(xiàn)。 https://digi.bib.uni-mannheim.de/tesseract/tesseract-ocr-w64-setup-v5.3.0.20221214.exe
2、訓(xùn)練模型下載 https://github.com/tesseract-ocr/tessdata_best
3、pom配置
<!-- Tesseract OCR 主依賴 -->
<dependency>
<groupId>net.sourceforge.tess4j</groupId>
<artifactId>tess4j</artifactId>
<version>5.8.0</version> <!-- 使用最新版本 -->
<exclusions>
<!-- 排除 tess4j 自帶的舊版 JNA -->
<exclusion>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 顯式添加最新版 JNA -->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.13.0</version> <!-- 使用最新穩(wěn)定版 -->
</dependency>
<!-- 用來判斷文件實(shí)際類型 -->
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId>
<version>2.7.0</version>
</dependency>
<!-- 如果需要 PDF 支持 -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.29</version> <!-- 最新穩(wěn)定版 -->
</dependency>
4、java基本實(shí)現(xiàn)
//對傳入的文件進(jìn)行處理
public File imageCheck(MultipartFile multipartFile) {
File tempFile = null;
File reNameFile = null;
try {
// 使用UUID生成唯一字符串
String uuid = UUID.randomUUID().toString();
tempFile = new File(SAVE_PATH+multipartFile.getOriginalFilename());
multipartFile.transferTo(tempFile);
//獲取實(shí)際類型;舉例傳入圖片后綴為png但實(shí)際圖片類型為jpg,此時(shí)需要對圖片后綴更正,若不進(jìn)行更正識別時(shí)會(huì)存在異常
String mimeType = new Tika().detect(tempFile);
System.out.println(mimeType);
String[] type = mimeType.split("/");
String fileName = SAVE_PATH+uuid+"."+type[1];
reNameFile = new File(fileName);
tempFile.renameTo(reNameFile);
//openVC(fileName); //圖片預(yù)處理
} catch (Exception e) {
if (reNameFile != null) {
reNameFile.delete();
}
throw new RuntimeException("文件生成異常", e);
} finally {
if (tempFile != null) {
tempFile.delete();
}
}
return reNameFile;
}
//pdf文字提取
public String convertPdfToImage(Tesseract tesseract, File pdfFile, int dpi) {
try (PDDocument document = PDDocument.load(pdfFile)) {
List<Word> allWorld = new ArrayList<>();
for (int page = 0; page < document.getNumberOfPages(); page++) {
PDFRenderer renderer = new PDFRenderer(document);
// 渲染指定頁面為圖像,dpi參數(shù)控制圖像質(zhì)量
BufferedImage bf = renderer.renderImageWithDPI(page, dpi);
List<Word> words = tesseract.getWords(bf, ITessAPI.TessPageIteratorLevel.RIL_WORD);
allWorld.addAll(words);
}
return JSONObject.toJSONString(allWorld);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
//此處為開始,開始傳入圖片,對圖片進(jìn)行文字識別
public String ocrCore(MultipartFile multipartFile) {
Tesseract tesseract = new Tesseract();
File reNameFile = null;
String result = "";
try {
reNameFile = imageCheck(multipartFile);
tesseract.setDatapath(TEST_DATA_PATH); // 設(shè)置訓(xùn)練數(shù)據(jù)路徑
tesseract.setLanguage("chi_sim+chi_tra+eng"); // 同時(shí)識別中文和英文
BufferedImage bf = null;
if (reNameFile.getAbsolutePath().endsWith(".pdf")) {
result= convertPdfToImage(tesseract,reNameFile, 300);
} else {
bf = ImageIO.read(reNameFile);
List<Word> words = tesseract.getWords(bf, ITessAPI.TessPageIteratorLevel.RIL_WORD);
result = JSONObject.toJSONString(words);
}
//result = tesseract.doOCR(reNameFile);
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (reNameFile != null) {
reNameFile.delete();
}
}
return result;
}
PaddleOCR
1、Python 安裝
pip install paddlepaddle paddleocr
若需要識別pdf文件需要安裝以下python組件,windows需手動(dòng)安裝poppler(https://github.com/oschwartz10612/poppler-windows/releases/tag/v24.08.0-0/ 下載后bin路徑需要配置到環(huán)境變量中)
##若需要識別pdf文件需要安裝以下python組件 pip install pdf2image poppler-utils
2、Python實(shí)現(xiàn),創(chuàng)建orc接口
from flask import Flask, request, jsonify
from paddleocr import PaddleOCR
from pdf2image import convert_from_path
import numpy as np
import json
app = Flask(__name__)
ocr = PaddleOCR(use_angle_cls=True, lang="ch",use_gpu=True)
@app.route('/ocr', methods=['POST'])
def ocr_api():
img_path = request.json['image_path']
if is_pdf(img_path) :
# 將 PDF 轉(zhuǎn)換為圖像列表(每頁一張圖)
images = convert_from_path(img_path, dpi=300) # dpi 越高越清晰,但速度越慢
resp = []
# 遍歷所有頁面識別文字
for i, image in enumerate(images):
# 將 PIL.Image 轉(zhuǎn)為 numpy 數(shù)組
img_np = np.array(image)
result = ocr.ocr(img_np)
resp.append(result)
return json.dumps(resp, ensure_ascii=False)
else:
result = ocr.ocr(img_path, cls=True)
return json.dumps(result, ensure_ascii=False)
def is_pdf(file_path):
return file_path.lower().endswith('.pdf')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, threaded=False)
###多線程情況下 連續(xù)解析同一張圖片可能會(huì)存在 OpenCV/Pillow 的圖像解碼沖突,可能導(dǎo)致間歇性失敗
# pps 會(huì)對復(fù)雜文本進(jìn)行布局分析,支持識別分欄樣式文檔的識別
table_engine = PPStructure(recovery=True, use_pdf2docx_api=True)
# 處理圖片或PDF
result = table_engine(img_path)
#result = ocr.ocr(img_path, cls=True)
texts = []
for region in result:
if region['type'] in ('text', 'equation','title', 'header','figure','figure_caption'): # 只保留文本類型區(qū)域
texts.append(one_row(region['res']))
if region['type'] == 'table':
texts.append(region['res']['html'])
return json.dumps(texts, ensure_ascii=False)
3、java 實(shí)現(xiàn) 調(diào)用Python 實(shí)現(xiàn)的ORC接口
請求示例:
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\r\n \"image_path\":\"D:/Users/Administrator/Document/personal/ocr/結(jié)構(gòu)化文檔樣式/記錄紙.pdf\"\r\n}\r\n");
Request request = new Request.Builder()
.url("http://localhost:5000/ocr")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.build();
Response response = client.newCall(request).execute();
RapidOCR
1、pom文件
<!-- ocr圖片識別 -->
<dependency>
<groupId>io.github.mymonstercat</groupId>
<artifactId>rapidocr</artifactId>
<version>0.0.7</version>
</dependency>
<dependency>
<groupId>io.github.mymonstercat</groupId>
<artifactId>rapidocr-onnx-platform</artifactId>
<version>0.0.7</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.29</version> <!-- 最新穩(wěn)定版 -->
</dependency>
<!-- Linux 需要配置 -->
<dependency>
<groupId>io.github.mymonstercat</groupId>
<artifactId>rapidocr-onnx-linux-x86_64</artifactId>
<version>1.2.2</version>
</dependency>
2、java實(shí)現(xiàn)
//這里開始
public String rapidocrORC(MultipartFile multipartFile) {
File reNameFile = null;
String result = "";
try {
reNameFile = imageCheck(multipartFile);//見Tesseract 部分
InferenceEngine engine = InferenceEngine.getInstance(Model.ONNX_PPOCR_V3);
if (reNameFile.getAbsolutePath().endsWith(".pdf")) {
result = convertPdfToImage(engine, reNameFile, 300);
} else {
OcrResult ocrResult = engine.runOcr(reNameFile.getAbsolutePath());
result = JSONObject.toJSONString(ocrResult);
}
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (reNameFile != null) {
reNameFile.delete();
}
}
return result;
}
//pdf 文字提取
public String convertPdfToImage(InferenceEngine engine, File pdfFile, int dpi) {
try (PDDocument document = PDDocument.load(pdfFile)) {
List<OcrResult> allWorld = new ArrayList<>();
for (int page = 0; page < document.getNumberOfPages(); page++) {
PDFRenderer renderer = new PDFRenderer(document);
// 渲染指定頁面為圖像,dpi參數(shù)控制圖像質(zhì)量
BufferedImage bf = renderer.renderImageWithDPI(page, dpi);
String fileName = pdfFile.getAbsolutePath().replace(".pdf","_"+page+".png");
File image = new File(fileName);
try {
ImageIO.write(bf, "png", image);
OcrResult ocrResult = engine.runOcr(fileName);
allWorld.add(ocrResult);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (image != null) {
image.delete();
}
}
}
return JSONObject.toJSONString(allWorld);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
總結(jié)
到此這篇關(guān)于java中實(shí)現(xiàn)OCR文字提取的幾個(gè)常用工具的文章就介紹到這了,更多相關(guān)java實(shí)現(xiàn)OCR文字提取內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java?中?hashCode()?與?equals()?的關(guān)系(面試)
這篇文章主要介紹了Java中hashCode()與equals()的關(guān)系,ava中hashCode()和equals()的關(guān)系是面試中的??键c(diǎn),文章對hashCode與equals的關(guān)系做出詳解,需要的小伙伴可以參考一下2022-09-09
Java中的三種標(biāo)準(zhǔn)注解和四種元注解說明
這篇文章主要介紹了Java中的三種標(biāo)準(zhǔn)注解和四種元注解說明,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
Java調(diào)用外接設(shè)備詳解(制卡機(jī))
這篇文章主要為大家詳細(xì)介紹了Java調(diào)用外接設(shè)備的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07
Java POI實(shí)現(xiàn)Excel導(dǎo)入導(dǎo)出通用方法與樣式處理
Apache POI庫是Java領(lǐng)域處理Microsoft Office文件的關(guān)鍵工具,該項(xiàng)目使用POI 3.17版本實(shí)現(xiàn)Excel文件的讀寫功能,本文介紹Excel導(dǎo)入導(dǎo)出的步驟以及如何添加和維護(hù)樣式,包括字體、顏色、邊框和對齊等,需要的朋友可以參考下2025-08-08
Java char[]數(shù)組轉(zhuǎn)成String類型詳細(xì)介紹
這篇文章詳細(xì)介紹了Java char[]數(shù)組轉(zhuǎn)成String類型(char to String)的方法,文章中有詳細(xì)的代碼示例,需要的朋友可以參考閱讀2023-04-04
SpringBoot實(shí)現(xiàn)無感刷新Token的項(xiàng)目實(shí)踐
token刷新是前端安全中必要的一部分,本文就來介紹一下SpringBoot實(shí)現(xiàn)無感刷新Token的項(xiàng)目實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03
springboot Actuator的指標(biāo)監(jiān)控可視化功能詳解
SpringBoot Actuator是springboot為簡化我們對微服務(wù)項(xiàng)目的監(jiān)控功能抽取出來的模塊,使得我們每個(gè)微服務(wù)快速引用即可獲得生產(chǎn)界別的應(yīng)用監(jiān)控、審計(jì)等功能。這篇文章主要介紹了springboot Actuator的指標(biāo)監(jiān)控可視化,需要的朋友可以參考下2021-08-08

