Java实现OCR识别
日期 |
版本 |
作者 |
说明 |
2024-10-26 |
V-1.0 |
孔留锋 |
文档新建。 |
|
|
|
|
|
|
|
|
需求
项目需求做身份认证,用户注册时候收集用户手机号、身份证号。用户认证的时候,上传身份证号正反面,对比身份证号基于认证标识。
方案一基于Tesseract+Opencv
思路,基于Tesseract 对身份证进行识别,实际测试识别的效果不是很多,故利用opencv 库对图片预处理,从而提高 Tesseract 的识别准确度。图像预处理通常包括:灰度化、二值化、去噪、旋转和倾斜校正等操作。
- Tesseract :是一个开源的光学字符识别(OCR,Optical Character Recognition)引擎。它被广泛用于从图像中提取文本,支持多种语言,并且能够处理不同类型的文本图像,包括打印文本、手写文本以及结构化的文档。
- opencv:(Open Source Computer Vision Library,开源计算机视觉库)是一个开源的计算机视觉和机器学习软件库。它提供了丰富的功能,用于图像处理、视频分析、物体检测、人脸识别、机器学习等任务。OpenCV 是由 Intel 开发并发布的,后续由社区和组织进行维护和扩展。它支持多种编程语言,包括 C++、Python、Java 和 MATLAB/Octave。
Tesseract
官网地址
https://github.com/tesseract-ocr/tesseract
下载地址
https://github.com/UB-Mannheim/tesseract/wiki
安装
安装包:tesseract-ocr-w64-setup-5.5.0.20241111.exe
安装目录可以选择 D:\Mac\ai\tessearct-ocr
点击下一步即可。
语言模型下载
https://tesseract-ocr.github.io/tessdoc/Data-Files.html
下载对应的语言包,下载下来后,移动到安装目录D:\Mac\ai\tessearct-ocr\tessdata 下。
tesseract –list-langs 查看是否识别
命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
|
tesseract -h
tesseract -v
tesseract --list-langs chi_sim 简体中文 chi_tra 繁体中文 eng 英文
tesseract imagename outputbase [-l lang] [--oem ocrenginemode] [--psm pagesegmode] [configfiles...]
-l chi_sim
-l chi_sim+eng
tesseract images/toc.png - --psm 6 -c preserve_interword_spaces=1
|
opencv
官网地址
https://opencv.org
下载地址
https://opencv.org/releases/
安装
安装包:opencv-4.10.0-windows.exe
点击安装即可
1 2 3 4
| D:\Mac\ai\opencv\opencv\ ├── build\ ├── opencv\ └── opencv_contrib\
|
环境变量配置
1 2 3 4
| 将 D:\Mac\ai\opencv\opencv\build\x64\vc15\bin 路径添加到系统环境变量 PATH 中 将 D:\Mac\ai\opencv\opencv\build\bin 路径添加到系统环境变量 PATH 中 将 D:\Mac\ai\opencv\opencv\build\java 路径添加到系统环境变量 PATH 中 将 D:\Mac\ai\opencv\opencv\build\java\x64 路径添加到系统环境变量 PATH 中
|
命令行使用Tesseract
1 2 3
| tesseract b.jpg result -l chi_sim --oem 3 --psm 4
|
Java使用Tesseract
POM安装
1 2 3 4 5
| <dependency> <groupId>net.sourceforge.tess4j</groupId> <artifactId>tess4j</artifactId> <version>4.5.5</version> </dependency>
|
Java 使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public static void main(String[] args) { String IdCardPath = "D:\\data\\b.jpg" ITesseract instance = new Tesseract(); instance.setDatapath("D:\\Mac\\ai\\tessearct-ocr\\tessdata\\"); instance.setLanguage("chi_sim"); instance.setOcrEngineMode(3); instance.setPageSegMode(4); try { String result = instance.doOCR(new File("IdCardPath")); System.out.println(result); } catch (TesseractException e) { e.printStackTrace(); } }
|
Java使用Tesseract+opencv
POM安装
1 2 3 4 5 6 7 8 9 10 11
| <dependency> <groupId>net.sourceforge.tess4j</groupId> <artifactId>tess4j</artifactId> <version>4.5.5</version> </dependency>
<dependency> <groupId>org.opencv</groupId> <artifactId>opencv</artifactId> <version>4.10.0</version> </dependency>
|
Java 使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
| package com.imalt.ai.api;
import net.sourceforge.tess4j.ITesseract; import net.sourceforge.tess4j.Tesseract; import net.sourceforge.tess4j.TesseractException; import org.opencv.core.*; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc;
import java.awt.image.BufferedImage;
public class TesseractOCR { static { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }
public static Mat preprocessImage(String imagePath) { Mat img = Imgcodecs.imread(imagePath);
Mat gray = new Mat(); Imgproc.cvtColor(img, gray, Imgproc.COLOR_BGR2GRAY);
Mat binary = new Mat(); Imgproc.threshold(gray, binary, 0, 255, Imgproc.THRESH_BINARY_INV + Imgproc.THRESH_OTSU);
Mat denoised = new Mat(); Imgproc.GaussianBlur(binary, denoised, new Size(5, 5), 0);
Mat rotated = correctTilt(denoised);
return rotated; }
public static Mat correctTilt(Mat img) { Mat edges = new Mat(); Imgproc.Canny(img, edges, 50, 150);
MatOfPoint2f approxCurve = new MatOfPoint2f(); Mat hierarchy = new Mat(); java.util.List<MatOfPoint> contours = new java.util.ArrayList<>(); Imgproc.findContours(edges, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
double angle = 0.0; for (MatOfPoint contour : contours) { RotatedRect rect = Imgproc.minAreaRect(new MatOfPoint2f(contour.toArray())); angle = rect.angle; if (Math.abs(angle) > 45) { angle = 90 - Math.abs(angle); } break; }
Mat rotated = new Mat(); Point center = new Point(img.width() / 2, img.height() / 2); Mat rotationMatrix = Imgproc.getRotationMatrix2D(center, angle, 1.0); Imgproc.warpAffine(img, rotated, rotationMatrix, img.size());
return rotated; }
public static String recognizeText(Mat processedImage) { BufferedImage bufferedImage = matToBufferedImage(processedImage);
ITesseract instance = new Tesseract(); instance.setDatapath("D:\\Mac\\ai\\tessearct-ocr\\tessdata\\"); instance.setLanguage("chi_sim"); instance.setOcrEngineMode(3); instance.setPageSegMode(4);
try { String result = instance.doOCR(bufferedImage); System.out.println(result); return result; } catch (TesseractException e) { e.printStackTrace(); } return null; }
public static BufferedImage matToBufferedImage(Mat mat) { int width = mat.width(); int height = mat.height(); int channels = mat.channels(); byte[] sourcePixels = new byte[width * height * channels * 10]; mat.get(0, 0, sourcePixels);
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR); image.getRaster().setDataElements(0, 0, width, height, sourcePixels); return image; }
public static void main(String[] args) { String imagePath = "D:\\data\\b.jpg";
Mat preprocessedImage = preprocessImage(imagePath);
String result = recognizeText(preprocessedImage);
System.out.println("识别结果: " + result); } }
|
方案二基于RapidOcr-Java
mymonstercat
官网地址
https://github.com/MyMonsterCat/RapidOcr-Java
简介
POM安装
1 2 3 4 5 6 7 8 9 10
| <dependency> <groupId>io.github.mymonstercat</groupId> <artifactId>rapidocr</artifactId> <version>0.0.7</version> </dependency> <dependency> <groupId>io.github.mymonstercat</groupId> <artifactId>rapidocr-onnx-platform</artifactId> <version>0.0.7</version> </dependency>
|
Java 使用
1 2 3 4 5 6 7 8 9
| public static void main(String[] args) { ParamConfig paramConfig = ParamConfig.getDefaultConfig(); paramConfig.setDoAngle(true); paramConfig.setMostAngle(true); InferenceEngine engine = InferenceEngine.getInstance(Model.ONNX_PPOCR_V4); OcrResult ocrResult = engine.runOcr( "D:\\data\\b.jpg", paramConfig); String strRes=ocrResult.getStrRes(); System.out.println(strRes); }
|
Linux 环境风险
文档参考
https://github.com/MyMonsterCat/RapidOcr-Java/blob/main/docs/CentOS7.md
Linux环境要求
- 确保gcc>=9.1.0
- 确保cmake>=4
- 确保GLIBC>=2.26
使用建议