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

Java可使用的OCR工具Tess4J使用举例

  • 1.简介
    • 1.1 简单介绍
    • 1.2 官方说明
  • 2.使用举例
    • 2.1 依赖及语言数据包
    • 2.2 核心代码
    • 2.3 识别身份证信息
      • 2.3.1 核心代码
      • 2.3.2 截取指定字符
      • 2.3.3 去掉字符串里的非中文字符
      • 2.3.4 提取出生日期(待优化)
      • 2.3.5 实测
  • 3.总结

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能用挺友好
  • 缺点是识别率有点儿低

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/361300.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

闭包的理解?闭包使用场景

说说你对闭包的理解&#xff1f;闭包使用场景 #一、是什么 一个函数和对其周围状态&#xff08;lexical environment&#xff0c;词法环境&#xff09;的引用捆绑在一起&#xff08;或者说函数被引用包围&#xff09;&#xff0c;这样的组合就是闭包&#xff08;closure&#…

FFmpeg和Monibuka拉取rtsp(大华摄像头)视频流时未进行URLCode编码导致提示404等报错

场景 Monibucav4(开源流媒体服务器)在Windows上搭建rtmp服务器并实现拉取rtsp视频流以及转换flv播放&#xff1a; Monibucav4(开源流媒体服务器)在Windows上搭建rtmp服务器并实现拉取rtsp视频流以及转换flv播放_monibuca 搭建流媒体服务-CSDN博客 Nginx搭建RTMP服务器FFmpeg…

Origin 2022下载安装教程,操作简单,小白也能轻松搞定,附安装包,带软件使用教程

前言 Origin是一个科学绘图、数据分析软件&#xff0c;支持各种各样的2D/3D图形&#xff0c;包括统计&#xff0c;信号处理&#xff0c;曲线拟合以及峰值分析&#xff0c;Origin具有强大的数据导入功能和多样的图形输出格式。 准备工作 1、Win7及以上系统 2、提前准备好 Or…

十分钟快速上手Spring Boot与微信小程序API接口的调用,快速开发小程序后端服务

1.1 微信小程序API接口介绍 微信小程序API接口是连接小程序前端与后端服务器的桥梁&#xff0c;它提供了丰富的功能接口&#xff0c;包括用户信息、支付、模板消息、数据存储等。这些API接口能够满足开发者在小程序中实现各种复杂业务逻辑的需求。 用户信息接口 用户信息接口…

Windows PC版微信内置浏览器调试(更新版)

前言 在日常的开发中&#xff0c;尤其是在微信公众号的相关开发中&#xff0c;我们需要进行微信端的调试&#xff0c;如果是后端开发&#xff0c;频率会更高。早期的微信版本&#xff0c;还支持查看网页元素以及接口请求&#xff0c;近年来&#xff0c;微信将这个功能频闭掉了…

链动2+1:打造企业级社交电商新篇章

随着互联网的迅猛发展&#xff0c;社交电商已成为商业领域的新宠。而在众多社交电商模式中&#xff0c;链动21模式以其独特的优势和魅力&#xff0c;正逐渐成为企业级用户的首选。本文将深入探讨链动21模式的优势&#xff0c;以及如何助力企业级用户实现商业成功。 一、链动21模…

vue环境安装 nodejs和vue

npm 是 NodeJS 下的包管理器,vue-cli脚手架模板就是基于 node 下的 npm 来完成安装的。 webpack: 它的主要用途是通过CommonJS的语法把所有浏览器端需要发布的静态资源做相应的准备,比如资源的合并和打包。 vue-cli:官方提供的一个脚手架,用于快速生成一个 vue 的项目模板。…

精通Python第16篇—深入解析Pyecharts极坐标系参数与实战

文章目录 Pyecharts绘制多种炫酷极坐标系参数说明与方向的技术博客1. 导入必要的库2. 极坐标系基础3. 定制化极坐标系4. 方向性的极坐标系5. 极坐标系的动画效果6. 自定义极坐标轴标签7. 添加极坐标系的背景图8. 极坐标系的雷达图总结 Pyecharts绘制多种炫酷极坐标系参数说明与…

Unity触发检测Trigger踩坑合集

正常状态 绿色方块&#xff1a;刚体碰撞盒检测触发碰撞脚本 蓝色方块&#xff1a;碰撞盒 检测脚本&#xff1a; 正常进出&#xff1a; 踩坑1 绿色方块&#xff1a;刚体碰撞盒检测触发碰撞脚本 蓝色方块&#xff1a;碰撞盒 保持绿色和蓝色方块的接触 对蓝色方块&#xff1a…

http代理与socks5代理有什么差异,http代理出现502错误如何修复?

一、HTTP代理与SOCKS5代理的差异HTTP代理和SOCKS5代理都是网络代理服务的两种主要类型&#xff0c;但它们在实现方式和应用场景上存在明显的差异。1.协议差异HTTP代理基于HTTP协议&#xff0c;是一种应用层代理&#xff0c;主要用于代理HTTP请求和响应。而SOCKS5代理则基于SOCK…

幻兽帕鲁服务器一键部署保姆教程

在帕鲁的世界&#xff0c;你可以选择与神奇的生物「帕鲁」一同享受悠闲的生活&#xff0c;也可以投身于与偷猎者进行生死搏斗的冒险。帕鲁可以进行战斗、繁殖、协助你做农活&#xff0c;也可以为你在工厂工作。你也可以将它们进行售卖&#xff0c;或肢解后食用。 想要部署属于自…

BC1.2 SDP/CDP/DCP介绍

参考&#xff1a;文章链接 Microchip Lightning Support 问题 Q1.) 在Microchip产品的数据表中提到了电池充电技术&#xff0c;但以下术语是什么意思: BC1.2? SDP? CDP? DCP? “SE1”? Q2.) 如何配置Microchip Hub以启用这些功能&#xff1f; Q3.) 如何在我的硬件上物…

Codeforces Round 922 (Div. 2)补题

Brick Wall&#xff08;Problem - A - Codeforces&#xff09; 题目大意&#xff1a;规定砖的大小为1*k&#xff08;k>2&#xff09;,现在有一面n*m的砖墙&#xff0c;n是墙高&#xff0c;m是墙宽&#xff0c;砖在砖墙中有两种放法&#xff0c;水平放置和竖直放置&#xff…

修复WordPress内部服务器错误的步骤及解决方案

WordPress是一款广泛使用的开源内容管理系统&#xff0c;但在使用过程中&#xff0c;可能会遇到各种内部服务器错误。这些错误可能由于多种原因引起&#xff0c;例如插件冲突、文件权限问题、服务器配置不当等。为了帮助您快速解决这些问题&#xff0c;本文将为您提供一套详细的…

智能优化算法 | Matlab实现霸王龙优化算法(TROA)(内含完整源码)

文章目录 效果一览文章概述源码设计参考资料效果一览 文章概述 智能优化算法 | Matlab实现霸王龙优化算法(TROA)(内含完整源码) 源码设计 %%clear all clcSearchAgents_no=50; % Number of search agentsFunction_name=</

Spring AOP原理的常见面试题

Spring AOP原理的常见面试题 .Spring AOP是怎么实现的什么是代理模式静态代理动态代理怎么实现的JDK动态代理CGLIB动态代理引入依赖 JDK与CJLIB的区别什么时候使用JDK与CJLIB . Spring AOP是怎么实现的 答:Spring AOP是通过动态代理来实现AOP的 什么是代理模式 答:代理模式也…

离线使用Element UI和Vue

需要依赖如下&#xff1a; 1.vue.js; 2.index.js(Element UI) 3.index.css(Element UI) 4.element-icons.ttf(Element UI字体) 5.element-icons.woff(Element UI图标) 下载链接如下&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1nGOi0Vm_xExRGmVp6oVLoA 提取…

Django问题报错:Cannot resolve keyword ‘name‘ into field. Choices are: course, id

笔者在进行登录注册实验用户名已经注册过的操作时报错 一、错误位置 二、问题原因 使用Student模型时参数名错误 三、解决办法 修改为与Student模型中对应的参数名,问题解决

Cache Lab:Part A【模拟出使用LRU策略的高速缓存存储器组织结构】

目录 任务描述 知识回顾 实验内容 测试结果 Cache Lab 对应《CS:APP》6.3节至第六章结束的内容。 任务描述 Your job for Part A is to fill in the csim.c file so that it takes the same command line arguments and produces the identical output as the reference …

0131-2-关于事件捕获和冒泡

关于事件捕获和冒泡 DOM事件流分为三个阶段&#xff1a;捕获阶段、目标阶段、冒泡阶段 点击目标元素后&#xff0c;不会马上触发目标元素&#xff0c;而是先执行事件捕获&#xff0c;从顶部逐步到目标元素&#xff1b;处于目标阶段的时候触发目标元素&#xff1b;最后冒泡阶段…