前提:
1,下载Tesseract-OCR,https://tesseract-ocr.github.io/并安装;
2,下载训练字库tessdata_best,当然也可以不用下载,安装好之后,自带字库,识别成功效果当然也不太好;
所有字库都可以从官方网站下载到,你如果愿意自己做字库训练也是可以的;
下载的字库可以和安装的字库放统一目录,
例如我安装的位置:D:\Program Files\Tesseract-OCR,本身这个目录下有了tessdata字库,下载的tessdata_best字库可以和tessdata平级;
3, 追加环境变量:
Path=D:\Program Files\Tesseract-OCR
TESSDATA_PREFIX=D:\Program Files\Tesseract-OCR\tessdata
打开命令终端,输入:tesseract -v 可以看到版本信息;
4,建立java工程,添加maven依赖,版本号用最新的就好了,还用到了hutool-all工具,自行添加就好
<dependency>
<groupId>net.sourceforge.tess4j</groupId>
<artifactId>tess4j</artifactId><version>4.5.5</version>
</dependency>
5,上代码
package com.boot.test;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.List;
import javax.imageio.ImageIO;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cn.hutool.core.img.ImgUtil;
import net.sourceforge.tess4j.ITessAPI.TessPageIteratorLevel;
import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.util.ImageHelper;
public class OcrTest {
private static Logger logger = LoggerFactory.getLogger(OcrTest.class);
@Test
public void testOcr() throws Exception {
process("D:\\card1.jpg");
logger.info("-------------------------------------");
process("D:\\card2.jpg");
logger.info("-------------------------------------");
process("D:\\card3.jpg");
}
public void process(String path) throws Exception {
double MINIMUM_DESKEW_THRESHOLD = 5.0d;
File file = new File(path);
BufferedImage image = ImageIO.read(file);
ImgUtil.read(file);
// ImageDeskew id = new ImageDeskew(image);
// double imageSkewAngle = id.getSkewAngle(); // determine skew angle
// logger.info("imageSkewAngle:{}",imageSkewAngle);
// if ((imageSkewAngle > MINIMUM_DESKEW_THRESHOLD || imageSkewAngle < -(MINIMUM_DESKEW_THRESHOLD))) {
// image = ImageHelper.rotateImage(image, -imageSkewAngle); // deskew image
// }
//灰色图片
Image gray = ImgUtil.gray(ImgUtil.read(file));
BufferedImage imageGray = ImageHelper.convertImageToGrayscale(image);
//二值化处理
BufferedImage image2D =ImageHelper.convertImageToBinary(imageGray);
Image finalImg = ImgUtil.cut(gray, new Rectangle(5,372,248,26));
ITesseract instance = new Tesseract();
//获得Tesseract的文字库,设置语言库位置
instance.setDatapath("D:\\Program Files\\Tesseract-OCR\\tessdata_best");
instance.setTessVariable("tessedit_char_whitelist", "1234567890");//设置识别范围
//chi_sim :简体中文, eng:英文 根据需求选择语言库
// instance.setLanguage("chi_sim");
// instance.setOcrEngineMode(TessOcrEngineMode.OEM_TESSERACT_ONLY);
//把要识别的图片按文字行拆成多个区域块
List<Rectangle> resultList = instance.getSegmentedRegions(imageGray,TessPageIteratorLevel.RIL_TEXTLINE);
Rectangle rect = null;
for (int i = 0; i < resultList.size(); i++) {
rect = resultList.get(i);
// String result = instance.doOCR(ImgUtil.toBufferedImage(gray),rect);
// logger.info(result);
// logger.info(String.format("Box[%d]: x=%d, y=%d, w=%d, h=%d", i, rect.x, rect.y, rect.width, rect.height));
}
// ImgUtil.cut(gray, new File("D:\\card1-c.jpg"), rect);
String result = "";
// long startTime = System.currentTimeMillis();
//识别灰色图片的最后一个区域块
result = instance.doOCR(ImgUtil.toBufferedImage(gray),rect);
//识别二值化图片的最后一个区域块
// result = instance.doOCR(image2D,rect);
// long endTime = System.currentTimeMillis();
// logger.info("Time is:" + (endTime - startTime) + " 毫秒");
logger.info("result: \n {}",result);
}
}
原图片:
卡号识别效果:
6,问题说明:
a,识别过程: 读取-->图片旋转(视情况而定)-->图片转灰(视情况而定) -->图片二值化处理(视情况而定) --->图片识别区块拆分(视情况而定) --->识别结果;
b,对于识别的结果这和设置的字库,图片都有关系;例如上面例子中,灰图的识别就比二值化的识别效果要好;设置了不同的字库也有可能识别出不同的结果,
这个大家要根据实际需求调试代码;
c,Linux环境注意,tess4j.jar包中要看下有没有包含tesseract.so文件(目前我的版本是没有的);如果没有,需要在linux环境安装Tesseract-OCR之后,把tesseract.so复制
到resource目录或classpath指向的目录,详情请看tess4j.jar包的net.sourceforge.tess4j.util.LoadLibs文件