一.Tesseract-OCR 简介
Tesseract 是Ray Smith 在1985 - 1995年间在惠普布里斯托实验室开发的一个ocr引擎(OCR (Optical Character Recognition,光学字符识别)),也是目前由谷歌支持的开源OCR项目。
有两种方式 动态库方式 libtesseract
和 执行程序方式 tesseract
.exe 使用Tesseract 此处只介绍第二种方式
二.Tesseract-OCR环境搭建
1.官网下载tesseract
.exe (注意:不含中文字库)
2.安装可执行程序tesseract
.exe
安装完成之后的目录
3.如果要对含有中文的图片进行识别,需要将中文训练字库(chi_sim.traineddata,自行百度下载或者上我的网盘链接有提供)放到安装完成之后的Tesseract-OCR\tessdata 文件夹下面以供引用
红线标记的即为中文字库,此处已导入
三,代码实现
识别图片准备
中文图片
英文图片
新建OCRHelper类 代码如下 该类既封装了单张图片识别的函数 ,又封装了文件夹识别的函数 只需注意当识别中文图片和英文图片时传递不同的flag即可
package ocr;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import utils.ImageGray;
import utils.ImageTailor;
import utils.ImageWatermark;
import utils.ImagesIO;
public class OCRHelper {
/**
* @param imageFile
* 传入的图像文件
* @param flag
* 是否识别中文
*
* @return 识别后的字符串
*/
public String recognizeByOne(File imageFile, Boolean flag) throws Exception {
// 将识别出的内容保存在txt临时文本中,目录与图片在同一级,读取万临时文件内容后会删除该文件
File tempFile = new File(imageFile.getParentFile(), "temp");
StringBuffer result = new StringBuffer(); // 接收识别结果
// cmd 输出格式[C:\Program Files (x86)\Tesseract-OCR\tesseract, 1.png,
// output,-l, chi_sim]
List<String> cmd = new ArrayList<String>();
// 注意: C:\\Program Files (x86)\\Tesseract-OCR是你的tesseract-OCR的安装目录
// 我这里是默认安装目录
cmd.add("C:\\Program Files (x86)\\Tesseract-OCR\\tesseract");
cmd.add("");
cmd.add(tempFile.getName()); // 指定识别出内容保存位置
cmd.add("-l"); // 语言参数标志 注意 :这里是字母l 不是数字1
if (flag) { // 设置语言库 中文 chi_sim 英文 eng
cmd.add("chi_sim");
} else {
cmd.add("eng");
}
// ProcessBuilder类是J2SE 1.5在java.lang中新添加的一个新类,
// 此类用于创建操作系统进程,它提供一种启动和管理进程(也就是应用程序)的方法。
// 也可用 Runtime.getRuntime().exec("tesseract.exe 1.jpg 1 -l chi_sim"); 执行
ProcessBuilder pb = new ProcessBuilder();
pb.directory(imageFile.getParentFile()); // 设置进程工作目录
cmd.set(1, imageFile.getName());
pb.command(cmd);
pb.redirectErrorStream(true);
Process process = pb.start();
int w = process.waitFor(); // 进程等待
if (w == 0)// 0代表正常退出
{
BufferedReader in = new BufferedReader(
new InputStreamReader(new FileInputStream(tempFile.getAbsolutePath() + ".txt"), "UTF-8"));
String str;
while ((str = in.readLine()) != null) { // 读取识别结果
result.append(str + "\n"); // 这里每读取一行需要添加换行符
// (否则识别出的结果在用记事本打开不会换行,但是用notepad会看见换行)
}
in.close();
} else {
String msg;
switch (w) {
case 1:
msg = "Errors accessing files. There may be spaces in your image's filename.";
break;
case 29:
msg = "Cannot recognize the image or its selected region.";
break;
case 31:
msg = "Unsupported image format.";
break;
default:
msg = "Errors occurred.";
}
throw new RuntimeException(msg);
}
new File(tempFile.getAbsolutePath() + ".txt").delete(); // 删除临时生成的txt文件
return result.toString();
}
/**
* 根据文件目录识别图片
*
* @param folder
* 需要识别的图片文件夹
* @param flag
* 是否识别中文图片
*/
public String recognizeByFolder(String folder, Boolean flag) {
String result = "";// 保存识别出的结果
String[] fileNames = ImagesIO.getFileNames(folder);// 获取所有图片名称
for (String filename : fileNames) {
String impPath = folder + "/" + filename; // 图片路径
try {
result += this.recognizeByOne(new File(impPath), false) + "\n";
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return result;
}
public static void main(String[] args) {
//单张图片识别方法
File file = new File("D:\\images\\test1.png");
try {
System.out.println(new OCRHelper().recognizeByOne(file, false));//英文识别 false 中文识别 true
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//文件夹识别方法
// String folder = "D:\\images";
// try {
// System.out.println(new OCRHelper().recognizeByFolder(folder, false));//英文识别 false 中文识别 true
// } catch (Exception e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
}
}
中文识别对比效果
英文识别对比效果
总结:由此可看出,图片识别率过低,对此可以有两种方法改进
1.对图片进行预处理,比如灰度化,二值化,对比度增强等
2.利用jTessBoxEditor工具对中文字库进行训练,提高识别正确率(读者可自行百度学习)
安装jTessBoxEditor
解压后得到jTessBoxEditor,由于这是由Java开发的,所以我们应该确保在运行jTessBoxEditor前先安装JRE(Java Runtime Environment,Java运行环境)。
5.异常分析
1. Exception in thread “main” java.lang.Error: Invalid memory access
没有设置训练库的位置
2. Exception in thread “main” java.lang.UnsupportedClassVersionError: net/sourceforge/tess4j/Tesseract :
JDK版本低于1.7,使用1.7或更高的版本。