【Java-tesseract】OCR图片文本识别
文章目录
- 一、需求
- 二、概述
- 三、部署安装
- 四、技术细节
- 五、总结
一、需求
场景需求:是对识别常见的PNG,JPEG,TIFF,GIF图片识别,环境为离线内网。组件要求开源免费,并且可以集成Java生成接口服务。
二、概述
我不做选型对比了,我筛选测试了下Tesseract(v5.5.0)是比较符合我的需求的。其 支持多种图像格式进行光学字符识别(OCR),以下是 Tesseract 支持的主要图像格式:
- 常见图像格式:
- PNG:无损压缩格式,是最常用的图像格式之一,适用于OCR,因为它可以保留图像细节。
- JPEG(JPG):有损压缩格式,通常用于照片和复杂图像。尽管可能存在质量损失,Tesseract 依然能够处理 JPEG 格式的图像。
- TIFF:一种无损压缩格式,常用于扫描文档。TIFF 格式通常比 JPEG 更适合OCR,因为它保留了更多细节。
- BMP:位图格式,通常较大,但Tesseract也支持该格式。
- GIF:支持的图像格式,尽管在颜色精度和压缩效率方面不如 PNG 或 TIFF。
- 支持的颜色模式:
Tesseract 支持不同的颜色模式来处理图像:
- RGB:标准的三通道图像,支持彩色图像。
- Grayscale:灰度图像模式,通常用于文档图像。
- Black & White (1-bit):黑白图像,通常在扫描的文档或手写文本中使用。
- 其他支持的图像格式:
Tesseract 还支持通过某些图像处理库(如 PIL)处理的其他图像格式。通过 Python 的 pytesseract,你还可以使用一些其他图像格式,如:
- WEBP:一种新的图像格式,常用于Web图片。
- PPM/PGM:一个无损的图像格式,通常用于科学计算中。
- HEIF:高级图像文件格式(如 iPhone 图片),Tesseract 可以通过额外的库来支持。
- 图像转换和预处理:
尽管 Tesseract 支持多种格式,通常对于 OCR 的最佳效果,建议图像为高质量的灰度图像(即灰度模式)。如果原始图像格式过大或质量不高,可以考虑进行预处理,如:
- 裁剪:去除不必要的边缘区域。
- 二值化:将图像转换为黑白色调,以提高文字识别的准确性。
- 去噪:去除背景噪音,有助于提高识别效果。
- 旋转:如果文档有角度,可以对其进行旋转校正。
- 官网地址
- github:tesseract-ocr地址
- 官网文档:官网文档
- 安装包地址:软件发行版下载地址
三、部署安装
我上传了下面两个部署包,提供给无法访问github的同学使用:部署包
- windwos下载:下载安装即可
- linux部署:需要下载.tar.gz源码包编译
我这边使用ubuntu24.10容器部署编译了tesseract5.5.0,并且打包成了tar压缩包,需要的同学可以去这里下载。当然也可以自己用gcc编译。注意(该docker没有那种java等,属于一个轻量包,方便后续你进行扩展)
我上传的文件地址:tesseract.tar
- 使用方法:
#加载镜像文件
docker load -i tesseract.tar
#运行镜像
docker run -itd --name tesseract -v ./data:/data tesseract:v0
- 调用服务
若需要将tesseract提供给外部使用,需要使用java开发接口,通过http将服务暴露给外部使用。
#可以进入容器
docker exec -it tesseract /bin/bash
#执行一下命令解析图片测试,需要图片放到./data中挂载到容器的/data中,-l chi_sim是识别中文
tesseract input_image.png output_text -l chi_sim
- 整合包(重量)
相对上述2,新增了整合了java和tesseract语言包的docker镜像tesseract-java,其可以开箱即用,但是很大有1.81G,需要7Z压缩下。
整合包地址:整合包地址
1.使用教程与上述2操作一致,区别如下:
1.容器中服务端口为8080,启动时你可以将端口暴露出来
2.jar包目录:/home
3.启动命令:sh /home/start.sh start
4.docker run -itd --name tesseract -p 8080:8080 wanchen/tesseract-java:v2
# 原谅我懒,没做成服务。。大家自己实现
2.服务调用
POST:http://服务节点IP:8080/orc/transform
form-data:file
四、技术细节
- java代码调用tesseract
package com.develop.guide.service;
import lombok.extern.slf4j.Slf4j;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
@Slf4j
@Service
public class OCRService {
@Value("${ocr.path}")
// 我容器默认/usr/local/share/tessdata
private String tessDataPath;
@Value("${ocr.tempPath}")
// 文件临时存储地址
private String tempFilePath;
private final Tesseract tesseract;
public OCRService() {
// 初始化 Tesseract 对象
this.tesseract = new Tesseract();
tesseract.setDatapath(tessDataPath);
//可以选择设置 OCR 语言
this.tesseract.setLanguage("eng+chi_sim");
}
/**
* 将接口传输来的文件转换为String
* @param multipartFile
* @return
* @throws Exception
*/
@Async
public CompletableFuture<String> recognizeTextFromImage(MultipartFile multipartFile){
File file = new File(tempFilePath+multipartFile.getOriginalFilename());
String result = "";
try {
multipartFile.transferTo(file);
result = tesseract.doOCR(file);
} catch (IOException e) {
log.error("转换前端文件异常!");
throw new RuntimeException(e);
} catch (TesseractException e) {
log.error("ocr识别异常!");
throw new RuntimeException(e);
}
finally {
if (file.exists() && !file.delete()) {
log.warn("临时文件删除失败: {}", file.getAbsolutePath());
}
}
return CompletableFuture.completedFuture(result);
}
}
- pom
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.8</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>net.sourceforge.tess4j</groupId>
<artifactId>tess4j</artifactId>
<version>5.11.0</version>
</dependency>
</dependencies>
- 接口
package com.develop.guide.controller;
import com.develop.guide.service.OCRService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.util.concurrent.ExecutionException;
/**
* @author wanChen
* @ClassName ORCController
* @Description:
* @Version 1.0
*/
@RestController
@RequestMapping("/orc")
public class ORCController {
private final OCRService ocrService;
@Autowired
public ORCController(OCRService ocrService) {
this.ocrService = ocrService;
}
@PostMapping("/transform")
public String transform(@RequestParam("file") MultipartFile file) {
String result = "无法识别:"+file.getName();
try {
result = ocrService.recognizeTextFromImage(file).get();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
return result;
}
}
- 启动类
package com.develop.guide;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableAsync
public class SpringbootGuideApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootGuideApplication.class, args);
}
}
五、总结
Tesseract 5.5.0 的优劣势分析
- 优势:
- 高精度、多语言支持,适合处理各种语言的 OCR 任务。
- 开放源代码,社区活跃,灵活且免费的 OCR 工具。
- 强大的训练和微调能力,适合定制化应用。
- 支持多种输出格式,能够适应不同的需求。
- 跨平台支持,适用于 Linux、Windows 和 macOS。
- 多线程支持,能够提升处理速度,尤其在处理大量图像时。
- 劣势:
- 对图像质量敏感,需要良好的图像质量才能达到最佳效果。
- 手写文字、特殊字体和复杂文档布局的识别效果较差。
- 需要大量训练数据,且训练过程较为复杂。
- 配置和使用相对复杂,特别是在高级功能和定制化应用时。
总体来说,Tesseract 5.5.0 是一个非常强大且灵活的 OCR 工具,尤其适合需要进行自定义训练、批量 OCR 处理、以及开发开源项目的用户。对于一些特殊的应用场景(如手写识别、复杂布局文档等),可能需要考虑其他商业OCR软件或结合多种技术进行优化。