一.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 

 

安装完成之后的目录

java版本ocr java开源ocr_图片文字识别

 

3.如果要对含有中文的图片进行识别,需要将中文训练字库(chi_sim.traineddata,自行百度下载或者上我的网盘链接有提供)放到安装完成之后的Tesseract-OCR\tessdata 文件夹下面以供引用

红线标记的即为中文字库,此处已导入

java版本ocr java开源ocr_java版本ocr_02

三,代码实现

识别图片准备

中文图片

java版本ocr java开源ocr_图片文字识别_03

英文图片

java版本ocr java开源ocr_java版本ocr_04

 

新建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();
//		}
	}

}

 

中文识别对比效果

java版本ocr java开源ocr_java版本ocr_05

 

英文识别对比效果

java版本ocr java开源ocr_Tesseract_06

 

总结:由此可看出,图片识别率过低,对此可以有两种方法改进

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或更高的版本。