最近因为公司项目需求需要识别出图片的户口本上的姓名,然后把图片的名字改成户口本上的名字。然后我就使用了Tesseract OCR来实现这个需求。35张能够正确的识别34张。像素越高成功率就越高。然后Tesseract OCR是需要配置环境变量的这个网上有很多文章,大伙可以去上找一下
依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-webflux -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>com.beust</groupId>
<artifactId>jcommander</artifactId>
<version>1.72</version>
</dependency>
<dependency>
<groupId>net.sourceforge.tess4j</groupId>
<artifactId>tess4j</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
主方法
package com.example.demo;
import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.util.ImageHelper;
import org.apache.commons.io.FileUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.system.ApplicationHome;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@SpringBootApplication
public class test {
public static void main(String[] args){
SpringApplication.run(test.class, args);
System.out.println("identify.areas.x="+ServerStartupParameter.x);
System.out.println("identify.areas.y="+ServerStartupParameter.y);
System.out.println("identify.areas.width="+ServerStartupParameter.width);
System.out.println("identify.areas.high="+ServerStartupParameter.high);
try {
//jar包当前路径
ApplicationHome h = new ApplicationHome(test.class);
File jarF = h.getSource();
String path = jarF.getParentFile().toString();
//识别器的路径
String tesspath = System.getProperty("user.dir");
Map<String, File> map = new HashMap<String, File>();
long l = System.currentTimeMillis();
ITesseract iTesseract = new Tesseract();
iTesseract.setDatapath(tesspath+"/Tesseract-OCR/tessdata");
// iTesseract.setDatapath("C:\\Program Files (x86)\\Tesseract-OCR\\tessdata");
iTesseract.setLanguage("chi_sim");// 中英文结合用 + 分隔
File imageFile = new File(path);
//File imageFile = new File(tesspath);
List<String> names = new ArrayList<String>();
List<String> allFildNames = new ArrayList<String>();
File[] files = imageFile.listFiles(new FRFilenameFilter());
System.out.println("所要识别图片的总数量="+files.length);
//指定文件名的命名规则
//Pattern pattern = Pattern.compile("^(.*?){5}\\d$");
for (File file : files){
String fileName = file.getName();
allFildNames.add(fileName);
}
for (int i = 0; i < files.length; i++) {
//boolean flag = false;
BufferedImage img = ImageIO.read(files[i]);
// 截取图片,要扫描的位置
//img = ImageHelper.getSubImage(img, 385, 1287, 200, 59);
//img = ImageHelper.getSubImage(img, 253, 858, 200, 39);
img = ImageHelper.getSubImage(img, ServerStartupParameter.x, ServerStartupParameter.y, ServerStartupParameter.width, ServerStartupParameter.high);
String name = iTesseract.doOCR(img).replace(" ", "").replaceAll("\r|\n", "");
String newFileName = name+".jpg";
int num = 0;
for (int j = 0; j < allFildNames.size(); j++) {
if(i!=j){
if(allFildNames.get(j).equals(newFileName)){
num++;
newFileName = name+String.valueOf(num)+".jpg";
}
}
}
allFildNames.add(newFileName);
fileRename(newFileName,names,files[i],newFileName);
}
System.out.println("Tesseract-OCR文件夹路径"+tesspath+"\\Tesseract-OCR");
System.out.println("当前jar路径"+tesspath);
System.out.println("识别内容"+names);
System.out.println("用时时间"+ "用时:" + (System.currentTimeMillis() - l) + "ms");
}catch (Exception e){
System.out.println(e.toString());
}
}
//文件夹重命名
public static void fileRename(String name,List<String> names,File file,String newFileName){
File newDir = new File(newFileName);
file.renameTo(newDir);
names.add(name);
}
}
FRFilenameFilter(过滤文件类型只识别png和jpg)
package com.example.demo;
import java.io.File;
import java.io.FilenameFilter;
public class FRFilenameFilter implements FilenameFilter {
@Override
public boolean accept(File dir, String name) {
// TODO Auto-generated method stub
boolean falg = false;
if(name.toLowerCase().endsWith(".jpg")||name.toLowerCase().endsWith(".png")){
falg = true;
}
return falg;
}
}
ServerStartupParameter
package com.example.demo;
import com.beust.jcommander.Parameter;
public class ServerStartupParameter {
public static int x;
public static int y;
public static int width;
public static int high;
}
WelcomeConfig
package com.example.demo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
@Configuration
public class WelcomeConfig {
@Value("${identify.areas.x}")
public int x;
@Value("${identify.areas.y}")
public int y;
@Value("${identify.areas.width}")
public int width;
@Value("${identify.areas.high}")
public int high;
@PostConstruct
public void init() {
ServerStartupParameter.x = x;
ServerStartupParameter.y = y;
ServerStartupParameter.width = width;
ServerStartupParameter.high = high;
}
}
demo的目录结构
项目演示
把项目导出成jar包。编写一个start.bat文件
start.bat
–identify.areas.x=253 --identify.areas.y=858 识别区域左上角的x和y轴的位置
–identify.areas.width=200 --identify.areas.high=39 识别区域的高和宽
@echo off
java -jar tesseract.jar --identify.areas.x=253 --identify.areas.y=858 --identify.areas.width=200 --identify.areas.high=39
pause
演示
然后双击start.bar
35张图片29秒总得 正确率34/35还算可以