身份证识别JAVA+OPENCV+OCR
一、相关的地址
https://github.com/tesseract-ocr/tessdata
Releases - OpenCV
opencv要装好,我装的是4.5.3的,最新版的没试过。
tessdata就下载了需要用的。好像还有best和fast的版本,我试了一下报错,不知道是不是版本不支持的问题。

二、主要的思路
识别的代码到没什么特别的,就是在每一行的识别上,为了提高准确度,稍微花了点心思,但也不时很完善。
发现识别的时候会出现很多干扰,所以从“姓”这一行开始算第一行,然后一行一行分析。
如果图片不清晰,不是太准,有待改进。
三、代码
pom.xml的依赖:
<!-- OpenCV --><dependency><groupId>org.openpnp</groupId><artifactId>opencv</artifactId><version>4.5.3-4</version></dependency><!-- Tesseract --><dependency><groupId>net.sourceforge.tess4j</groupId><artifactId>tess4j</artifactId><version>5.11.0</version> <!-- 使用最新版本 --></dependency>
JAVA代码:
package com.yutiandada.idcardread.demos.test;import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;import net.sourceforge.tess4j.*;public class IDCardRecognition2 {static {System.setProperty("java.library.path", "D:\\opencv\\opencv\\build\\java\\x64");try {Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");fieldSysPath.setAccessible(true);fieldSysPath.set(null, null);} catch (Exception e) {e.printStackTrace();}System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}public static Mat preprocessImage(String imagePath) {// 读取图像Mat image = Imgcodecs.imread(imagePath);// 可选:进行一些图像增强操作,例如锐化Mat enhancedImage = new Mat();Imgproc.GaussianBlur(image, enhancedImage, new Size(0, 0), 3);Core.addWeighted(image, 1.5, enhancedImage, -0.5, 0, enhancedImage);return enhancedImage;}public static List<String> recognizeText(Mat mat) throws TesseractException {try {// 将Mat转换为FileFile tempFile = File.createTempFile("temp", ".png");Imgcodecs.imwrite(tempFile.getAbsolutePath(), mat);// 初始化TesseractTesseract tesseract = new Tesseract();tesseract.setLanguage("chi_sim"); // 设置语言为简体中文tesseract.setDatapath("d:/tessdata"); // 设置Tesseract数据路径
// tesseract.setPageSegMode(PageSegMode.PSM_AUTO); // 设置页面分割模式// 进行OCR识别String result = tesseract.doOCR(tempFile);tempFile.delete(); // 删除临时文件// 将结果按行分割List<String> lines = new ArrayList<>();String[] splitResult = result.split("\\r?\\n");for (String line : splitResult) {if (!line.trim().isEmpty()) {lines.add(line.trim());}}return lines;} catch (IOException e) {// 处理异常,例如记录日志或显示错误信息e.printStackTrace();throw new TesseractException("Error during OCR processing", e);}}public static void main(String[] args) {try {String imagePath = "D:/images/test01.png";Mat processedImage = preprocessImage(imagePath);List<String> recognizedLines = recognizeText(processedImage);System.out.println("Recognized Text:");// 找到包含“姓”字的行索引int startIndex = -1;for (int i = 0; i < recognizedLines.size(); i++) {if (recognizedLines.get(i).contains("姓") || recognizedLines.get(i).contains("名") ) {startIndex = i;break;}}if (startIndex != -1) {// 从包含“姓”字的行开始重新编号List<String> filteredLines = recognizedLines.subList(startIndex, recognizedLines.size());// 第一行:“姓名”之后的字符串String name = filteredLines.get(0).replaceAll(".*姓名", "").trim();System.out.println("Name: " + name);// 第二行:性别String gender = "";String ethnicity = "";String secondLine = filteredLines.get(1);if (secondLine.contains("男")) {gender = "男";} else if (secondLine.contains("女")) {gender = "女";}int minIndex = secondLine.indexOf("民") + 2;if (minIndex > 0 && minIndex < secondLine.length()) {ethnicity = secondLine.substring(minIndex).trim();}System.out.println("Gender: " + gender);System.out.println("Ethnicity: " + ethnicity);// 第三行:出生日期,只显示数字String thirdLine = filteredLines.get(2).replaceAll("[^0-9]", "").trim();if (thirdLine.length() == 8) {String birthYear = thirdLine.substring(0, 4);String birthMonth = thirdLine.substring(4, 6);String birthDay = thirdLine.substring(6, 8);System.out.println("Birth Year: " + birthYear);System.out.println("Birth Month: " + birthMonth);System.out.println("Birth Day: " + birthDay);} else {System.out.println("Invalid date format in the third line.");}// 第四行:地址String addressPart1 = filteredLines.get(3).replaceAll("\\s+", "").substring(2).trim();String addressPart2 = filteredLines.get(4).replaceAll("\\s+", "").trim();String address = addressPart1 + addressPart2;System.out.println("Address: " + address);// 第六行:身份证号,只显示数字和字母String idNumber = filteredLines.get(5).replaceAll("[^a-zA-Z0-9]", "").trim();System.out.println("ID Number: " + idNumber);} else {System.out.println("No line containing '姓' found.");}} catch (Exception e) {e.printStackTrace();}}
}
IDEA里面要配置一下

把安装好的OPENCV装一下

四、效果
网上随便找的图

识别的效果

相关文章:
身份证识别JAVA+OPENCV+OCR
一、相关的地址 https://github.com/tesseract-ocr/tessdata Releases - OpenCV opencv要装好,我装的是4.5.3的,最新版的没试过。 tessdata就下载了需要用的。好像还有best和fast的版本,我试了一下报错,不知道是不是版本不支持…...
独立开发者如何利用AI实现高收入
引言 在探索独立开发领域时,AI技术的出现为开发者打开了新世界的大门。本文将分享如何利用AI技术提高开发效率,实现更高的收入。 AI在编程中的应用 AI技术的快速发展为独立开发者带来了前所未有的机遇。通过使用AI,我们可以: …...
Go第三方框架--gorm框架(一)
前言 orm模型简介 orm模型全称是Object-Relational Mapping,即对象关系映射。其实就是在原生sql基础之上进行更高程度的封装。方便程序员采用面向对象的方式来操作数据库,将表映射成对象。 这种映射带来几个好处: 代码简洁:不用…...
ONLYOFFICE文档8.2:开启无缝PDF协作
ONLYOFFICE 开源办公套件的最新版本新增约30个新功能,并修复了超过500处故障。 什么是 ONLYOFFICE 文档 ONLYOFFICE 文档是一套功能强大的文档编辑器,支持编辑处理文档、表格、幻灯片、可填写的表单和PDF。可多人在线协作,支持插件和 AI 集…...
内网python smtplib用ssh隧道通过跳板机发邮件
Python 自带 smtplib 包可以发邮件,示例见 [1,2],在邮箱设置启用 IMAP/POP3 就能用。有些邮箱需要设置授权码,如新浪、163 邮箱,然后以授权码作为 smtplib 登录服务器的密码。邮箱端配置参考 [3,4]。 现在情况是: 邮…...
基于C#开发游戏辅助工具的Windows底层相关方法详解
开发游戏辅助工具通常需要深入了解Windows操作系统的底层机制,以及如何与游戏进程进行有效交互。本文将基于C#语言,从Windows底层方法的角度来详细讲解开发游戏辅助工具的相关技术和概念。 一、游戏辅助工具的基本概述 游戏辅助工具,通常被称…...
SSRF+Redis进行内网渗透
SSRFRedis进行内网渗透 一 环境搭建 准备一台服务器,开启了lampp以及redis,redis只允许内网访问 把上面这个注释放开后,redis就只能内网访问 启动redis 使用kali进行端口扫描,扫不到6379端口 kali连接不上redis ssrf漏洞代码 &…...
栈与队列-Java【力扣】【算法学习day.7】
前言 我做这类文档一个重要的目的还是给正在学习的大家提供方向(例如想要掌握基础用法,该刷哪些题?)我的解析也不会做的非常详细,只会提供思路和一些关键点,力扣上的大佬们的题解质量是非常非常高滴&#…...
最新版本!IntelliJ IDEA 2024.2.4 (Ultimate Edition) 的新特性
IntelliJ IDEA 2024.2版本(Ultimate Edition)的关键新特性包括: 改进的Spring Data JPA支持: 允许在IDE中直接运行Spring Data JPA方法,进行即时仓库查询验证。 无需运行应用程序或分析日志文件,即可查看…...
从头学PHP之运算符
关于运算符的图片均来自网络,主要是自己写太麻烦了,程序是个简化自己工作量的方式,能复制粘贴就不要手写了(建议初期还是多写写,加深下记忆)在这里我就偷个懒,图片涉及到侵权及时,请…...
使用 Git LFS(大文件存储)
Git LFS(Large File Storage)是一种扩展 Git 的工具,旨在更有效地管理大文件的版本控制。它通过将大文件的内容存储在 Git 之外来解决 Git 在处理大文件时的性能问题。 主要特点 替代存储:Git LFS 不直接将大文件存储在 Git 仓库…...
js 将一维数组转换成树形结构的方法
一维数组的数据结构,如下 const flatArray [ { id: 1, parent_id: null, name: ‘root1’ }, { id: 2, parent_id: null, name: ‘root2’ }, { id: 3, parent_id: 1, name: ‘child1’ }, { id: 4, parent_id: 2, name: ‘child2’ }, { id: 5, parent_id: 3, nam…...
HarmonyOS NEXT开发实战:实现高效下拉刷新与上拉加载组件(二)刷新核心逻辑与空页面集成
前言: 在上一篇文章中,我们深入探讨了如何在HarmonyOS中实现一个功能完备的空页面组件。现在,我们将进入下拉刷新和上拉加载功能的核心逻辑实现。这不仅仅是技术实现,更是对用户体验的深刻理解。本文将详细介绍如何将空页面与下拉刷新、上拉加载逻辑相结合,打造一个既高效…...
Crawler4j在多线程网页抓取中的应用
网页爬虫作为获取网络数据的重要工具,其效率和性能直接影响到数据获取的速度和质量。Crawler4j作为一个强大的Java库,专门用于网页爬取,提供了丰富的功能来帮助开发者高效地抓取网页内容。本文将探讨如何利用Crawler4j进行多线程网页抓取&…...
【无标题】Django转化为exe,app
目录 1. 将 Django 项目转换为 .exe 文件(Windows)2. 将 Django 项目转换为 .app 应用程序(macOS)3. 发布到微信公众号将一个 Django 项目转换为 .exe 文件或 .app 应用程序,并发布到微信公众号,实际上涉及多个步骤和技术。下面我将分别介绍这些过程。 1. 将 Django 项目…...
HTML5_标签_各类表格的实现
目录 1. 表格标签 1.1 表格的主要作用 1.2 表格的基本语法 1.3 表头单元格标签 1.4 表格属性 案例分析 先制作表格的结构. 后书写表格属性. 代码示例: 1.5 表格结构标签 1.6 合并单元格 合并单元格方式: 目标单元格:(写合并代码) 合并单元…...
C语言数据结构之单向链表(SingleList)
C语言数据结构之单向链表(SingleList) 自定义结构体数据类型SListNode表示单向链表的节点,成员包括一个无类型的data用来存贮数据和一个SListNode本身类型的指针next,指向下一个节点。围绕SListNode写一系列函数以slist_开头实现…...
【银河麒麟高级服务器操作系统实例】金融行业TCP连接数猛增场景的系统优化
了解更多银河麒麟操作系统全新产品,请点击访问 麒麟软件产品专区:https://product.kylinos.cn 开发者专区:https://developer.kylinos.cn 文档中心:https://documentkylinos.cn 服务器环境以及配置 物理机/虚拟机/云/容器 物理…...
详解Java的类文件结构(.class文件的结构)
this_class 指向常量池中索引为 2 的 CONSTANT_Class_info。super_class 指向常量池中索引为 3 的 CONSTANT_Class_info。由于没有接口,所以 interfaces 的信息为空。 对应 class 文件中的位置如下图所示。 06、字段表 一个类中定义的字段会被存储在字段表&#x…...
爆肝整理14天!AI工具宝藏合集
随着AI技术的飞速发展,各类AI工具如雨后春笋般涌现。经过对上百款AI工具的深入探索与测试,我精心挑选出了一些功能强大的AI神器,这些工具将极大地降低自媒体创作的门槛。 🚀无论是撰写文案、剪辑视频、设计图文,还是处…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...
在 Visual Studio Code 中使用驭码 CodeRider 提升开发效率:以冒泡排序为例
目录 前言1 插件安装与配置1.1 安装驭码 CodeRider1.2 初始配置建议 2 示例代码:冒泡排序3 驭码 CodeRider 功能详解3.1 功能概览3.2 代码解释功能3.3 自动注释生成3.4 逻辑修改功能3.5 单元测试自动生成3.6 代码优化建议 4 驭码的实际应用建议5 常见问题与解决建议…...
用递归算法解锁「子集」问题 —— LeetCode 78题解析
文章目录 一、题目介绍二、递归思路详解:从决策树开始理解三、解法一:二叉决策树 DFS四、解法二:组合式回溯写法(推荐)五、解法对比 递归算法是编程中一种非常强大且常见的思想,它能够优雅地解决很多复杂的…...
