参考:Tess4J 简单使用入门_一个爱浪费时间的人的博客-CSDN博客_tess4j
Tesseract-OCR支持中文识别,并且开源和提供全套的训练工具,是快速低成本开发的首选。而Tess4J则是Tesseract在Java PC上的应用。在英文和数字识别中性能还是不错的,但是在中文识别中,无论速度还是识别率还是较弱,建议有条件的话,针对场景进行训练,会获得较好结果,本文仅对目前Tess4J的用法进行介绍
Github地址:GitHub - nguyenq/tess4j: Java JNA wrapper for Tesseract OCR API
- dist:综合jar,不需要配置dll
- lib:所有相关的jar包
- src:源码包
- tessdata:训练好的字体模型
- test:测试用例
Pom.xml
- "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.0modelVersion>
-
- <groupId>org.examplegroupId>
- <artifactId>tess4j-demoartifactId>
- <version>1.0-SNAPSHOTversion>
-
- <properties>
- <maven.compiler.source>8maven.compiler.source>
- <maven.compiler.target>8maven.compiler.target>
- <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
- properties>
-
- <dependencies>
- <dependency>
- <groupId>net.sourceforge.tess4jgroupId>
- <artifactId>tess4jartifactId>
- <version>5.4.0version>
- dependency>
-
- <dependency>
- <groupId>junitgroupId>
- <artifactId>junit-departifactId>
- <version>4.11version>
- dependency>
-
- <dependency>
- <groupId>org.slf4jgroupId>
- <artifactId>slf4j-apiartifactId>
- <version>2.0.3version>
- dependency>
- dependencies>
- project>
设置引擎模式,设置识别语种,设置图片分割模式
- 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
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);
- }
- }
对待识别图片进行预处理,便于识别
- 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);
将识别后的文本,标识到图片中相应的识别位置上
- 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
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
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
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;
- }
-
- }
- # 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