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
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 实测
图片:
结果:{ name=代用名, gender=男, nation=汉, birth=2013年05月06日, address=湖南省长沙市开福区送道街仪幸福小区居民组, no=30512198908131367}
姓名 正确
- 性别 正确
- 民族 正确
- 出生 正确
- 住址 错了一个字(巡)多了一个字(仪)
公民身份证号码 缺少首位(4)
3.总结
Java能用挺友好
- 缺点是识别率有点儿低