【Java-tesseract】OCR图片文本识别

文章目录

一、需求

场景需求:是对识别常见的PNG,JPEG,TIFF,GIF 图片识别,环境为离线内网 。组件要求开源免费,并且可以集成Java生成接口服务。

二、概述

我不做选型对比了,我筛选测试了下Tesseract(v5.5.0)是比较符合我的需求的。其 支持多种图像格式进行光学字符识别(OCR),以下是 Tesseract 支持的主要图像格式:

  1. 常见图像格式:
  • PNG:无损压缩格式,是最常用的图像格式之一,适用于OCR,因为它可以保留图像细节。
  • JPEG(JPG):有损压缩格式,通常用于照片和复杂图像。尽管可能存在质量损失,Tesseract 依然能够处理 JPEG 格式的图像。
  • TIFF:一种无损压缩格式,常用于扫描文档。TIFF 格式通常比 JPEG 更适合OCR,因为它保留了更多细节。
  • BMP:位图格式,通常较大,但Tesseract也支持该格式。
  • GIF:支持的图像格式,尽管在颜色精度和压缩效率方面不如 PNG 或 TIFF。
  1. 支持的颜色模式:
    Tesseract 支持不同的颜色模式来处理图像:
  • RGB:标准的三通道图像,支持彩色图像。
  • Grayscale:灰度图像模式,通常用于文档图像。
  • Black & White (1-bit):黑白图像,通常在扫描的文档或手写文本中使用。
  1. 其他支持的图像格式:
    Tesseract 还支持通过某些图像处理库(如 PIL)处理的其他图像格式。通过 Python 的 pytesseract,你还可以使用一些其他图像格式,如:
  • WEBP:一种新的图像格式,常用于Web图片。
  • PPM/PGM:一个无损的图像格式,通常用于科学计算中。
  • HEIF:高级图像文件格式(如 iPhone 图片),Tesseract 可以通过额外的库来支持。
  1. 图像转换和预处理:
    尽管 Tesseract 支持多种格式,通常对于 OCR 的最佳效果,建议图像为高质量的灰度图像(即灰度模式)。如果原始图像格式过大或质量不高,可以考虑进行预处理,如:
  • 裁剪:去除不必要的边缘区域。
  • 二值化:将图像转换为黑白色调,以提高文字识别的准确性。
  • 去噪:去除背景噪音,有助于提高识别效果。
  • 旋转:如果文档有角度,可以对其进行旋转校正。
  1. 官网地址

三、部署安装

我上传了下面两个部署包,提供给无法访问github的同学使用:部署包

  1. windwos下载:下载安装即可
  2. linux部署:需要下载.tar.gz源码包编译
    我这边使用ubuntu24.10容器部署编译了tesseract5.5.0,并且打包成了tar压缩包,需要的同学可以去这里下载。当然也可以自己用gcc编译。注意(该docker没有那种java等,属于一个轻量包,方便后续你进行扩展)
    我上传的文件地址:tesseract.tar
  • 使用方法:
bash 复制代码
#加载镜像文件
docker load -i tesseract.tar
#运行镜像
docker run -itd --name tesseract -v ./data:/data tesseract:v0
  • 调用服务
    若需要将tesseract提供给外部使用,需要使用java开发接口,通过http将服务暴露给外部使用。
bash 复制代码
#可以进入容器
docker exec -it tesseract /bin/bash
#执行一下命令解析图片测试,需要图片放到./data中挂载到容器的/data中,-l chi_sim是识别中文
tesseract input_image.png output_text -l chi_sim
  1. 整合包(重量)
    相对上述2,新增了整合了java和tesseract语言包的docker镜像tesseract-java,其可以开箱即用,但是很大有1.81G,需要7Z压缩下。
    整合包地址:整合包地址
    1.使用教程与上述2操作一致,区别如下:
bash 复制代码
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.服务调用

bash 复制代码
POST:http://服务节点IP:8080/orc/transform
form-data:file

四、技术细节

  1. java代码调用tesseract
bash 复制代码
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);
    }

}
  1. pom
bash 复制代码
<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>
 
  1. 接口
bash 复制代码
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;
    }
}
  1. 启动类
bash 复制代码
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 的优劣势分析

  1. 优势:
  • 高精度、多语言支持,适合处理各种语言的 OCR 任务。
  • 开放源代码,社区活跃,灵活且免费的 OCR 工具。
  • 强大的训练和微调能力,适合定制化应用。
  • 支持多种输出格式,能够适应不同的需求。
  • 跨平台支持,适用于 Linux、Windows 和 macOS。
  • 多线程支持,能够提升处理速度,尤其在处理大量图像时。
  1. 劣势:
  • 对图像质量敏感,需要良好的图像质量才能达到最佳效果。
  • 手写文字、特殊字体和复杂文档布局的识别效果较差。
  • 需要大量训练数据,且训练过程较为复杂。
  • 配置和使用相对复杂,特别是在高级功能和定制化应用时。
    总体来说,Tesseract 5.5.0 是一个非常强大且灵活的 OCR 工具,尤其适合需要进行自定义训练、批量 OCR 处理、以及开发开源项目的用户。对于一些特殊的应用场景(如手写识别、复杂布局文档等),可能需要考虑其他商业OCR软件或结合多种技术进行优化。
相关推荐
A XMan.1 小时前
JSON结构快捷转XML结构API集成指南
xml·java·前端·json·php
小林爱1 小时前
【Compose multiplatform教程06】用IDEA编译Compose Multiplatform常见问题
android·java·前端·kotlin·intellij-idea·compose·多平台
炸鸡配泡面3 小时前
Qt 12.28 day3
java·开发语言
get_money_3 小时前
代码随想录Day37 动态规划:完全背包理论基础,518.零钱兑换II,本周小结动态规划,377. 组合总和 Ⅳ,70. 爬楼梯(进阶版)。
java·笔记·算法·动态规划
get_money_3 小时前
代码随想录38 322. 零钱兑换,279.完全平方数,本周小结动态规划,139.单词拆分,动态规划:关于多重背包,你该了解这些!背包问题总结篇。
java·开发语言·笔记·算法·动态规划
憶巷5 小时前
设计模式的分类及作用
java·设计模式
向宇it6 小时前
【从零开始入门unity游戏开发之——C#篇36】C#的out协变和in逆变如何解决泛型委托的类型转换问题
java·开发语言·unity·c#·游戏引擎
天空之外1366 小时前
Spring Boot Actuator、Spring Boot Actuator使用、Spring Boot Actuator 监控、Spring程序监控
java·spring boot·spring
baihb10246 小时前
Docker 默认安装位置迁移
java·docker
B1nnnn丶6 小时前
通用导出任何对象列表数据的excel工具类
java·spring boot·excel