一、需要用到Tesseract-OCR所以先下载,并安装
二、配置环境变量,在系统环境变量中,Path添加C:\Program Files (x86)\Tesseract-OCR;新建变量TESSDATA_PREFIX,变量值为C:\Program Files (x86)\Tesseract-OCR\tessdata
三、开始识别
(1)例如C:\Users\dell\Desktop\test\test.jpg的图片
(2)测试识别效果
识别图片命令
tesseract 图片名称 生成的结果文件的名称 字库
cmd命令行进入图片所在文件夹位置,输入命令(其中chi_sim是中文的字库),result是在当前文件夹下生产一个result.txt文件并写入识别的内容
tesseract test.jpg result -l chi_sim
(3)打开result.txt文件,识别的不是很准确,可以对字库进行训练
四、训练字库
(1)需要下载jTessBoxEditor工具,jTessBoxEditor是java写的,所以需要安装jdk
(2)修改图片名字,不能随意命名,有固定的格式,这里我把图片名字改成cs.roy.exp0.jpg
[lang].[fontname].exp[num]
(3)利用windows自带的画图工具另存为.tif文件
(4)生成.box文件,cmd输入命令
tesseract cs.roy.exp0.tif cs.roy.exp0 -l chi_sim batch.nochop makebox
(5)打开jTessBoxEditor的train.bat,选择tif文件,可以点击merge按钮进行合并文字,如果没有中文可以在Settings->Font里设置宋体
(6)优化后点保存
(7)输入命令
tesseract cs.roy.exp0.jpg cs.roy.exp0 nobatch box.train
(8)输入命令
unicharset_extractor cs.roy.exp0.box
(9)新建font_properties文件,内容写入roy 0 0 0 0 0
注:roy对应的是命名规则的[fontname],font_properties文件不是font_properties.txt
(10)输入命令
shapeclustering -F font_properties -U unicharset cs.roy.exp0.tr
(11)输入命令
mftraining -F font_properties -U unicharset -O unicharset cs.roy.exp0.tr
(12)输入命令
cntraining cs.roy.exp0.tr
(13)把新生成的五个文件加上前缀roy.
(14)合并相关文件,输入命令,生成.traineddata文件
combine_tessdata roy.
(15)把roy.traineddata文件复制到C:\Program Files (x86)\Tesseract-OCR\tessdata文件夹下
(16)输入命令进行识别测试,-l 后面输入对应的字库
tesseract cs.roy.exp0.jpg cs.roy.exp0 -l roy
五、java代码调用(其中getImg()方法是把图片二值化处理增加识别效果)
package springboot;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class OCRHelper {
private final String LANG_OPTION = "-l";
private final String EOL = System.getProperty("line.separator");
public static void main(String[] args) {
try {
//需要被识别的图片
File file = new File("C:\\Users\\dell\\Desktop\\test\\cs.roy.exp0.jpg");
String recognizeText = new OCRHelper().recognizeText(file);
System.out.print(recognizeText + "\t");
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void getImg(File read,File write) throws IOException {
BufferedImage image = ImageIO.read(read);
int w = image.getWidth();
int h = image.getHeight();
float[] rgb = new float[3];
double[][] zuobiao = new double[w][h];
int R = 0;
float red = 0;
float green = 0;
float blue = 0;
BufferedImage bi= new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY);
;
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
int pixel = image.getRGB(x, y);
rgb[0] = (pixel & 0xff0000) >> 16;
rgb[1] = (pixel & 0xff00) >> 8;
rgb[2] = (pixel & 0xff);
red += rgb[0];
green += rgb[1];
blue += rgb[2];
R = (x+1) *(y+1);
float avg = (rgb[0]+rgb[1]+rgb[2])/3;
zuobiao[x][y] = avg;
}
}
double SW = 170;
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
if (zuobiao[x][y] <= SW) {
int max = new Color(0, 0, 0).getRGB();
bi.setRGB(x, y, max);
}else{
int min = new Color(255, 255, 255).getRGB();
bi.setRGB(x, y, min);
}
}
}
ImageIO.write(bi, "jpg", write);
}
/**
* Tesseract-OCR的安装路径
*/
private String tessPath = "C://Program Files (x86)//Tesseract-OCR";
//private String tessPath = new File("tesseract").getAbsolutePath();
/**
* @param imageFile 传入的图像文件
* @return 识别后的字符串
*/
public String recognizeText(File imageFile) throws Exception {
/**
* 设置输出文件的保存的文件目录
*/
File outputFile = new File(imageFile.getParentFile(), "output");
StringBuffer strB = new StringBuffer();
List cmd = new ArrayList();
cmd.add(tessPath + "\\tesseract");
cmd.add("");
cmd.add(outputFile.getName());
cmd.add(LANG_OPTION);
// cmd.add("chi_sim");
cmd.add("roy");
ProcessBuilder pb = new ProcessBuilder();
pb.directory(imageFile.getParentFile());
cmd.set(1, imageFile.getName());
pb.command(cmd);
pb.redirectErrorStream(true);
long startTime = System.currentTimeMillis();
System.out.println("开始时间:" + startTime);
Process process = pb.start();
int w = process.waitFor();
if (w == 0) {// 0代表正常退出
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(outputFile.getAbsolutePath() + ".txt"), "UTF-8"));
String str;
while ((str = in.readLine()) != null) {
strB.append(str).append(EOL);
}
in.close();
long endTime = System.currentTimeMillis();
System.out.println("结束时间:" + endTime);
System.out.println("耗时:" + (endTime - startTime) + "毫秒");
} 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(outputFile.getAbsolutePath() + ".txt").delete();
return strB.toString().replaceAll("\\s*", "");
}
}