2025年5月19日 星期一 乙巳(蛇)年 二月廿一 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > 人工智能

图像文字识别(二):java调用tesseract 识别图片文字

时间:05-23来源:作者:点击数:75

在JAVA中调用tesseract识别图片的文字内容,主要有两种方式:cmd方式,tess4j方式。在这篇博客中,主要记录一下通过cmd命令行的方式。cmd方式,就是通过在java中调用命令行,来执行tesseract,它的原理就是上篇博客所写的内容。

步骤:

(1)导入两个jar包:jai_imageio-1.1.1.jar 和 swingx-1.6.1.jar

(2)编写ImageIOHelper类,用于创建临时图片文件,防止损坏初始文件

  • import java.awt.image.BufferedImage;
  • import java.io.File;
  • import java.io.IOException;
  • import java.util.Iterator;
  • import java.util.Locale;
  • import javax.imageio.IIOImage;
  • import javax.imageio.ImageIO;
  • import javax.imageio.ImageReader;
  • import javax.imageio.ImageWriteParam;
  • import javax.imageio.ImageWriter;
  • import javax.imageio.metadata.IIOMetadata;
  • import javax.imageio.stream.ImageInputStream;
  • import javax.imageio.stream.ImageOutputStream;
  • import com.sun.media.imageio.plugins.tiff.TIFFImageWriteParam;
  • /**
  • * 类说明 :创建临时图片文件防止损坏初始文件
  • */
  • public class ImageIOHelper {
  •     //设置语言
  •     private Locale locale=Locale.CHINESE;
  •     //自定义语言构造的方法
  • public ImageIOHelper(Locale locale){
  • this.locale=locale;
  • }
  • //默认构造器Locale.CHINESE
  • public ImageIOHelper(){
  • }
  • /**
  • * 创建临时图片文件防止损坏初始文件
  • * @param imageFile
  • * @param imageFormat like png,jps .etc
  • * @return TempFile of Image
  • */
  • public File createImage(File imageFile, String imageFormat) throws IOException {
  • //读取图片文件
  • Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName(imageFormat);
  • ImageReader reader = readers.next();
  • //获取文件流
  • ImageInputStream iis = ImageIO.createImageInputStream(imageFile);
  • reader.setInput(iis);
  • IIOMetadata streamMetadata = reader.getStreamMetadata();
  • //设置writeParam
  • TIFFImageWriteParam tiffWriteParam = new TIFFImageWriteParam(Locale.CHINESE);
  • tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_DISABLED); //设置可否压缩
  • //获得tiffWriter和设置output
  • Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("tiff");
  • ImageWriter writer = writers.next();
  • BufferedImage bi = reader.read(0);
  • IIOImage image = new IIOImage(bi,null,reader.getImageMetadata(0));
  • File tempFile = tempImageFile(imageFile);
  • ImageOutputStream ios = ImageIO.createImageOutputStream(tempFile);
  • writer.setOutput(ios);
  • writer.write(streamMetadata, image, tiffWriteParam);
  • ios.close();
  • iis.close();
  • writer.dispose();
  • reader.dispose();
  • return tempFile;
  • }
  • /**
  • * 给tempfile添加后缀
  • * @param imageFile
  • * @throws IOException
  • */
  • private File tempImageFile(File imageFile) throws IOException {
  • String path = imageFile.getPath();
  • StringBuffer strB = new StringBuffer(path);
  • strB.insert(path.lastIndexOf('.'),"_text_recognize_temp");
  • String s=strB.toString().replaceFirst("(?<=//.)(//w+)$", "tif");
  • Runtime.getRuntime().exec("attrib "+"\""+s+"\""+" +H"); //设置文件隐藏
  • return new File(strB.toString());
  • }
  • }

(3)创建OCRUtil工具类,用于进行图片文字识别:

  • import java.io.BufferedReader;
  • import java.io.File;
  • import java.io.FileInputStream;
  • import java.io.IOException;
  • import java.io.InputStreamReader;
  • import java.util.ArrayList;
  • import java.util.List;
  • import java.util.Locale;
  • import org.jdesktop.swingx.util.OS;
  • /**
  • * 类说明:OCR工具类
  • */
  • public class OCRUtil {
  • private final String LANG_OPTION = "-l"; //英文字母小写l,并非阿拉伯数字1
  • private final String EOL = System.getProperty("line.separator");
  • private String tessPath = "D://Tesseract//Tsseract-OCR//Tesseract-OCR";//ocr的安装路径
  • public OCRUtil(String tessPath,String transFileName){
  • this.tessPath=tessPath;
  • }
  • //OCRUtil的构造方法,默认路径是"C://Program Files (x86)//Tesseract-OCR"
  • public OCRUtil(){ }
  • public String getTessPath() {
  • return tessPath;
  • }
  • public void setTessPath(String tessPath) {
  • this.tessPath = tessPath;
  • }
  • public String getLANG_OPTION() {
  • return LANG_OPTION;
  • }
  • public String getEOL() {
  • return EOL;
  • }
  • /**
  • * @param 需要识别的文件
  • * @param 文件的格式
  • * @return 识别后的文字
  • */
  • public String recognizeText(File imageFile,String imageFormat)throws Exception{
  • File tempImage = new ImageIOHelper().createImage(imageFile,imageFormat);
  • return ocrImages(tempImage, imageFile);
  • }
  • //可以自定义语言
  • public String recognizeText(File imageFile,String imageFormat,Locale locale)throws Exception{
  • File tempImage = new ImageIOHelper(locale).createImage(imageFile,imageFormat);
  • return ocrImages(tempImage, imageFile);
  • }
  • /**
  • * @param 临时文件
  • * @param 需要识别的文件
  • * @return 识别后的内容
  • * @throws IOException
  • * @throws InterruptedException
  • */
  • private String ocrImages(File tempImage,File imageFile) throws IOException, InterruptedException{
  • //设置输出文件的保存的文件目录,以及文件名
  • File outputFile = new File(imageFile.getParentFile(),"test");
  • StringBuffer strB = new StringBuffer();
  • //设置命令行内容
  • List<String> cmd = new ArrayList<String>();
  • if(OS.isWindowsXP()){
  • cmd.add(tessPath+"//tesseract");
  • }else if(OS.isLinux()){
  • cmd.add("tesseract");
  • }else{
  • cmd.add(tessPath+"//tesseract");
  • }
  • cmd.add("");
  • cmd.add(outputFile.getName());
  • cmd.add(LANG_OPTION);
  • cmd.add("chi_sim");//中文包
  • cmd.add("equ");//常用数学公式包
  • cmd.add("eng");//英语包
  • //创建操作系统进程
  • ProcessBuilder pb = new ProcessBuilder();
  • pb.directory(imageFile.getParentFile());//设置此进程生成器的工作目录
  • cmd.set(1, tempImage.getName());
  • pb.command(cmd);//设置要执行的cmd命令
  • pb.redirectErrorStream(true);//设置后续子进程生成的错误输出都将与标准输出合并
  • long startTime = System.currentTimeMillis();
  • System.out.println("开始时间:" + startTime);
  • Process process = pb.start();//开始执行,并返回进程实例
  • //最终执行命令为:tesseract 1.png test -l chi_sim+equ+eng
  • int w = process.waitFor();
  • tempImage.delete();//删除临时正在工作文件
  • 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 recongnize the image or its selected region.";
  • break;
  • case 31:
  • msg = "Unsupported image format.";
  • break;
  • default:
  • msg = "Errors occurred.";
  • }
  • tempImage.delete();
  • throw new RuntimeException(msg);
  • }
  • new File(outputFile.getAbsolutePath()+".txt");//.delete();
  • return strB.toString().replaceAll("\\s*", "");
  • }
  • }

(4)创建测试类Test:

  • import java.io.File;
  • import java.io.IOException;
  • /**
  • * @version 创建时间:2018年4月25日 下午5:09:19
  • * 类说明:测试类
  • */
  • public class Test {
  •     public static void main(String[] args) {
  • try {
  • //图片文件:此图片是需要被识别的图片路径
  • File file = new File("C://Users//1_20180208150251_x4hzz//1.png");
  • //String recognizeText = new OCRHelper().recognizeText(file);
  • String recognizeText = new OCRUtil().recognizeText(file, "png");
  • System.out.print(recognizeText + "\t");
  • } catch (IOException e) {
  • e.printStackTrace();
  • } catch (Exception e) {
  • e.printStackTrace();
  • }
  • }
  • }

至此,只要传入需要识别的图片,就可以识别出图片中的文字的内容了。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门