一.簡介
Tesseract-OCR支援中文識别,并且開源和提供全套的訓練工具,是快速低成本開發的首選。而Tess4J則是Tesseract在Java PC上的應用。在英文和數字識别中性能還是不錯的,但是在中文識别中,無論速度還是識别率還是較弱,建議有條件的話,針對場景進行訓練,會獲得較好結果,本文僅對目前Tess4J的用法進行介紹
二.入門教程
2.1 Tess4J官網下載下傳最新的源碼包
Tess4J官網.
Github位址:GitHub - nguyenq/tess4j: Java JNA wrapper for Tesseract OCR API
2.2 Tess4J目錄說明
- Tess4J目錄:
- dist:綜合jar,不需要配置dll
- lib:所有相關的jar包
- src:源碼包
- tessdata:訓練好的字型模型
- test:測試用例
2.3 Java Maven Demo
Pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>tess4j-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>net.sourceforge.tess4j</groupId>
<artifactId>tess4j</artifactId>
<version>5.4.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit-dep</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.3</version>
</dependency>
</dependencies>
</project>
示例1
設定引擎模式,設定識别語種,設定圖檔分割模式
package org.example;
import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) throws TesseractException {
System.out.println("Hello world!");
File file = new File("D:\\1.jpg");
ITesseract iTesseract = new Tesseract();
iTesseract.setDatapath("D:\\programs\\TessractOCR\\tessdata"); // 設定tessdata目錄
iTesseract.setLanguage("eng"); // 指定需要識别的語種
// 隻提取數字
List<String> configList = new ArrayList<>();
configList.add("digits");
iTesseract.setConfigs(configList);
iTesseract.setOcrEngineMode(1); // 設定OCR引擎模式(OEM)
iTesseract.setPageSegMode(6); // 設定圖檔分割模式(PSM)
String result = iTesseract.doOCR(file);
System.out.println(result);
}
}
- 其中模型資料就在tessdata目錄下
- tessdata下載下傳位址:traineddata,tessdata_best
示例2
對待識别圖檔進行預處理,便于識别
package org.example;
import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
import net.sourceforge.tess4j.util.ImageHelper;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
/**
* 圖檔優化
* @author 86133 2022-11-18 10:01:09
*/
public class ImgOptimize {
public static void main(String[] args) throws IOException {
// 識别圖檔的檔案(修改為自己的圖檔路徑)
String imagePath = ClassLoader.getSystemResource("tupian/9188.png").getPath();
if (imagePath.length() > 0) {
imagePath = imagePath.substring(1);
}
System.out.println("imagePath:" + imagePath);
File file = new File(imagePath);
// 圖檔轉圖檔流
BufferedImage img = ImageIO.read(file);
// 這裡對圖檔黑白處理,增強識别率.這裡先通過截圖,截取圖檔中需要識别的部分
img = ImageHelper.convertImageToGrayscale(img);
// 圖檔銳化,自己使用中影響識别率的主要因素是針式列印機字迹不連貫,是以銳化反而降低識别率
img = ImageHelper.convertImageToBinary(img);
// 圖檔放大5倍,增強識别率(很多圖檔本身無法識别,放大7倍時就可以輕易識,但是考濾到客戶電腦組態低,針式列印機列印不連貫的問題,這裡就放大7倍)
img = ImageHelper.getScaledInstance(img, img.getWidth() * 7, img.getHeight() * 7);
ITesseract instance = new Tesseract();
//設定訓練庫的位置
String path = ClassLoader.getSystemResource("tessdata").getPath();
if (path.length() > 0) {
path = path.substring(1);
}
// 列印路徑
System.out.println("tessdata:" + path);
instance.setDatapath(path);
//chi_sim :簡體中文, eng 根據需求選擇語言庫
instance.setLanguage("eng");
String result = null;
try {
long startTime = System.currentTimeMillis();
result = instance.doOCR(img);
long endTime = System.currentTimeMillis();
System.out.println("Time is:" + (endTime - startTime) + " 毫秒");
} catch (TesseractException e) {
e.printStackTrace();
}
System.out.println("result: " + result);
}
}
說明:
// 基于圖檔識别的識别率不高,一般先做圖檔的處理再進行識别。Tess4J專門提供的ImageHelper:
getScaledInstance 放大圖檔
getSubImage 截取圖檔
convertImageToBinary 轉二進制
convertImageToGrayscale 将圖像轉換為灰階
invertImageColor 反轉圖像顔色
rotateImage 旋轉影像
//圖檔轉圖檔流
BufferedImage img = ImageIO.read(file);
// 這裡對圖檔黑白處理,增強識别率.這裡先通過截圖,截取圖檔中需要識别的部分
img = ImageHelper.convertImageToGrayscale(img);
// 圖檔銳化,自己使用中影響識别率的主要因素是針式列印機字迹不連貫,是以銳化反而降低識别率
img = ImageHelper.convertImageToBinary(img);
// 圖檔放大5倍,增強識别率(很多圖檔本身無法識别,放大7倍時就可以輕易識,
// 但是考濾到客戶電腦組態低,針式列印機列印不連貫的問題,這裡就放大7倍)
img = ImageHelper.getScaledInstance(img, img.getWidth() * 7, img.getHeight() * 7);
示例3
将識别後的文本,辨別到圖檔中相應的識别位置上
package org.example;
import net.sourceforge.tess4j.*;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 圖檔文字識别,并将識别結果辨別在圖檔上
*
* @author 86133 2022-11-17 15:04:18
*/
public class ImgIdentification {
public static void main(String[] args) throws IOException {
File imageFile = new File("img/test.png");
BufferedImage bi = ImageIO.read(Files.newInputStream(imageFile.toPath()));
ITesseract instance = getInstance();
// 擷取識别的詞彙清單
List<Word> wordList = instance.getWords(bi, ITessAPI.TessPageIteratorLevel.RIL_WORD);
System.out.println("wordList: ----------------- " + wordList);
File outImageFile = new File("img/result.png");
identifyImg(bi, wordList, outImageFile);
}
/**
* 識别并辨別圖檔
*
* @param wordList
* @throws IOException
*/
private static void identifyImg(BufferedImage bi, List<Word> wordList, File outImageFile) throws IOException {
// 建立畫筆
Graphics2D pen = bi.createGraphics();
pen.setColor(Color.RED);
for (Word word : wordList) {
Rectangle rect = word.getBoundingBox();
pen.drawRect(rect.x, rect.y, rect.width, rect.height);
pen.setFont(new Font("微軟雅黑", Font.ITALIC, 18));
pen.drawString(word.getText(), rect.x, rect.y - 10);
}
ImageOutputStream ios = ImageIO.createImageOutputStream(outImageFile);
ImageIO.write(bi, "png", ios);
}
private static void createDocumentsWithResultsTest() throws Exception {
ITesseract instance = getInstance();
File imageFile = new File("img", "image.png");
BufferedImage bi = ImageIO.read(Files.newInputStream(imageFile.toPath()));
String outputbase = "target/test-classes/test-results/docrenderer1-5";
List<ITesseract.RenderedFormat> formats = new ArrayList<>(Arrays.asList(ITesseract.RenderedFormat.HOCR, ITesseract.RenderedFormat.PDF, ITesseract.RenderedFormat.TEXT));
OCRResult or = instance.createDocumentsWithResults(bi, imageFile.getPath(), outputbase, formats, ITessAPI.TessPageIteratorLevel.RIL_WORD);
System.out.println(or.getWords());
}
private static ITesseract getInstance() {
ITesseract instance = new Tesseract();
// 設定tessdata目錄, 下載下傳位址: https://github.com/tesseract-ocr/tessdata_best
instance.setDatapath("D:\\programs\\TessractOCR\\tessdata");
/**
* 設定需要識别的語種,
* chi_sim+eng: 表示識别簡體中文和英文;
* eng: 僅識别英文
*/
instance.setLanguage("chi_sim+eng");
instance.setOcrEngineMode(1); // 設定OCR引擎模式(OEM)
instance.setPageSegMode(6); // 設定圖檔分割模式(PSM)
return instance;
}
}
2.4 READ.ME
# Note
Tesseract引入訓練模型的方法
根據自己的需要下載下傳需要的模型檔案,将traineddata檔案放在
%TesseractOCR_HOME%\tessdata 目錄(Tesseract安裝目錄)下就可以了。
tessdata下載下傳位址:
https://github.com/tesseract-ocr/tessdata_best
tessdata_best可用來再訓練字庫
訓練方法參考文檔:
https://tesseract-ocr.github.io/tessdoc/tess4/TrainingTesseract-4.00.html
# 參數釋義
## 自定義配置
config = r'-l chi_sim+eng --psm 6'
# 其它OCR選項:
# --tessdata-dir PATH:Specify the location of tessdata path.
# --user-words PATH:Specify the location of user words file.
# --user-patterns PATH:Specify the location of user patterns file.
# --dpi VALUE:Specify DPI for input image.
# -l LANG[+LANG]:Specify language(s) used for OCR.
# -c VAR=VALUE:Set value for config variables. Multiple -c arguments are allowed.
# --psm NUM:Specify page segmentation mode.
# --oem NUM:Specify OCR Engine mode.
text = pytesseract.image_to_string(Image.open(r'D:\workspace\tesseract-ocr\test.jpg'), config=config)
## ImageHelper
getScaledInstance 放大圖檔
getSubImage 截取圖檔
convertImageToBinary 轉二進制
convertImageToGrayscale 将圖像轉換為灰階
invertImageColor 反轉圖像顔色
rotateImage 旋轉影像
## 圖檔分割模式(PSM)
tesseract有13種圖檔分割模式(page segmentation mode,psm):
0 – Orientation and script detection (OSD) only. 方向及語言檢測(Orientation and script detection,OSD)
1 – Automatic page segmentation with OSD. 自動圖檔分割
2 – Automatic page segmentation, but no OSD, or OCR. 自動圖檔分割,沒有OSD和OCR
3 – Fully automatic page segmentation, but no OSD. (Default) 完全的自動圖檔分割,沒有OSD
4 – Assume a single column of text of variable sizes. 假設有一列不同大小的文本
5 – Assume a single uniform block of vertically aligned text. 假設有一個垂直對齊的文本塊
6 – Assume a single uniform block of text. 假設有一個對齊的文本塊
7 – Treat the image as a single text line. 圖檔為單行文本
8 – Treat the image as a single word. 圖檔為單詞
9 – Treat the image as a single word in a circle. 圖檔為圓形的單詞
10 – Treat the image as a single character. 圖檔為單個字元
11 – Sparse text. Find as much text as possible in no particular order. 稀疏文本。查找盡可能多的文本,沒有特定的順序。
12 – Sparse text with OSD. OSD稀疏文本
13 – Raw line. Treat the image as a single text line, bypassing hacks that are Tesseract-specific. 原始行。将圖像視為單個文本行。
## OCR引擎模式(OEM)
有4種OCR引擎模式:
0 – Legacy engine only.
1 – Neural nets LSTM engine only.
2 – Legacy + LSTM engines.
3 – Default, based on what is available.
## 方向及語言檢測OSD
Tesseract支援方向及語言檢測(Orientation and script detection,OSD) ,比如檢測下面的圖檔:
![img.png](img/img.png)
### 檢測方法:
osd = pytesseract.image_to_osd('osd-example.png',config='--psm 0 -c min_characters_to_try=5')
print(osd)
### 執行結果:
Page number: 0
Orientation in degrees: 90
Rotate: 270
Orientation confidence: 0.74
Script: Han
Script confidence: 0.83