AI工具【OCR 01】Java可使用的OCR工具Tess4J使用举例(身份证信息识别核心代码及信息提取方法分享)

简介: 【2月更文挑战第1天】Lept4J和Tess4J都是基于Tesseract OCR引擎的Java接口,可以用来识别图像中的文本,本次介绍Tess4J

1.简介

1.1 简单介绍

Lept4J和Tess4J都是基于Tesseract OCR引擎的Java接口,可以用来识别图像中的文本:

  • 前者是Leptonica图像处理库的Java封装,提供了图像的加载、处理、分析等功能。
  • 后者是Tesseract OCR引擎的Java封装,提供了图像的OCR识别、PDF文档的生成等功能。

Lept4J和Tess4J的区别在于,Lept4J主要负责图像的预处理,而Tess4J主要负责图像的后处理,特点分别是:

  • Lept4J支持多种图像格式,可以进行图像的缩放、旋转、裁剪、二值化、降噪等操作,提高图像的质量和识别率。
  • Tess4J支持多种语言的识别,可以生成文本、HTML、PDF等格式的输出,提供了多种识别模式和参数设置,满足不同的需求。

根据具体场景和需求,可以选择使用Lept4J或Tess4J,或者结合使用两者,以达到最佳的效果。

1.2 官方说明

官网:https://tess4j.sourceforge.net/
描述:A Java JNA wrapper for Tesseract OCR API.Tess4J is released and distributed under the Apache License, v2.0 and is also available from Maven Central Repository.
特性:The library provides optical character recognition (OCR) support for:

  • TIFF, JPEG, GIF, PNG, and BMP image formats
  • Multi-page TIFF images
  • PDF document format

    2.使用举例

    2.1 依赖及语言数据包

    <!-- https://mvnrepository.com/artifact/net.sourceforge.tess4j/tess4j -->
    <dependency>
          <groupId>net.sourceforge.tess4j</groupId>
          <artifactId>tess4j</artifactId>
          <version>5.9.0</version>
    </dependency>
    

    语言数据包下载地址:https://github.com/tesseract-ocr/tessdata
    LanguageData.jpg

    2.2 核心代码

      /**
       * 识别图片字符信息
       *
       * @param imagePath 图片路径
       */
      private static String recognitionString(String imagePath) {
         
          File imageFile = new File(imagePath);
          ITesseract instance = new Tesseract();
          // 1.语言数据包路径
          instance.setDatapath("tessdata");
          // 2.加载语言文件名称
          instance.setLanguage("chi_sim");
          String result = "";
          try {
         
              result = instance.doOCR(imageFile);
          } catch (TesseractException e) {
         
              e.printStackTrace();
          }
          return result;
      }
    

    2.3 识别身份证信息

    2.3.1 核心代码

      /**
       * 识别身份证信息
       *
       * @param imagePath 图片路径
       */
      private static Map<String, Object> recognitionIdentityCardInfo(String imagePath) {
         
          Map<String, Object> res = new HashMap<>(2);
          // 识别图片
          File imageFile = new File(imagePath);
          BufferedImage bufferedImage = null;
          try {
         
              bufferedImage = ImageIO.read(imageFile);
          } catch (IOException e) {
         
              e.printStackTrace();
          }
          ITesseract instance = new Tesseract();
          instance.setDatapath("tessdata");
          instance.setLanguage("chi_sim");
          List<Word> words = instance.getWords(bufferedImage, 1);
          // 获取姓名
          int nameLineIndex = 0;
          if (words.size() > nameLineIndex) {
         
              res.put("name", getStringByIndex(words.get(0).getText(), 2));
          }
          // 获取性别和民族
          int genderAndNationLineIndex = 1;
          if (words.size() > genderAndNationLineIndex) {
         
              res.put("gender", getStringByIndex(words.get(1).getText(), 2, 1));
              res.put("nation", removeNonChinese(getStringByIndex(words.get(1).getText(), 5, -1)));
          }
          // 获取出生日期
          int birthLineIndex = 2;
          if (words.size() > birthLineIndex) {
         
              res.put("birth", extractBirthDate(getStringByIndex(words.get(2).getText(), 2)));
          }
          // 获取住址
          int addressLineIndex = 3;
          if (words.size() > addressLineIndex) {
         
              res.put("address", getStringByIndex(words.get(3).getText(), 2).replace("/", ""));
          }
          // 获取身份证号码
          int noLineIndex = 4;
          if (words.size() > noLineIndex) {
         
              res.put("no", getStringByIndex(words.get(4).getText(), 7));
          }
          return res;
      }
    

    2.3.2 截取指定字符

      /**
       * 截取指定字符
       *
       * @param inputString 字符串
       * @param indexStart  开始Index
       * @return 截取的字符串
       */
      private static String getStringByIndex(String inputString, int indexStart) {
         
          return getStringByIndex(inputString, indexStart, -1);
      }
    
      /**
       * 截取指定字符
       *
       * @param inputString 字符串
       * @param indexStart  开始Index
       * @param size        截取的字符个数
       * @return 截取的字符串
       */
      private static String getStringByIndex(String inputString, int indexStart, int size) {
         
          // 去除字符串两端的空白字符
          String trimmedString = inputString.trim();
          // 将字符串以空白字符分割
          StringBuilder res = new StringBuilder();
          String[] words = trimmedString.split("\\s+");
          int length = words.length;
          int contentSize = indexStart + size;
          if (length > indexStart) {
         
              int index = length;
              if (size > 0 && length > contentSize) {
         
                  index = contentSize;
              }
              for (int i = indexStart; i < index; i++) {
         
                  res.append(words[i]);
              }
          }
          return res.toString();
      }
    

    2.3.3 去掉字符串里的非中文字符

      /**
       * 去掉字符串里的非中文字符
       *
       * @param inputString 字符串
       * @return 中文字符串
       */
      private static String removeNonChinese(String inputString) {
         
          // 匹配非汉字字符的正则表达式
          String regex = "[^\u4E00-\u9FA5]";
          Pattern pattern = Pattern.compile(regex);
          Matcher matcher = pattern.matcher(inputString);
          // 替换非汉字字符为空格
          return matcher.replaceAll("");
      }
    

    2.3.4 提取出生日期(待优化)

      /**
       * 提取出生日期
       *
       * @param inputString 字符串
       * @return 出生日期
       */
      private static String extractBirthDate(String inputString) {
         
          // 匹配日期格式的正则表达式
          String regex = "(\\d{4}年\\d{2}月\\d{2}日)";
          Pattern pattern = Pattern.compile(regex);
          Matcher matcher = pattern.matcher(inputString);
          // 提取匹配到的日期
          if (matcher.find()) {
         
              return matcher.group(1);
          } else {
         
              return "未找到日期";
          }
      }
    

    2.3.5 实测

    图片:
    ID.jpg
    结果:

    {
         name=代用名, gender=男, nation=汉, birth=20130506, address=湖南省长沙市开福区送道街仪幸福小区居民组, no=30512198908131367}
    
  • 姓名 正确

  • 性别 正确
  • 民族 正确
  • 出生 正确
  • 住址 错了一个字(巡)多了一个字(仪)
  • 公民身份证号码 缺少首位(4)

    3.总结

  • Java能用挺友好

  • 缺点是识别率有点儿低
目录
相关文章
|
11月前
|
机器学习/深度学习 编解码 文字识别
医疗票据OCR图像预处理:印章干扰过滤方案与代码实现
医疗票据OCR技术能自动提取票据中的关键信息,但在实际应用中面临多重挑战。首先,票据版式多样,不同医院、地区的格式差异大,需借助动态模板匹配技术来应对。其次,图像质量参差不齐,存在褶皱、模糊、倾斜、印章遮挡等问题,常通过超分辨率重建和图像修复算法处理。此外,手写体识别、复杂业务逻辑理解(如医疗术语和费用规则)以及数据安全与隐私合规要求也是技术难点。 为应对这些挑战,快瞳系统采用“OCR基础识别 + NLP语义修正”的混合架构,并结合深度学习模型(如CRNN、Transformer)来提升准确率和泛化能力。该技术能显著提升医保报销、保险理赔等场景的效率,是推动医疗信息数字化管理的重要工具。
1002 5
|
11月前
|
人工智能 自然语言处理 物联网
GEO优化方法有哪些?2025企业抢占AI流量必看指南
AI的不断重塑传统的信息入口之际,用户的搜索行为也从单一的百度、抖音的简单的查找答案的模式,逐渐转向了对DeepSeek、豆包、文心一言等一系列的AI对话平台的更加深入的探索和体验。DeepSeek的不断迭代优化同时,目前其月活跃的用户已破1.6亿,全网的AI用户规模也已超过6亿,这无疑为其下一阶段的迅猛发展提供了坚实的基础和广泛的市场空间。
|
11月前
|
Java
Java语言实现字母大小写转换的方法
Java提供了多种灵活的方法来处理字符串中的字母大小写转换。根据具体需求,可以选择适合的方法来实现。在大多数情况下,使用 String类或 Character类的方法已经足够。但是,在需要更复杂的逻辑或处理非常规字符集时,可以通过字符流或手动遍历字符串来实现更精细的控制。
606 18
|
11月前
|
机器学习/深度学习 文字识别 Linux
Umi-OCR_文字识别工具 免安装使用教程(附下载安装包)!永久免费,开源离线OCR识别软件下载
Umi-OCR是一款开源免费、支持离线运行的高精度OCR文字识别工具,基于深度学习技术,可快速识别中文、英文、日文等多种语言。无需联网,保护隐私,适用于Windows和Linux系统,解压即用,操作简便,是处理图片转文本的理想选择。
6249 7
|
11月前
|
Java 编译器 Go
【Java】(5)方法的概念、方法的调用、方法重载、构造方法的创建
Java方法是语句的集合,它们在一起执行一个功能。方法是解决一类问题的步骤的有序组合方法包含于类或对象中方法在程序中被创建,在其他地方被引用方法的优点使程序变得更简短而清晰。有利于程序维护。可以提高程序开发的效率。提高了代码的重用性。方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头写,不使用连接符。例如:addPerson。这种就属于驼峰写法下划线可能出现在 JUnit 测试方法名称中用以分隔名称的逻辑组件。
419 4
|
11月前
|
编解码 Java 开发者
Java String类的关键方法总结
以上总结了Java `String` 类最常见和重要功能性方法。每种操作都对应着日常编程任务,并且理解每种操作如何影响及处理 `Strings` 对于任何使用 Java 的开发者来说都至关重要。
565 5
|
12月前
|
算法 安全 Java
除了类,Java中的接口和方法也可以使用泛型吗?
除了类,Java中的接口和方法也可以使用泛型吗?
302 11
|
12月前
|
人工智能 数据安全/隐私保护 异构计算
桌面版exe安装和Python命令行安装2种方法详细讲解图片去水印AI源码私有化部署Lama-Cleaner安装使用方法-优雅草卓伊凡
桌面版exe安装和Python命令行安装2种方法详细讲解图片去水印AI源码私有化部署Lama-Cleaner安装使用方法-优雅草卓伊凡
1725 8
桌面版exe安装和Python命令行安装2种方法详细讲解图片去水印AI源码私有化部署Lama-Cleaner安装使用方法-优雅草卓伊凡
|
12月前
|
Java 开发者
Java 函数式编程全解析:静态方法引用、实例方法引用、特定类型方法引用与构造器引用实战教程
本文介绍Java 8函数式编程中的四种方法引用:静态、实例、特定类型及构造器引用,通过简洁示例演示其用法,帮助开发者提升代码可读性与简洁性。